File indexing completed on 2024-05-26 05:00:33

0001 /*! jQuery UI - v1.12.1 - 2016-09-14
0002 * http://jqueryui.com
0003 * Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
0004 * Copyright jQuery Foundation and other contributors; Licensed MIT */
0005 
0006 (function( factory ) {
0007         if ( typeof define === "function" && define.amd ) {
0008 
0009                 // AMD. Register as an anonymous module.
0010                 define([ "jquery" ], factory );
0011         } else {
0012 
0013                 // Browser globals
0014                 factory( jQuery );
0015         }
0016 }(function( $ ) {
0017 
0018 $.ui = $.ui || {};
0019 
0020 var version = $.ui.version = "1.12.1";
0021 
0022 
0023 /*!
0024  * jQuery UI Widget 1.12.1
0025  * http://jqueryui.com
0026  *
0027  * Copyright jQuery Foundation and other contributors
0028  * Released under the MIT license.
0029  * http://jquery.org/license
0030  */
0031 
0032 //>>label: Widget
0033 //>>group: Core
0034 //>>description: Provides a factory for creating stateful widgets with a common API.
0035 //>>docs: http://api.jqueryui.com/jQuery.widget/
0036 //>>demos: http://jqueryui.com/widget/
0037 
0038 
0039 
0040 var widgetUuid = 0;
0041 var widgetSlice = Array.prototype.slice;
0042 
0043 $.cleanData = ( function( orig ) {
0044         return function( elems ) {
0045                 var events, elem, i;
0046                 for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
0047                         try {
0048 
0049                                 // Only trigger remove when necessary to save time
0050                                 events = $._data( elem, "events" );
0051                                 if ( events && events.remove ) {
0052                                         $( elem ).triggerHandler( "remove" );
0053                                 }
0054 
0055                         // Http://bugs.jquery.com/ticket/8235
0056                         } catch ( e ) {}
0057                 }
0058                 orig( elems );
0059         };
0060 } )( $.cleanData );
0061 
0062 $.widget = function( name, base, prototype ) {
0063         var existingConstructor, constructor, basePrototype;
0064 
0065         // ProxiedPrototype allows the provided prototype to remain unmodified
0066         // so that it can be used as a mixin for multiple widgets (#8876)
0067         var proxiedPrototype = {};
0068 
0069         var namespace = name.split( "." )[ 0 ];
0070         name = name.split( "." )[ 1 ];
0071         var fullName = namespace + "-" + name;
0072 
0073         if ( !prototype ) {
0074                 prototype = base;
0075                 base = $.Widget;
0076         }
0077 
0078         if ( $.isArray( prototype ) ) {
0079                 prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
0080         }
0081 
0082         // Create selector for plugin
0083         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
0084                 return !!$.data( elem, fullName );
0085         };
0086 
0087         $[ namespace ] = $[ namespace ] || {};
0088         existingConstructor = $[ namespace ][ name ];
0089         constructor = $[ namespace ][ name ] = function( options, element ) {
0090 
0091                 // Allow instantiation without "new" keyword
0092                 if ( !this._createWidget ) {
0093                         return new constructor( options, element );
0094                 }
0095 
0096                 // Allow instantiation without initializing for simple inheritance
0097                 // must use "new" keyword (the code above always passes args)
0098                 if ( arguments.length ) {
0099                         this._createWidget( options, element );
0100                 }
0101         };
0102 
0103         // Extend with the existing constructor to carry over any static properties
0104         $.extend( constructor, existingConstructor, {
0105                 version: prototype.version,
0106 
0107                 // Copy the object used to create the prototype in case we need to
0108                 // redefine the widget later
0109                 _proto: $.extend( {}, prototype ),
0110 
0111                 // Track widgets that inherit from this widget in case this widget is
0112                 // redefined after a widget inherits from it
0113                 _childConstructors: []
0114         } );
0115 
0116         basePrototype = new base();
0117 
0118         // We need to make the options hash a property directly on the new instance
0119         // otherwise we'll modify the options hash on the prototype that we're
0120         // inheriting from
0121         basePrototype.options = $.widget.extend( {}, basePrototype.options );
0122         $.each( prototype, function( prop, value ) {
0123                 if ( !$.isFunction( value ) ) {
0124                         proxiedPrototype[ prop ] = value;
0125                         return;
0126                 }
0127                 proxiedPrototype[ prop ] = ( function() {
0128                         function _super() {
0129                                 return base.prototype[ prop ].apply( this, arguments );
0130                         }
0131 
0132                         function _superApply( args ) {
0133                                 return base.prototype[ prop ].apply( this, args );
0134                         }
0135 
0136                         return function() {
0137                                 var __super = this._super;
0138                                 var __superApply = this._superApply;
0139                                 var returnValue;
0140 
0141                                 this._super = _super;
0142                                 this._superApply = _superApply;
0143 
0144                                 returnValue = value.apply( this, arguments );
0145 
0146                                 this._super = __super;
0147                                 this._superApply = __superApply;
0148 
0149                                 return returnValue;
0150                         };
0151                 } )();
0152         } );
0153         constructor.prototype = $.widget.extend( basePrototype, {
0154 
0155                 // TODO: remove support for widgetEventPrefix
0156                 // always use the name + a colon as the prefix, e.g., draggable:start
0157                 // don't prefix for widgets that aren't DOM-based
0158                 widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
0159         }, proxiedPrototype, {
0160                 constructor: constructor,
0161                 namespace: namespace,
0162                 widgetName: name,
0163                 widgetFullName: fullName
0164         } );
0165 
0166         // If this widget is being redefined then we need to find all widgets that
0167         // are inheriting from it and redefine all of them so that they inherit from
0168         // the new version of this widget. We're essentially trying to replace one
0169         // level in the prototype chain.
0170         if ( existingConstructor ) {
0171                 $.each( existingConstructor._childConstructors, function( i, child ) {
0172                         var childPrototype = child.prototype;
0173 
0174                         // Redefine the child widget using the same prototype that was
0175                         // originally used, but inherit from the new version of the base
0176                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
0177                                 child._proto );
0178                 } );
0179 
0180                 // Remove the list of existing child constructors from the old constructor
0181                 // so the old child constructors can be garbage collected
0182                 delete existingConstructor._childConstructors;
0183         } else {
0184                 base._childConstructors.push( constructor );
0185         }
0186 
0187         $.widget.bridge( name, constructor );
0188 
0189         return constructor;
0190 };
0191 
0192 $.widget.extend = function( target ) {
0193         var input = widgetSlice.call( arguments, 1 );
0194         var inputIndex = 0;
0195         var inputLength = input.length;
0196         var key;
0197         var value;
0198 
0199         for ( ; inputIndex < inputLength; inputIndex++ ) {
0200                 for ( key in input[ inputIndex ] ) {
0201                         value = input[ inputIndex ][ key ];
0202                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
0203 
0204                                 // Clone objects
0205                                 if ( $.isPlainObject( value ) ) {
0206                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
0207                                                 $.widget.extend( {}, target[ key ], value ) :
0208 
0209                                                 // Don't extend strings, arrays, etc. with objects
0210                                                 $.widget.extend( {}, value );
0211 
0212                                 // Copy everything else by reference
0213                                 } else {
0214                                         target[ key ] = value;
0215                                 }
0216                         }
0217                 }
0218         }
0219         return target;
0220 };
0221 
0222 $.widget.bridge = function( name, object ) {
0223         var fullName = object.prototype.widgetFullName || name;
0224         $.fn[ name ] = function( options ) {
0225                 var isMethodCall = typeof options === "string";
0226                 var args = widgetSlice.call( arguments, 1 );
0227                 var returnValue = this;
0228 
0229                 if ( isMethodCall ) {
0230 
0231                         // If this is an empty collection, we need to have the instance method
0232                         // return undefined instead of the jQuery instance
0233                         if ( !this.length && options === "instance" ) {
0234                                 returnValue = undefined;
0235                         } else {
0236                                 this.each( function() {
0237                                         var methodValue;
0238                                         var instance = $.data( this, fullName );
0239 
0240                                         if ( options === "instance" ) {
0241                                                 returnValue = instance;
0242                                                 return false;
0243                                         }
0244 
0245                                         if ( !instance ) {
0246                                                 return $.error( "cannot call methods on " + name +
0247                                                         " prior to initialization; " +
0248                                                         "attempted to call method '" + options + "'" );
0249                                         }
0250 
0251                                         if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
0252                                                 return $.error( "no such method '" + options + "' for " + name +
0253                                                         " widget instance" );
0254                                         }
0255 
0256                                         methodValue = instance[ options ].apply( instance, args );
0257 
0258                                         if ( methodValue !== instance && methodValue !== undefined ) {
0259                                                 returnValue = methodValue && methodValue.jquery ?
0260                                                         returnValue.pushStack( methodValue.get() ) :
0261                                                         methodValue;
0262                                                 return false;
0263                                         }
0264                                 } );
0265                         }
0266                 } else {
0267 
0268                         // Allow multiple hashes to be passed on init
0269                         if ( args.length ) {
0270                                 options = $.widget.extend.apply( null, [ options ].concat( args ) );
0271                         }
0272 
0273                         this.each( function() {
0274                                 var instance = $.data( this, fullName );
0275                                 if ( instance ) {
0276                                         instance.option( options || {} );
0277                                         if ( instance._init ) {
0278                                                 instance._init();
0279                                         }
0280                                 } else {
0281                                         $.data( this, fullName, new object( options, this ) );
0282                                 }
0283                         } );
0284                 }
0285 
0286                 return returnValue;
0287         };
0288 };
0289 
0290 $.Widget = function( /* options, element */ ) {};
0291 $.Widget._childConstructors = [];
0292 
0293 $.Widget.prototype = {
0294         widgetName: "widget",
0295         widgetEventPrefix: "",
0296         defaultElement: "<div>",
0297 
0298         options: {
0299                 classes: {},
0300                 disabled: false,
0301 
0302                 // Callbacks
0303                 create: null
0304         },
0305 
0306         _createWidget: function( options, element ) {
0307                 element = $( element || this.defaultElement || this )[ 0 ];
0308                 this.element = $( element );
0309                 this.uuid = widgetUuid++;
0310                 this.eventNamespace = "." + this.widgetName + this.uuid;
0311 
0312                 this.bindings = $();
0313                 this.hoverable = $();
0314                 this.focusable = $();
0315                 this.classesElementLookup = {};
0316 
0317                 if ( element !== this ) {
0318                         $.data( element, this.widgetFullName, this );
0319                         this._on( true, this.element, {
0320                                 remove: function( event ) {
0321                                         if ( event.target === element ) {
0322                                                 this.destroy();
0323                                         }
0324                                 }
0325                         } );
0326                         this.document = $( element.style ?
0327 
0328                                 // Element within the document
0329                                 element.ownerDocument :
0330 
0331                                 // Element is window or document
0332                                 element.document || element );
0333                         this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
0334                 }
0335 
0336                 this.options = $.widget.extend( {},
0337                         this.options,
0338                         this._getCreateOptions(),
0339                         options );
0340 
0341                 this._create();
0342 
0343                 if ( this.options.disabled ) {
0344                         this._setOptionDisabled( this.options.disabled );
0345                 }
0346 
0347                 this._trigger( "create", null, this._getCreateEventData() );
0348                 this._init();
0349         },
0350 
0351         _getCreateOptions: function() {
0352                 return {};
0353         },
0354 
0355         _getCreateEventData: $.noop,
0356 
0357         _create: $.noop,
0358 
0359         _init: $.noop,
0360 
0361         destroy: function() {
0362                 var that = this;
0363 
0364                 this._destroy();
0365                 $.each( this.classesElementLookup, function( key, value ) {
0366                         that._removeClass( value, key );
0367                 } );
0368 
0369                 // We can probably remove the unbind calls in 2.0
0370                 // all event bindings should go through this._on()
0371                 this.element
0372                         .off( this.eventNamespace )
0373                         .removeData( this.widgetFullName );
0374                 this.widget()
0375                         .off( this.eventNamespace )
0376                         .removeAttr( "aria-disabled" );
0377 
0378                 // Clean up events and states
0379                 this.bindings.off( this.eventNamespace );
0380         },
0381 
0382         _destroy: $.noop,
0383 
0384         widget: function() {
0385                 return this.element;
0386         },
0387 
0388         option: function( key, value ) {
0389                 var options = key;
0390                 var parts;
0391                 var curOption;
0392                 var i;
0393 
0394                 if ( arguments.length === 0 ) {
0395 
0396                         // Don't return a reference to the internal hash
0397                         return $.widget.extend( {}, this.options );
0398                 }
0399 
0400                 if ( typeof key === "string" ) {
0401 
0402                         // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
0403                         options = {};
0404                         parts = key.split( "." );
0405                         key = parts.shift();
0406                         if ( parts.length ) {
0407                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
0408                                 for ( i = 0; i < parts.length - 1; i++ ) {
0409                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
0410                                         curOption = curOption[ parts[ i ] ];
0411                                 }
0412                                 key = parts.pop();
0413                                 if ( arguments.length === 1 ) {
0414                                         return curOption[ key ] === undefined ? null : curOption[ key ];
0415                                 }
0416                                 curOption[ key ] = value;
0417                         } else {
0418                                 if ( arguments.length === 1 ) {
0419                                         return this.options[ key ] === undefined ? null : this.options[ key ];
0420                                 }
0421                                 options[ key ] = value;
0422                         }
0423                 }
0424 
0425                 this._setOptions( options );
0426 
0427                 return this;
0428         },
0429 
0430         _setOptions: function( options ) {
0431                 var key;
0432 
0433                 for ( key in options ) {
0434                         this._setOption( key, options[ key ] );
0435                 }
0436 
0437                 return this;
0438         },
0439 
0440         _setOption: function( key, value ) {
0441                 if ( key === "classes" ) {
0442                         this._setOptionClasses( value );
0443                 }
0444 
0445                 this.options[ key ] = value;
0446 
0447                 if ( key === "disabled" ) {
0448                         this._setOptionDisabled( value );
0449                 }
0450 
0451                 return this;
0452         },
0453 
0454         _setOptionClasses: function( value ) {
0455                 var classKey, elements, currentElements;
0456 
0457                 for ( classKey in value ) {
0458                         currentElements = this.classesElementLookup[ classKey ];
0459                         if ( value[ classKey ] === this.options.classes[ classKey ] ||
0460                                         !currentElements ||
0461                                         !currentElements.length ) {
0462                                 continue;
0463                         }
0464 
0465                         // We are doing this to create a new jQuery object because the _removeClass() call
0466                         // on the next line is going to destroy the reference to the current elements being
0467                         // tracked. We need to save a copy of this collection so that we can add the new classes
0468                         // below.
0469                         elements = $( currentElements.get() );
0470                         this._removeClass( currentElements, classKey );
0471 
0472                         // We don't use _addClass() here, because that uses this.options.classes
0473                         // for generating the string of classes. We want to use the value passed in from
0474                         // _setOption(), this is the new value of the classes option which was passed to
0475                         // _setOption(). We pass this value directly to _classes().
0476                         elements.addClass( this._classes( {
0477                                 element: elements,
0478                                 keys: classKey,
0479                                 classes: value,
0480                                 add: true
0481                         } ) );
0482                 }
0483         },
0484 
0485         _setOptionDisabled: function( value ) {
0486                 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
0487 
0488                 // If the widget is becoming disabled, then nothing is interactive
0489                 if ( value ) {
0490                         this._removeClass( this.hoverable, null, "ui-state-hover" );
0491                         this._removeClass( this.focusable, null, "ui-state-focus" );
0492                 }
0493         },
0494 
0495         enable: function() {
0496                 return this._setOptions( { disabled: false } );
0497         },
0498 
0499         disable: function() {
0500                 return this._setOptions( { disabled: true } );
0501         },
0502 
0503         _classes: function( options ) {
0504                 var full = [];
0505                 var that = this;
0506 
0507                 options = $.extend( {
0508                         element: this.element,
0509                         classes: this.options.classes || {}
0510                 }, options );
0511 
0512                 function processClassString( classes, checkOption ) {
0513                         var current, i;
0514                         for ( i = 0; i < classes.length; i++ ) {
0515                                 current = that.classesElementLookup[ classes[ i ] ] || $();
0516                                 if ( options.add ) {
0517                                         current = $( $.unique( current.get().concat( options.element.get() ) ) );
0518                                 } else {
0519                                         current = $( current.not( options.element ).get() );
0520                                 }
0521                                 that.classesElementLookup[ classes[ i ] ] = current;
0522                                 full.push( classes[ i ] );
0523                                 if ( checkOption && options.classes[ classes[ i ] ] ) {
0524                                         full.push( options.classes[ classes[ i ] ] );
0525                                 }
0526                         }
0527                 }
0528 
0529                 this._on( options.element, {
0530                         "remove": "_untrackClassesElement"
0531                 } );
0532 
0533                 if ( options.keys ) {
0534                         processClassString( options.keys.match( /\S+/g ) || [], true );
0535                 }
0536                 if ( options.extra ) {
0537                         processClassString( options.extra.match( /\S+/g ) || [] );
0538                 }
0539 
0540                 return full.join( " " );
0541         },
0542 
0543         _untrackClassesElement: function( event ) {
0544                 var that = this;
0545                 $.each( that.classesElementLookup, function( key, value ) {
0546                         if ( $.inArray( event.target, value ) !== -1 ) {
0547                                 that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
0548                         }
0549                 } );
0550         },
0551 
0552         _removeClass: function( element, keys, extra ) {
0553                 return this._toggleClass( element, keys, extra, false );
0554         },
0555 
0556         _addClass: function( element, keys, extra ) {
0557                 return this._toggleClass( element, keys, extra, true );
0558         },
0559 
0560         _toggleClass: function( element, keys, extra, add ) {
0561                 add = ( typeof add === "boolean" ) ? add : extra;
0562                 var shift = ( typeof element === "string" || element === null ),
0563                         options = {
0564                                 extra: shift ? keys : extra,
0565                                 keys: shift ? element : keys,
0566                                 element: shift ? this.element : element,
0567                                 add: add
0568                         };
0569                 options.element.toggleClass( this._classes( options ), add );
0570                 return this;
0571         },
0572 
0573         _on: function( suppressDisabledCheck, element, handlers ) {
0574                 var delegateElement;
0575                 var instance = this;
0576 
0577                 // No suppressDisabledCheck flag, shuffle arguments
0578                 if ( typeof suppressDisabledCheck !== "boolean" ) {
0579                         handlers = element;
0580                         element = suppressDisabledCheck;
0581                         suppressDisabledCheck = false;
0582                 }
0583 
0584                 // No element argument, shuffle and use this.element
0585                 if ( !handlers ) {
0586                         handlers = element;
0587                         element = this.element;
0588                         delegateElement = this.widget();
0589                 } else {
0590                         element = delegateElement = $( element );
0591                         this.bindings = this.bindings.add( element );
0592                 }
0593 
0594                 $.each( handlers, function( event, handler ) {
0595                         function handlerProxy() {
0596 
0597                                 // Allow widgets to customize the disabled handling
0598                                 // - disabled as an array instead of boolean
0599                                 // - disabled class as method for disabling individual parts
0600                                 if ( !suppressDisabledCheck &&
0601                                                 ( instance.options.disabled === true ||
0602                                                 $( this ).hasClass( "ui-state-disabled" ) ) ) {
0603                                         return;
0604                                 }
0605                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
0606                                         .apply( instance, arguments );
0607                         }
0608 
0609                         // Copy the guid so direct unbinding works
0610                         if ( typeof handler !== "string" ) {
0611                                 handlerProxy.guid = handler.guid =
0612                                         handler.guid || handlerProxy.guid || $.guid++;
0613                         }
0614 
0615                         var match = event.match( /^([\w:-]*)\s*(.*)$/ );
0616                         var eventName = match[ 1 ] + instance.eventNamespace;
0617                         var selector = match[ 2 ];
0618 
0619                         if ( selector ) {
0620                                 delegateElement.on( eventName, selector, handlerProxy );
0621                         } else {
0622                                 element.on( eventName, handlerProxy );
0623                         }
0624                 } );
0625         },
0626 
0627         _off: function( element, eventName ) {
0628                 eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
0629                         this.eventNamespace;
0630                 element.off( eventName ).off( eventName );
0631 
0632                 // Clear the stack to avoid memory leaks (#10056)
0633                 this.bindings = $( this.bindings.not( element ).get() );
0634                 this.focusable = $( this.focusable.not( element ).get() );
0635                 this.hoverable = $( this.hoverable.not( element ).get() );
0636         },
0637 
0638         _delay: function( handler, delay ) {
0639                 function handlerProxy() {
0640                         return ( typeof handler === "string" ? instance[ handler ] : handler )
0641                                 .apply( instance, arguments );
0642                 }
0643                 var instance = this;
0644                 return setTimeout( handlerProxy, delay || 0 );
0645         },
0646 
0647         _hoverable: function( element ) {
0648                 this.hoverable = this.hoverable.add( element );
0649                 this._on( element, {
0650                         mouseenter: function( event ) {
0651                                 this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
0652                         },
0653                         mouseleave: function( event ) {
0654                                 this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
0655                         }
0656                 } );
0657         },
0658 
0659         _focusable: function( element ) {
0660                 this.focusable = this.focusable.add( element );
0661                 this._on( element, {
0662                         focusin: function( event ) {
0663                                 this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
0664                         },
0665                         focusout: function( event ) {
0666                                 this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
0667                         }
0668                 } );
0669         },
0670 
0671         _trigger: function( type, event, data ) {
0672                 var prop, orig;
0673                 var callback = this.options[ type ];
0674 
0675                 data = data || {};
0676                 event = $.Event( event );
0677                 event.type = ( type === this.widgetEventPrefix ?
0678                         type :
0679                         this.widgetEventPrefix + type ).toLowerCase();
0680 
0681                 // The original event may come from any element
0682                 // so we need to reset the target on the new event
0683                 event.target = this.element[ 0 ];
0684 
0685                 // Copy original event properties over to the new event
0686                 orig = event.originalEvent;
0687                 if ( orig ) {
0688                         for ( prop in orig ) {
0689                                 if ( !( prop in event ) ) {
0690                                         event[ prop ] = orig[ prop ];
0691                                 }
0692                         }
0693                 }
0694 
0695                 this.element.trigger( event, data );
0696                 return !( $.isFunction( callback ) &&
0697                         callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
0698                         event.isDefaultPrevented() );
0699         }
0700 };
0701 
0702 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
0703         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
0704                 if ( typeof options === "string" ) {
0705                         options = { effect: options };
0706                 }
0707 
0708                 var hasOptions;
0709                 var effectName = !options ?
0710                         method :
0711                         options === true || typeof options === "number" ?
0712                                 defaultEffect :
0713                                 options.effect || defaultEffect;
0714 
0715                 options = options || {};
0716                 if ( typeof options === "number" ) {
0717                         options = { duration: options };
0718                 }
0719 
0720                 hasOptions = !$.isEmptyObject( options );
0721                 options.complete = callback;
0722 
0723                 if ( options.delay ) {
0724                         element.delay( options.delay );
0725                 }
0726 
0727                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
0728                         element[ method ]( options );
0729                 } else if ( effectName !== method && element[ effectName ] ) {
0730                         element[ effectName ]( options.duration, options.easing, callback );
0731                 } else {
0732                         element.queue( function( next ) {
0733                                 $( this )[ method ]();
0734                                 if ( callback ) {
0735                                         callback.call( element[ 0 ] );
0736                                 }
0737                                 next();
0738                         } );
0739                 }
0740         };
0741 } );
0742 
0743 var widget = $.widget;
0744 
0745 
0746 /*!
0747  * jQuery UI Position 1.12.1
0748  * http://jqueryui.com
0749  *
0750  * Copyright jQuery Foundation and other contributors
0751  * Released under the MIT license.
0752  * http://jquery.org/license
0753  *
0754  * http://api.jqueryui.com/position/
0755  */
0756 
0757 //>>label: Position
0758 //>>group: Core
0759 //>>description: Positions elements relative to other elements.
0760 //>>docs: http://api.jqueryui.com/position/
0761 //>>demos: http://jqueryui.com/position/
0762 
0763 
0764 ( function() {
0765 var cachedScrollbarWidth,
0766         max = Math.max,
0767         abs = Math.abs,
0768         rhorizontal = /left|center|right/,
0769         rvertical = /top|center|bottom/,
0770         roffset = /[\+\-]\d+(\.[\d]+)?%?/,
0771         rposition = /^\w+/,
0772         rpercent = /%$/,
0773         _position = $.fn.position;
0774 
0775 function getOffsets( offsets, width, height ) {
0776         return [
0777                 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
0778                 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
0779         ];
0780 }
0781 
0782 function parseCss( element, property ) {
0783         return parseInt( $.css( element, property ), 10 ) || 0;
0784 }
0785 
0786 function getDimensions( elem ) {
0787         var raw = elem[ 0 ];
0788         if ( raw.nodeType === 9 ) {
0789                 return {
0790                         width: elem.width(),
0791                         height: elem.height(),
0792                         offset: { top: 0, left: 0 }
0793                 };
0794         }
0795         if ( $.isWindow( raw ) ) {
0796                 return {
0797                         width: elem.width(),
0798                         height: elem.height(),
0799                         offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
0800                 };
0801         }
0802         if ( raw.preventDefault ) {
0803                 return {
0804                         width: 0,
0805                         height: 0,
0806                         offset: { top: raw.pageY, left: raw.pageX }
0807                 };
0808         }
0809         return {
0810                 width: elem.outerWidth(),
0811                 height: elem.outerHeight(),
0812                 offset: elem.offset()
0813         };
0814 }
0815 
0816 $.position = {
0817         scrollbarWidth: function() {
0818                 if ( cachedScrollbarWidth !== undefined ) {
0819                         return cachedScrollbarWidth;
0820                 }
0821                 var w1, w2,
0822                         div = $( "<div " +
0823                                 "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
0824                                 "<div style='height:100px;width:auto;'></div></div>" ),
0825                         innerDiv = div.children()[ 0 ];
0826 
0827                 $( "body" ).append( div );
0828                 w1 = innerDiv.offsetWidth;
0829                 div.css( "overflow", "scroll" );
0830 
0831                 w2 = innerDiv.offsetWidth;
0832 
0833                 if ( w1 === w2 ) {
0834                         w2 = div[ 0 ].clientWidth;
0835                 }
0836 
0837                 div.remove();
0838 
0839                 return ( cachedScrollbarWidth = w1 - w2 );
0840         },
0841         getScrollInfo: function( within ) {
0842                 var overflowX = within.isWindow || within.isDocument ? "" :
0843                                 within.element.css( "overflow-x" ),
0844                         overflowY = within.isWindow || within.isDocument ? "" :
0845                                 within.element.css( "overflow-y" ),
0846                         hasOverflowX = overflowX === "scroll" ||
0847                                 ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
0848                         hasOverflowY = overflowY === "scroll" ||
0849                                 ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
0850                 return {
0851                         width: hasOverflowY ? $.position.scrollbarWidth() : 0,
0852                         height: hasOverflowX ? $.position.scrollbarWidth() : 0
0853                 };
0854         },
0855         getWithinInfo: function( element ) {
0856                 var withinElement = $( element || window ),
0857                         isWindow = $.isWindow( withinElement[ 0 ] ),
0858                         isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
0859                         hasOffset = !isWindow && !isDocument;
0860                 return {
0861                         element: withinElement,
0862                         isWindow: isWindow,
0863                         isDocument: isDocument,
0864                         offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
0865                         scrollLeft: withinElement.scrollLeft(),
0866                         scrollTop: withinElement.scrollTop(),
0867                         width: withinElement.outerWidth(),
0868                         height: withinElement.outerHeight()
0869                 };
0870         }
0871 };
0872 
0873 $.fn.position = function( options ) {
0874         if ( !options || !options.of ) {
0875                 return _position.apply( this, arguments );
0876         }
0877 
0878         // Make a copy, we don't want to modify arguments
0879         options = $.extend( {}, options );
0880 
0881         var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
0882                 target = $( options.of ),
0883                 within = $.position.getWithinInfo( options.within ),
0884                 scrollInfo = $.position.getScrollInfo( within ),
0885                 collision = ( options.collision || "flip" ).split( " " ),
0886                 offsets = {};
0887 
0888         dimensions = getDimensions( target );
0889         if ( target[ 0 ].preventDefault ) {
0890 
0891                 // Force left top to allow flipping
0892                 options.at = "left top";
0893         }
0894         targetWidth = dimensions.width;
0895         targetHeight = dimensions.height;
0896         targetOffset = dimensions.offset;
0897 
0898         // Clone to reuse original targetOffset later
0899         basePosition = $.extend( {}, targetOffset );
0900 
0901         // Force my and at to have valid horizontal and vertical positions
0902         // if a value is missing or invalid, it will be converted to center
0903         $.each( [ "my", "at" ], function() {
0904                 var pos = ( options[ this ] || "" ).split( " " ),
0905                         horizontalOffset,
0906                         verticalOffset;
0907 
0908                 if ( pos.length === 1 ) {
0909                         pos = rhorizontal.test( pos[ 0 ] ) ?
0910                                 pos.concat( [ "center" ] ) :
0911                                 rvertical.test( pos[ 0 ] ) ?
0912                                         [ "center" ].concat( pos ) :
0913                                         [ "center", "center" ];
0914                 }
0915                 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
0916                 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
0917 
0918                 // Calculate offsets
0919                 horizontalOffset = roffset.exec( pos[ 0 ] );
0920                 verticalOffset = roffset.exec( pos[ 1 ] );
0921                 offsets[ this ] = [
0922                         horizontalOffset ? horizontalOffset[ 0 ] : 0,
0923                         verticalOffset ? verticalOffset[ 0 ] : 0
0924                 ];
0925 
0926                 // Reduce to just the positions without the offsets
0927                 options[ this ] = [
0928                         rposition.exec( pos[ 0 ] )[ 0 ],
0929                         rposition.exec( pos[ 1 ] )[ 0 ]
0930                 ];
0931         } );
0932 
0933         // Normalize collision option
0934         if ( collision.length === 1 ) {
0935                 collision[ 1 ] = collision[ 0 ];
0936         }
0937 
0938         if ( options.at[ 0 ] === "right" ) {
0939                 basePosition.left += targetWidth;
0940         } else if ( options.at[ 0 ] === "center" ) {
0941                 basePosition.left += targetWidth / 2;
0942         }
0943 
0944         if ( options.at[ 1 ] === "bottom" ) {
0945                 basePosition.top += targetHeight;
0946         } else if ( options.at[ 1 ] === "center" ) {
0947                 basePosition.top += targetHeight / 2;
0948         }
0949 
0950         atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
0951         basePosition.left += atOffset[ 0 ];
0952         basePosition.top += atOffset[ 1 ];
0953 
0954         return this.each( function() {
0955                 var collisionPosition, using,
0956                         elem = $( this ),
0957                         elemWidth = elem.outerWidth(),
0958                         elemHeight = elem.outerHeight(),
0959                         marginLeft = parseCss( this, "marginLeft" ),
0960                         marginTop = parseCss( this, "marginTop" ),
0961                         collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
0962                                 scrollInfo.width,
0963                         collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
0964                                 scrollInfo.height,
0965                         position = $.extend( {}, basePosition ),
0966                         myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
0967 
0968                 if ( options.my[ 0 ] === "right" ) {
0969                         position.left -= elemWidth;
0970                 } else if ( options.my[ 0 ] === "center" ) {
0971                         position.left -= elemWidth / 2;
0972                 }
0973 
0974                 if ( options.my[ 1 ] === "bottom" ) {
0975                         position.top -= elemHeight;
0976                 } else if ( options.my[ 1 ] === "center" ) {
0977                         position.top -= elemHeight / 2;
0978                 }
0979 
0980                 position.left += myOffset[ 0 ];
0981                 position.top += myOffset[ 1 ];
0982 
0983                 collisionPosition = {
0984                         marginLeft: marginLeft,
0985                         marginTop: marginTop
0986                 };
0987 
0988                 $.each( [ "left", "top" ], function( i, dir ) {
0989                         if ( $.ui.position[ collision[ i ] ] ) {
0990                                 $.ui.position[ collision[ i ] ][ dir ]( position, {
0991                                         targetWidth: targetWidth,
0992                                         targetHeight: targetHeight,
0993                                         elemWidth: elemWidth,
0994                                         elemHeight: elemHeight,
0995                                         collisionPosition: collisionPosition,
0996                                         collisionWidth: collisionWidth,
0997                                         collisionHeight: collisionHeight,
0998                                         offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
0999                                         my: options.my,
1000                                         at: options.at,
1001                                         within: within,
1002                                         elem: elem
1003                                 } );
1004                         }
1005                 } );
1006 
1007                 if ( options.using ) {
1008 
1009                         // Adds feedback as second argument to using callback, if present
1010                         using = function( props ) {
1011                                 var left = targetOffset.left - position.left,
1012                                         right = left + targetWidth - elemWidth,
1013                                         top = targetOffset.top - position.top,
1014                                         bottom = top + targetHeight - elemHeight,
1015                                         feedback = {
1016                                                 target: {
1017                                                         element: target,
1018                                                         left: targetOffset.left,
1019                                                         top: targetOffset.top,
1020                                                         width: targetWidth,
1021                                                         height: targetHeight
1022                                                 },
1023                                                 element: {
1024                                                         element: elem,
1025                                                         left: position.left,
1026                                                         top: position.top,
1027                                                         width: elemWidth,
1028                                                         height: elemHeight
1029                                                 },
1030                                                 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031                                                 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032                                         };
1033                                 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034                                         feedback.horizontal = "center";
1035                                 }
1036                                 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037                                         feedback.vertical = "middle";
1038                                 }
1039                                 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040                                         feedback.important = "horizontal";
1041                                 } else {
1042                                         feedback.important = "vertical";
1043                                 }
1044                                 options.using.call( this, props, feedback );
1045                         };
1046                 }
1047 
1048                 elem.offset( $.extend( position, { using: using } ) );
1049         } );
1050 };
1051 
1052 $.ui.position = {
1053         fit: {
1054                 left: function( position, data ) {
1055                         var within = data.within,
1056                                 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057                                 outerWidth = within.width,
1058                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059                                 overLeft = withinOffset - collisionPosLeft,
1060                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061                                 newOverRight;
1062 
1063                         // Element is wider than within
1064                         if ( data.collisionWidth > outerWidth ) {
1065 
1066                                 // Element is initially over the left side of within
1067                                 if ( overLeft > 0 && overRight <= 0 ) {
1068                                         newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069                                                 withinOffset;
1070                                         position.left += overLeft - newOverRight;
1071 
1072                                 // Element is initially over right side of within
1073                                 } else if ( overRight > 0 && overLeft <= 0 ) {
1074                                         position.left = withinOffset;
1075 
1076                                 // Element is initially over both left and right sides of within
1077                                 } else {
1078                                         if ( overLeft > overRight ) {
1079                                                 position.left = withinOffset + outerWidth - data.collisionWidth;
1080                                         } else {
1081                                                 position.left = withinOffset;
1082                                         }
1083                                 }
1084 
1085                         // Too far left -> align with left edge
1086                         } else if ( overLeft > 0 ) {
1087                                 position.left += overLeft;
1088 
1089                         // Too far right -> align with right edge
1090                         } else if ( overRight > 0 ) {
1091                                 position.left -= overRight;
1092 
1093                         // Adjust based on position and margin
1094                         } else {
1095                                 position.left = max( position.left - collisionPosLeft, position.left );
1096                         }
1097                 },
1098                 top: function( position, data ) {
1099                         var within = data.within,
1100                                 withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101                                 outerHeight = data.within.height,
1102                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1103                                 overTop = withinOffset - collisionPosTop,
1104                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105                                 newOverBottom;
1106 
1107                         // Element is taller than within
1108                         if ( data.collisionHeight > outerHeight ) {
1109 
1110                                 // Element is initially over the top of within
1111                                 if ( overTop > 0 && overBottom <= 0 ) {
1112                                         newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113                                                 withinOffset;
1114                                         position.top += overTop - newOverBottom;
1115 
1116                                 // Element is initially over bottom of within
1117                                 } else if ( overBottom > 0 && overTop <= 0 ) {
1118                                         position.top = withinOffset;
1119 
1120                                 // Element is initially over both top and bottom of within
1121                                 } else {
1122                                         if ( overTop > overBottom ) {
1123                                                 position.top = withinOffset + outerHeight - data.collisionHeight;
1124                                         } else {
1125                                                 position.top = withinOffset;
1126                                         }
1127                                 }
1128 
1129                         // Too far up -> align with top
1130                         } else if ( overTop > 0 ) {
1131                                 position.top += overTop;
1132 
1133                         // Too far down -> align with bottom edge
1134                         } else if ( overBottom > 0 ) {
1135                                 position.top -= overBottom;
1136 
1137                         // Adjust based on position and margin
1138                         } else {
1139                                 position.top = max( position.top - collisionPosTop, position.top );
1140                         }
1141                 }
1142         },
1143         flip: {
1144                 left: function( position, data ) {
1145                         var within = data.within,
1146                                 withinOffset = within.offset.left + within.scrollLeft,
1147                                 outerWidth = within.width,
1148                                 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149                                 collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150                                 overLeft = collisionPosLeft - offsetLeft,
1151                                 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152                                 myOffset = data.my[ 0 ] === "left" ?
1153                                         -data.elemWidth :
1154                                         data.my[ 0 ] === "right" ?
1155                                                 data.elemWidth :
1156                                                 0,
1157                                 atOffset = data.at[ 0 ] === "left" ?
1158                                         data.targetWidth :
1159                                         data.at[ 0 ] === "right" ?
1160                                                 -data.targetWidth :
1161                                                 0,
1162                                 offset = -2 * data.offset[ 0 ],
1163                                 newOverRight,
1164                                 newOverLeft;
1165 
1166                         if ( overLeft < 0 ) {
1167                                 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168                                         outerWidth - withinOffset;
1169                                 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170                                         position.left += myOffset + atOffset + offset;
1171                                 }
1172                         } else if ( overRight > 0 ) {
1173                                 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174                                         atOffset + offset - offsetLeft;
1175                                 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176                                         position.left += myOffset + atOffset + offset;
1177                                 }
1178                         }
1179                 },
1180                 top: function( position, data ) {
1181                         var within = data.within,
1182                                 withinOffset = within.offset.top + within.scrollTop,
1183                                 outerHeight = within.height,
1184                                 offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185                                 collisionPosTop = position.top - data.collisionPosition.marginTop,
1186                                 overTop = collisionPosTop - offsetTop,
1187                                 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188                                 top = data.my[ 1 ] === "top",
1189                                 myOffset = top ?
1190                                         -data.elemHeight :
1191                                         data.my[ 1 ] === "bottom" ?
1192                                                 data.elemHeight :
1193                                                 0,
1194                                 atOffset = data.at[ 1 ] === "top" ?
1195                                         data.targetHeight :
1196                                         data.at[ 1 ] === "bottom" ?
1197                                                 -data.targetHeight :
1198                                                 0,
1199                                 offset = -2 * data.offset[ 1 ],
1200                                 newOverTop,
1201                                 newOverBottom;
1202                         if ( overTop < 0 ) {
1203                                 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204                                         outerHeight - withinOffset;
1205                                 if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206                                         position.top += myOffset + atOffset + offset;
1207                                 }
1208                         } else if ( overBottom > 0 ) {
1209                                 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210                                         offset - offsetTop;
1211                                 if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212                                         position.top += myOffset + atOffset + offset;
1213                                 }
1214                         }
1215                 }
1216         },
1217         flipfit: {
1218                 left: function() {
1219                         $.ui.position.flip.left.apply( this, arguments );
1220                         $.ui.position.fit.left.apply( this, arguments );
1221                 },
1222                 top: function() {
1223                         $.ui.position.flip.top.apply( this, arguments );
1224                         $.ui.position.fit.top.apply( this, arguments );
1225                 }
1226         }
1227 };
1228 
1229 } )();
1230 
1231 var position = $.ui.position;
1232 
1233 
1234 /*!
1235  * jQuery UI :data 1.12.1
1236  * http://jqueryui.com
1237  *
1238  * Copyright jQuery Foundation and other contributors
1239  * Released under the MIT license.
1240  * http://jquery.org/license
1241  */
1242 
1243 //>>label: :data Selector
1244 //>>group: Core
1245 //>>description: Selects elements which have data stored under the specified key.
1246 //>>docs: http://api.jqueryui.com/data-selector/
1247 
1248 
1249 var data = $.extend( $.expr[ ":" ], {
1250         data: $.expr.createPseudo ?
1251                 $.expr.createPseudo( function( dataName ) {
1252                         return function( elem ) {
1253                                 return !!$.data( elem, dataName );
1254                         };
1255                 } ) :
1256 
1257                 // Support: jQuery <1.8
1258                 function( elem, i, match ) {
1259                         return !!$.data( elem, match[ 3 ] );
1260                 }
1261 } );
1262 
1263 /*!
1264  * jQuery UI Disable Selection 1.12.1
1265  * http://jqueryui.com
1266  *
1267  * Copyright jQuery Foundation and other contributors
1268  * Released under the MIT license.
1269  * http://jquery.org/license
1270  */
1271 
1272 //>>label: disableSelection
1273 //>>group: Core
1274 //>>description: Disable selection of text content within the set of matched elements.
1275 //>>docs: http://api.jqueryui.com/disableSelection/
1276 
1277 // This file is deprecated
1278 
1279 
1280 var disableSelection = $.fn.extend( {
1281         disableSelection: ( function() {
1282                 var eventType = "onselectstart" in document.createElement( "div" ) ?
1283                         "selectstart" :
1284                         "mousedown";
1285 
1286                 return function() {
1287                         return this.on( eventType + ".ui-disableSelection", function( event ) {
1288                                 event.preventDefault();
1289                         } );
1290                 };
1291         } )(),
1292 
1293         enableSelection: function() {
1294                 return this.off( ".ui-disableSelection" );
1295         }
1296 } );
1297 
1298 
1299 /*!
1300  * jQuery UI Effects 1.12.1
1301  * http://jqueryui.com
1302  *
1303  * Copyright jQuery Foundation and other contributors
1304  * Released under the MIT license.
1305  * http://jquery.org/license
1306  */
1307 
1308 //>>label: Effects Core
1309 //>>group: Effects
1310 // jscs:disable maximumLineLength
1311 //>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1312 // jscs:enable maximumLineLength
1313 //>>docs: http://api.jqueryui.com/category/effects-core/
1314 //>>demos: http://jqueryui.com/effect/
1315 
1316 
1317 
1318 var dataSpace = "ui-effects-",
1319         dataSpaceStyle = "ui-effects-style",
1320         dataSpaceAnimated = "ui-effects-animated",
1321 
1322         // Create a local jQuery because jQuery Color relies on it and the
1323         // global may not exist with AMD and a custom build (#10199)
1324         jQuery = $;
1325 
1326 $.effects = {
1327         effect: {}
1328 };
1329 
1330 /*!
1331  * jQuery Color Animations v2.1.2
1332  * https://github.com/jquery/jquery-color
1333  *
1334  * Copyright 2014 jQuery Foundation and other contributors
1335  * Released under the MIT license.
1336  * http://jquery.org/license
1337  *
1338  * Date: Wed Jan 16 08:47:09 2013 -0600
1339  */
1340 ( function( jQuery, undefined ) {
1341 
1342         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1343                 "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1344 
1345         // Plusequals test for += 100 -= 100
1346         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1347 
1348         // A set of RE's that can match strings and generate color tuples.
1349         stringParsers = [ {
1350                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1351                         parse: function( execResult ) {
1352                                 return [
1353                                         execResult[ 1 ],
1354                                         execResult[ 2 ],
1355                                         execResult[ 3 ],
1356                                         execResult[ 4 ]
1357                                 ];
1358                         }
1359                 }, {
1360                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1361                         parse: function( execResult ) {
1362                                 return [
1363                                         execResult[ 1 ] * 2.55,
1364                                         execResult[ 2 ] * 2.55,
1365                                         execResult[ 3 ] * 2.55,
1366                                         execResult[ 4 ]
1367                                 ];
1368                         }
1369                 }, {
1370 
1371                         // This regex ignores A-F because it's compared against an already lowercased string
1372                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1373                         parse: function( execResult ) {
1374                                 return [
1375                                         parseInt( execResult[ 1 ], 16 ),
1376                                         parseInt( execResult[ 2 ], 16 ),
1377                                         parseInt( execResult[ 3 ], 16 )
1378                                 ];
1379                         }
1380                 }, {
1381 
1382                         // This regex ignores A-F because it's compared against an already lowercased string
1383                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1384                         parse: function( execResult ) {
1385                                 return [
1386                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1387                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1388                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1389                                 ];
1390                         }
1391                 }, {
1392                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1393                         space: "hsla",
1394                         parse: function( execResult ) {
1395                                 return [
1396                                         execResult[ 1 ],
1397                                         execResult[ 2 ] / 100,
1398                                         execResult[ 3 ] / 100,
1399                                         execResult[ 4 ]
1400                                 ];
1401                         }
1402                 } ],
1403 
1404         // JQuery.Color( )
1405         color = jQuery.Color = function( color, green, blue, alpha ) {
1406                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
1407         },
1408         spaces = {
1409                 rgba: {
1410                         props: {
1411                                 red: {
1412                                         idx: 0,
1413                                         type: "byte"
1414                                 },
1415                                 green: {
1416                                         idx: 1,
1417                                         type: "byte"
1418                                 },
1419                                 blue: {
1420                                         idx: 2,
1421                                         type: "byte"
1422                                 }
1423                         }
1424                 },
1425 
1426                 hsla: {
1427                         props: {
1428                                 hue: {
1429                                         idx: 0,
1430                                         type: "degrees"
1431                                 },
1432                                 saturation: {
1433                                         idx: 1,
1434                                         type: "percent"
1435                                 },
1436                                 lightness: {
1437                                         idx: 2,
1438                                         type: "percent"
1439                                 }
1440                         }
1441                 }
1442         },
1443         propTypes = {
1444                 "byte": {
1445                         floor: true,
1446                         max: 255
1447                 },
1448                 "percent": {
1449                         max: 1
1450                 },
1451                 "degrees": {
1452                         mod: 360,
1453                         floor: true
1454                 }
1455         },
1456         support = color.support = {},
1457 
1458         // Element for support tests
1459         supportElem = jQuery( "<p>" )[ 0 ],
1460 
1461         // Colors = jQuery.Color.names
1462         colors,
1463 
1464         // Local aliases of functions called often
1465         each = jQuery.each;
1466 
1467 // Determine rgba support immediately
1468 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1469 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1470 
1471 // Define cache name and alpha properties
1472 // for rgba and hsla spaces
1473 each( spaces, function( spaceName, space ) {
1474         space.cache = "_" + spaceName;
1475         space.props.alpha = {
1476                 idx: 3,
1477                 type: "percent",
1478                 def: 1
1479         };
1480 } );
1481 
1482 function clamp( value, prop, allowEmpty ) {
1483         var type = propTypes[ prop.type ] || {};
1484 
1485         if ( value == null ) {
1486                 return ( allowEmpty || !prop.def ) ? null : prop.def;
1487         }
1488 
1489         // ~~ is an short way of doing floor for positive numbers
1490         value = type.floor ? ~~value : parseFloat( value );
1491 
1492         // IE will pass in empty strings as value for alpha,
1493         // which will hit this case
1494         if ( isNaN( value ) ) {
1495                 return prop.def;
1496         }
1497 
1498         if ( type.mod ) {
1499 
1500                 // We add mod before modding to make sure that negatives values
1501                 // get converted properly: -10 -> 350
1502                 return ( value + type.mod ) % type.mod;
1503         }
1504 
1505         // For now all property types without mod have min and max
1506         return 0 > value ? 0 : type.max < value ? type.max : value;
1507 }
1508 
1509 function stringParse( string ) {
1510         var inst = color(),
1511                 rgba = inst._rgba = [];
1512 
1513         string = string.toLowerCase();
1514 
1515         each( stringParsers, function( i, parser ) {
1516                 var parsed,
1517                         match = parser.re.exec( string ),
1518                         values = match && parser.parse( match ),
1519                         spaceName = parser.space || "rgba";
1520 
1521                 if ( values ) {
1522                         parsed = inst[ spaceName ]( values );
1523 
1524                         // If this was an rgba parse the assignment might happen twice
1525                         // oh well....
1526                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1527                         rgba = inst._rgba = parsed._rgba;
1528 
1529                         // Exit each( stringParsers ) here because we matched
1530                         return false;
1531                 }
1532         } );
1533 
1534         // Found a stringParser that handled it
1535         if ( rgba.length ) {
1536 
1537                 // If this came from a parsed string, force "transparent" when alpha is 0
1538                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1539                 if ( rgba.join() === "0,0,0,0" ) {
1540                         jQuery.extend( rgba, colors.transparent );
1541                 }
1542                 return inst;
1543         }
1544 
1545         // Named colors
1546         return colors[ string ];
1547 }
1548 
1549 color.fn = jQuery.extend( color.prototype, {
1550         parse: function( red, green, blue, alpha ) {
1551                 if ( red === undefined ) {
1552                         this._rgba = [ null, null, null, null ];
1553                         return this;
1554                 }
1555                 if ( red.jquery || red.nodeType ) {
1556                         red = jQuery( red ).css( green );
1557                         green = undefined;
1558                 }
1559 
1560                 var inst = this,
1561                         type = jQuery.type( red ),
1562                         rgba = this._rgba = [];
1563 
1564                 // More than 1 argument specified - assume ( red, green, blue, alpha )
1565                 if ( green !== undefined ) {
1566                         red = [ red, green, blue, alpha ];
1567                         type = "array";
1568                 }
1569 
1570                 if ( type === "string" ) {
1571                         return this.parse( stringParse( red ) || colors._default );
1572                 }
1573 
1574                 if ( type === "array" ) {
1575                         each( spaces.rgba.props, function( key, prop ) {
1576                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1577                         } );
1578                         return this;
1579                 }
1580 
1581                 if ( type === "object" ) {
1582                         if ( red instanceof color ) {
1583                                 each( spaces, function( spaceName, space ) {
1584                                         if ( red[ space.cache ] ) {
1585                                                 inst[ space.cache ] = red[ space.cache ].slice();
1586                                         }
1587                                 } );
1588                         } else {
1589                                 each( spaces, function( spaceName, space ) {
1590                                         var cache = space.cache;
1591                                         each( space.props, function( key, prop ) {
1592 
1593                                                 // If the cache doesn't exist, and we know how to convert
1594                                                 if ( !inst[ cache ] && space.to ) {
1595 
1596                                                         // If the value was null, we don't need to copy it
1597                                                         // if the key was alpha, we don't need to copy it either
1598                                                         if ( key === "alpha" || red[ key ] == null ) {
1599                                                                 return;
1600                                                         }
1601                                                         inst[ cache ] = space.to( inst._rgba );
1602                                                 }
1603 
1604                                                 // This is the only case where we allow nulls for ALL properties.
1605                                                 // call clamp with alwaysAllowEmpty
1606                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1607                                         } );
1608 
1609                                         // Everything defined but alpha?
1610                                         if ( inst[ cache ] &&
1611                                                         jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1612 
1613                                                 // Use the default of 1
1614                                                 inst[ cache ][ 3 ] = 1;
1615                                                 if ( space.from ) {
1616                                                         inst._rgba = space.from( inst[ cache ] );
1617                                                 }
1618                                         }
1619                                 } );
1620                         }
1621                         return this;
1622                 }
1623         },
1624         is: function( compare ) {
1625                 var is = color( compare ),
1626                         same = true,
1627                         inst = this;
1628 
1629                 each( spaces, function( _, space ) {
1630                         var localCache,
1631                                 isCache = is[ space.cache ];
1632                         if ( isCache ) {
1633                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1634                                 each( space.props, function( _, prop ) {
1635                                         if ( isCache[ prop.idx ] != null ) {
1636                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1637                                                 return same;
1638                                         }
1639                                 } );
1640                         }
1641                         return same;
1642                 } );
1643                 return same;
1644         },
1645         _space: function() {
1646                 var used = [],
1647                         inst = this;
1648                 each( spaces, function( spaceName, space ) {
1649                         if ( inst[ space.cache ] ) {
1650                                 used.push( spaceName );
1651                         }
1652                 } );
1653                 return used.pop();
1654         },
1655         transition: function( other, distance ) {
1656                 var end = color( other ),
1657                         spaceName = end._space(),
1658                         space = spaces[ spaceName ],
1659                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1660                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
1661                         result = start.slice();
1662 
1663                 end = end[ space.cache ];
1664                 each( space.props, function( key, prop ) {
1665                         var index = prop.idx,
1666                                 startValue = start[ index ],
1667                                 endValue = end[ index ],
1668                                 type = propTypes[ prop.type ] || {};
1669 
1670                         // If null, don't override start value
1671                         if ( endValue === null ) {
1672                                 return;
1673                         }
1674 
1675                         // If null - use end
1676                         if ( startValue === null ) {
1677                                 result[ index ] = endValue;
1678                         } else {
1679                                 if ( type.mod ) {
1680                                         if ( endValue - startValue > type.mod / 2 ) {
1681                                                 startValue += type.mod;
1682                                         } else if ( startValue - endValue > type.mod / 2 ) {
1683                                                 startValue -= type.mod;
1684                                         }
1685                                 }
1686                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1687                         }
1688                 } );
1689                 return this[ spaceName ]( result );
1690         },
1691         blend: function( opaque ) {
1692 
1693                 // If we are already opaque - return ourself
1694                 if ( this._rgba[ 3 ] === 1 ) {
1695                         return this;
1696                 }
1697 
1698                 var rgb = this._rgba.slice(),
1699                         a = rgb.pop(),
1700                         blend = color( opaque )._rgba;
1701 
1702                 return color( jQuery.map( rgb, function( v, i ) {
1703                         return ( 1 - a ) * blend[ i ] + a * v;
1704                 } ) );
1705         },
1706         toRgbaString: function() {
1707                 var prefix = "rgba(",
1708                         rgba = jQuery.map( this._rgba, function( v, i ) {
1709                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
1710                         } );
1711 
1712                 if ( rgba[ 3 ] === 1 ) {
1713                         rgba.pop();
1714                         prefix = "rgb(";
1715                 }
1716 
1717                 return prefix + rgba.join() + ")";
1718         },
1719         toHslaString: function() {
1720                 var prefix = "hsla(",
1721                         hsla = jQuery.map( this.hsla(), function( v, i ) {
1722                                 if ( v == null ) {
1723                                         v = i > 2 ? 1 : 0;
1724                                 }
1725 
1726                                 // Catch 1 and 2
1727                                 if ( i && i < 3 ) {
1728                                         v = Math.round( v * 100 ) + "%";
1729                                 }
1730                                 return v;
1731                         } );
1732 
1733                 if ( hsla[ 3 ] === 1 ) {
1734                         hsla.pop();
1735                         prefix = "hsl(";
1736                 }
1737                 return prefix + hsla.join() + ")";
1738         },
1739         toHexString: function( includeAlpha ) {
1740                 var rgba = this._rgba.slice(),
1741                         alpha = rgba.pop();
1742 
1743                 if ( includeAlpha ) {
1744                         rgba.push( ~~( alpha * 255 ) );
1745                 }
1746 
1747                 return "#" + jQuery.map( rgba, function( v ) {
1748 
1749                         // Default to 0 when nulls exist
1750                         v = ( v || 0 ).toString( 16 );
1751                         return v.length === 1 ? "0" + v : v;
1752                 } ).join( "" );
1753         },
1754         toString: function() {
1755                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1756         }
1757 } );
1758 color.fn.parse.prototype = color.fn;
1759 
1760 // Hsla conversions adapted from:
1761 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1762 
1763 function hue2rgb( p, q, h ) {
1764         h = ( h + 1 ) % 1;
1765         if ( h * 6 < 1 ) {
1766                 return p + ( q - p ) * h * 6;
1767         }
1768         if ( h * 2 < 1 ) {
1769                 return q;
1770         }
1771         if ( h * 3 < 2 ) {
1772                 return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1773         }
1774         return p;
1775 }
1776 
1777 spaces.hsla.to = function( rgba ) {
1778         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1779                 return [ null, null, null, rgba[ 3 ] ];
1780         }
1781         var r = rgba[ 0 ] / 255,
1782                 g = rgba[ 1 ] / 255,
1783                 b = rgba[ 2 ] / 255,
1784                 a = rgba[ 3 ],
1785                 max = Math.max( r, g, b ),
1786                 min = Math.min( r, g, b ),
1787                 diff = max - min,
1788                 add = max + min,
1789                 l = add * 0.5,
1790                 h, s;
1791 
1792         if ( min === max ) {
1793                 h = 0;
1794         } else if ( r === max ) {
1795                 h = ( 60 * ( g - b ) / diff ) + 360;
1796         } else if ( g === max ) {
1797                 h = ( 60 * ( b - r ) / diff ) + 120;
1798         } else {
1799                 h = ( 60 * ( r - g ) / diff ) + 240;
1800         }
1801 
1802         // Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1803         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1804         if ( diff === 0 ) {
1805                 s = 0;
1806         } else if ( l <= 0.5 ) {
1807                 s = diff / add;
1808         } else {
1809                 s = diff / ( 2 - add );
1810         }
1811         return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1812 };
1813 
1814 spaces.hsla.from = function( hsla ) {
1815         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1816                 return [ null, null, null, hsla[ 3 ] ];
1817         }
1818         var h = hsla[ 0 ] / 360,
1819                 s = hsla[ 1 ],
1820                 l = hsla[ 2 ],
1821                 a = hsla[ 3 ],
1822                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1823                 p = 2 * l - q;
1824 
1825         return [
1826                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1827                 Math.round( hue2rgb( p, q, h ) * 255 ),
1828                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1829                 a
1830         ];
1831 };
1832 
1833 each( spaces, function( spaceName, space ) {
1834         var props = space.props,
1835                 cache = space.cache,
1836                 to = space.to,
1837                 from = space.from;
1838 
1839         // Makes rgba() and hsla()
1840         color.fn[ spaceName ] = function( value ) {
1841 
1842                 // Generate a cache for this space if it doesn't exist
1843                 if ( to && !this[ cache ] ) {
1844                         this[ cache ] = to( this._rgba );
1845                 }
1846                 if ( value === undefined ) {
1847                         return this[ cache ].slice();
1848                 }
1849 
1850                 var ret,
1851                         type = jQuery.type( value ),
1852                         arr = ( type === "array" || type === "object" ) ? value : arguments,
1853                         local = this[ cache ].slice();
1854 
1855                 each( props, function( key, prop ) {
1856                         var val = arr[ type === "object" ? key : prop.idx ];
1857                         if ( val == null ) {
1858                                 val = local[ prop.idx ];
1859                         }
1860                         local[ prop.idx ] = clamp( val, prop );
1861                 } );
1862 
1863                 if ( from ) {
1864                         ret = color( from( local ) );
1865                         ret[ cache ] = local;
1866                         return ret;
1867                 } else {
1868                         return color( local );
1869                 }
1870         };
1871 
1872         // Makes red() green() blue() alpha() hue() saturation() lightness()
1873         each( props, function( key, prop ) {
1874 
1875                 // Alpha is included in more than one space
1876                 if ( color.fn[ key ] ) {
1877                         return;
1878                 }
1879                 color.fn[ key ] = function( value ) {
1880                         var vtype = jQuery.type( value ),
1881                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1882                                 local = this[ fn ](),
1883                                 cur = local[ prop.idx ],
1884                                 match;
1885 
1886                         if ( vtype === "undefined" ) {
1887                                 return cur;
1888                         }
1889 
1890                         if ( vtype === "function" ) {
1891                                 value = value.call( this, cur );
1892                                 vtype = jQuery.type( value );
1893                         }
1894                         if ( value == null && prop.empty ) {
1895                                 return this;
1896                         }
1897                         if ( vtype === "string" ) {
1898                                 match = rplusequals.exec( value );
1899                                 if ( match ) {
1900                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1901                                 }
1902                         }
1903                         local[ prop.idx ] = value;
1904                         return this[ fn ]( local );
1905                 };
1906         } );
1907 } );
1908 
1909 // Add cssHook and .fx.step function for each named hook.
1910 // accept a space separated string of properties
1911 color.hook = function( hook ) {
1912         var hooks = hook.split( " " );
1913         each( hooks, function( i, hook ) {
1914                 jQuery.cssHooks[ hook ] = {
1915                         set: function( elem, value ) {
1916                                 var parsed, curElem,
1917                                         backgroundColor = "";
1918 
1919                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1920                                                 ( parsed = stringParse( value ) ) ) ) {
1921                                         value = color( parsed || value );
1922                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1923                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1924                                                 while (
1925                                                         ( backgroundColor === "" || backgroundColor === "transparent" ) &&
1926                                                         curElem && curElem.style
1927                                                 ) {
1928                                                         try {
1929                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
1930                                                                 curElem = curElem.parentNode;
1931                                                         } catch ( e ) {
1932                                                         }
1933                                                 }
1934 
1935                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1936                                                         backgroundColor :
1937                                                         "_default" );
1938                                         }
1939 
1940                                         value = value.toRgbaString();
1941                                 }
1942                                 try {
1943                                         elem.style[ hook ] = value;
1944                                 } catch ( e ) {
1945 
1946                                         // Wrapped to prevent IE from throwing errors on "invalid" values like
1947                                         // 'auto' or 'inherit'
1948                                 }
1949                         }
1950                 };
1951                 jQuery.fx.step[ hook ] = function( fx ) {
1952                         if ( !fx.colorInit ) {
1953                                 fx.start = color( fx.elem, hook );
1954                                 fx.end = color( fx.end );
1955                                 fx.colorInit = true;
1956                         }
1957                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1958                 };
1959         } );
1960 
1961 };
1962 
1963 color.hook( stepHooks );
1964 
1965 jQuery.cssHooks.borderColor = {
1966         expand: function( value ) {
1967                 var expanded = {};
1968 
1969                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1970                         expanded[ "border" + part + "Color" ] = value;
1971                 } );
1972                 return expanded;
1973         }
1974 };
1975 
1976 // Basic color names only.
1977 // Usage of any of the other color names requires adding yourself or including
1978 // jquery.color.svg-names.js.
1979 colors = jQuery.Color.names = {
1980 
1981         // 4.1. Basic color keywords
1982         aqua: "#00ffff",
1983         black: "#000000",
1984         blue: "#0000ff",
1985         fuchsia: "#ff00ff",
1986         gray: "#808080",
1987         green: "#008000",
1988         lime: "#00ff00",
1989         maroon: "#800000",
1990         navy: "#000080",
1991         olive: "#808000",
1992         purple: "#800080",
1993         red: "#ff0000",
1994         silver: "#c0c0c0",
1995         teal: "#008080",
1996         white: "#ffffff",
1997         yellow: "#ffff00",
1998 
1999         // 4.2.3. "transparent" color keyword
2000         transparent: [ null, null, null, 0 ],
2001 
2002         _default: "#ffffff"
2003 };
2004 
2005 } )( jQuery );
2006 
2007 /******************************************************************************/
2008 /****************************** CLASS ANIMATIONS ******************************/
2009 /******************************************************************************/
2010 ( function() {
2011 
2012 var classAnimationActions = [ "add", "remove", "toggle" ],
2013         shorthandStyles = {
2014                 border: 1,
2015                 borderBottom: 1,
2016                 borderColor: 1,
2017                 borderLeft: 1,
2018                 borderRight: 1,
2019                 borderTop: 1,
2020                 borderWidth: 1,
2021                 margin: 1,
2022                 padding: 1
2023         };
2024 
2025 $.each(
2026         [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2027         function( _, prop ) {
2028                 $.fx.step[ prop ] = function( fx ) {
2029                         if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2030                                 jQuery.style( fx.elem, prop, fx.end );
2031                                 fx.setAttr = true;
2032                         }
2033                 };
2034         }
2035 );
2036 
2037 function getElementStyles( elem ) {
2038         var key, len,
2039                 style = elem.ownerDocument.defaultView ?
2040                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2041                         elem.currentStyle,
2042                 styles = {};
2043 
2044         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2045                 len = style.length;
2046                 while ( len-- ) {
2047                         key = style[ len ];
2048                         if ( typeof style[ key ] === "string" ) {
2049                                 styles[ $.camelCase( key ) ] = style[ key ];
2050                         }
2051                 }
2052 
2053         // Support: Opera, IE <9
2054         } else {
2055                 for ( key in style ) {
2056                         if ( typeof style[ key ] === "string" ) {
2057                                 styles[ key ] = style[ key ];
2058                         }
2059                 }
2060         }
2061 
2062         return styles;
2063 }
2064 
2065 function styleDifference( oldStyle, newStyle ) {
2066         var diff = {},
2067                 name, value;
2068 
2069         for ( name in newStyle ) {
2070                 value = newStyle[ name ];
2071                 if ( oldStyle[ name ] !== value ) {
2072                         if ( !shorthandStyles[ name ] ) {
2073                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2074                                         diff[ name ] = value;
2075                                 }
2076                         }
2077                 }
2078         }
2079 
2080         return diff;
2081 }
2082 
2083 // Support: jQuery <1.8
2084 if ( !$.fn.addBack ) {
2085         $.fn.addBack = function( selector ) {
2086                 return this.add( selector == null ?
2087                         this.prevObject : this.prevObject.filter( selector )
2088                 );
2089         };
2090 }
2091 
2092 $.effects.animateClass = function( value, duration, easing, callback ) {
2093         var o = $.speed( duration, easing, callback );
2094 
2095         return this.queue( function() {
2096                 var animated = $( this ),
2097                         baseClass = animated.attr( "class" ) || "",
2098                         applyClassChange,
2099                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2100 
2101                 // Map the animated objects to store the original styles.
2102                 allAnimations = allAnimations.map( function() {
2103                         var el = $( this );
2104                         return {
2105                                 el: el,
2106                                 start: getElementStyles( this )
2107                         };
2108                 } );
2109 
2110                 // Apply class change
2111                 applyClassChange = function() {
2112                         $.each( classAnimationActions, function( i, action ) {
2113                                 if ( value[ action ] ) {
2114                                         animated[ action + "Class" ]( value[ action ] );
2115                                 }
2116                         } );
2117                 };
2118                 applyClassChange();
2119 
2120                 // Map all animated objects again - calculate new styles and diff
2121                 allAnimations = allAnimations.map( function() {
2122                         this.end = getElementStyles( this.el[ 0 ] );
2123                         this.diff = styleDifference( this.start, this.end );
2124                         return this;
2125                 } );
2126 
2127                 // Apply original class
2128                 animated.attr( "class", baseClass );
2129 
2130                 // Map all animated objects again - this time collecting a promise
2131                 allAnimations = allAnimations.map( function() {
2132                         var styleInfo = this,
2133                                 dfd = $.Deferred(),
2134                                 opts = $.extend( {}, o, {
2135                                         queue: false,
2136                                         complete: function() {
2137                                                 dfd.resolve( styleInfo );
2138                                         }
2139                                 } );
2140 
2141                         this.el.animate( this.diff, opts );
2142                         return dfd.promise();
2143                 } );
2144 
2145                 // Once all animations have completed:
2146                 $.when.apply( $, allAnimations.get() ).done( function() {
2147 
2148                         // Set the final class
2149                         applyClassChange();
2150 
2151                         // For each animated element,
2152                         // clear all css properties that were animated
2153                         $.each( arguments, function() {
2154                                 var el = this.el;
2155                                 $.each( this.diff, function( key ) {
2156                                         el.css( key, "" );
2157                                 } );
2158                         } );
2159 
2160                         // This is guarnteed to be there if you use jQuery.speed()
2161                         // it also handles dequeuing the next anim...
2162                         o.complete.call( animated[ 0 ] );
2163                 } );
2164         } );
2165 };
2166 
2167 $.fn.extend( {
2168         addClass: ( function( orig ) {
2169                 return function( classNames, speed, easing, callback ) {
2170                         return speed ?
2171                                 $.effects.animateClass.call( this,
2172                                         { add: classNames }, speed, easing, callback ) :
2173                                 orig.apply( this, arguments );
2174                 };
2175         } )( $.fn.addClass ),
2176 
2177         removeClass: ( function( orig ) {
2178                 return function( classNames, speed, easing, callback ) {
2179                         return arguments.length > 1 ?
2180                                 $.effects.animateClass.call( this,
2181                                         { remove: classNames }, speed, easing, callback ) :
2182                                 orig.apply( this, arguments );
2183                 };
2184         } )( $.fn.removeClass ),
2185 
2186         toggleClass: ( function( orig ) {
2187                 return function( classNames, force, speed, easing, callback ) {
2188                         if ( typeof force === "boolean" || force === undefined ) {
2189                                 if ( !speed ) {
2190 
2191                                         // Without speed parameter
2192                                         return orig.apply( this, arguments );
2193                                 } else {
2194                                         return $.effects.animateClass.call( this,
2195                                                 ( force ? { add: classNames } : { remove: classNames } ),
2196                                                 speed, easing, callback );
2197                                 }
2198                         } else {
2199 
2200                                 // Without force parameter
2201                                 return $.effects.animateClass.call( this,
2202                                         { toggle: classNames }, force, speed, easing );
2203                         }
2204                 };
2205         } )( $.fn.toggleClass ),
2206 
2207         switchClass: function( remove, add, speed, easing, callback ) {
2208                 return $.effects.animateClass.call( this, {
2209                         add: add,
2210                         remove: remove
2211                 }, speed, easing, callback );
2212         }
2213 } );
2214 
2215 } )();
2216 
2217 /******************************************************************************/
2218 /*********************************** EFFECTS **********************************/
2219 /******************************************************************************/
2220 
2221 ( function() {
2222 
2223 if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2224         $.expr.filters.animated = ( function( orig ) {
2225                 return function( elem ) {
2226                         return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2227                 };
2228         } )( $.expr.filters.animated );
2229 }
2230 
2231 if ( $.uiBackCompat !== false ) {
2232         $.extend( $.effects, {
2233 
2234                 // Saves a set of properties in a data storage
2235                 save: function( element, set ) {
2236                         var i = 0, length = set.length;
2237                         for ( ; i < length; i++ ) {
2238                                 if ( set[ i ] !== null ) {
2239                                         element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2240                                 }
2241                         }
2242                 },
2243 
2244                 // Restores a set of previously saved properties from a data storage
2245                 restore: function( element, set ) {
2246                         var val, i = 0, length = set.length;
2247                         for ( ; i < length; i++ ) {
2248                                 if ( set[ i ] !== null ) {
2249                                         val = element.data( dataSpace + set[ i ] );
2250                                         element.css( set[ i ], val );
2251                                 }
2252                         }
2253                 },
2254 
2255                 setMode: function( el, mode ) {
2256                         if ( mode === "toggle" ) {
2257                                 mode = el.is( ":hidden" ) ? "show" : "hide";
2258                         }
2259                         return mode;
2260                 },
2261 
2262                 // Wraps the element around a wrapper that copies position properties
2263                 createWrapper: function( element ) {
2264 
2265                         // If the element is already wrapped, return it
2266                         if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2267                                 return element.parent();
2268                         }
2269 
2270                         // Wrap the element
2271                         var props = {
2272                                         width: element.outerWidth( true ),
2273                                         height: element.outerHeight( true ),
2274                                         "float": element.css( "float" )
2275                                 },
2276                                 wrapper = $( "<div></div>" )
2277                                         .addClass( "ui-effects-wrapper" )
2278                                         .css( {
2279                                                 fontSize: "100%",
2280                                                 background: "transparent",
2281                                                 border: "none",
2282                                                 margin: 0,
2283                                                 padding: 0
2284                                         } ),
2285 
2286                                 // Store the size in case width/height are defined in % - Fixes #5245
2287                                 size = {
2288                                         width: element.width(),
2289                                         height: element.height()
2290                                 },
2291                                 active = document.activeElement;
2292 
2293                         // Support: Firefox
2294                         // Firefox incorrectly exposes anonymous content
2295                         // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2296                         try {
2297                                 active.id;
2298                         } catch ( e ) {
2299                                 active = document.body;
2300                         }
2301 
2302                         element.wrap( wrapper );
2303 
2304                         // Fixes #7595 - Elements lose focus when wrapped.
2305                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2306                                 $( active ).trigger( "focus" );
2307                         }
2308 
2309                         // Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2310                         // lose the reference to the wrapped element
2311                         wrapper = element.parent();
2312 
2313                         // Transfer positioning properties to the wrapper
2314                         if ( element.css( "position" ) === "static" ) {
2315                                 wrapper.css( { position: "relative" } );
2316                                 element.css( { position: "relative" } );
2317                         } else {
2318                                 $.extend( props, {
2319                                         position: element.css( "position" ),
2320                                         zIndex: element.css( "z-index" )
2321                                 } );
2322                                 $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2323                                         props[ pos ] = element.css( pos );
2324                                         if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2325                                                 props[ pos ] = "auto";
2326                                         }
2327                                 } );
2328                                 element.css( {
2329                                         position: "relative",
2330                                         top: 0,
2331                                         left: 0,
2332                                         right: "auto",
2333                                         bottom: "auto"
2334                                 } );
2335                         }
2336                         element.css( size );
2337 
2338                         return wrapper.css( props ).show();
2339                 },
2340 
2341                 removeWrapper: function( element ) {
2342                         var active = document.activeElement;
2343 
2344                         if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2345                                 element.parent().replaceWith( element );
2346 
2347                                 // Fixes #7595 - Elements lose focus when wrapped.
2348                                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2349                                         $( active ).trigger( "focus" );
2350                                 }
2351                         }
2352 
2353                         return element;
2354                 }
2355         } );
2356 }
2357 
2358 $.extend( $.effects, {
2359         version: "1.12.1",
2360 
2361         define: function( name, mode, effect ) {
2362                 if ( !effect ) {
2363                         effect = mode;
2364                         mode = "effect";
2365                 }
2366 
2367                 $.effects.effect[ name ] = effect;
2368                 $.effects.effect[ name ].mode = mode;
2369 
2370                 return effect;
2371         },
2372 
2373         scaledDimensions: function( element, percent, direction ) {
2374                 if ( percent === 0 ) {
2375                         return {
2376                                 height: 0,
2377                                 width: 0,
2378                                 outerHeight: 0,
2379                                 outerWidth: 0
2380                         };
2381                 }
2382 
2383                 var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2384                         y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2385 
2386                 return {
2387                         height: element.height() * y,
2388                         width: element.width() * x,
2389                         outerHeight: element.outerHeight() * y,
2390                         outerWidth: element.outerWidth() * x
2391                 };
2392 
2393         },
2394 
2395         clipToBox: function( animation ) {
2396                 return {
2397                         width: animation.clip.right - animation.clip.left,
2398                         height: animation.clip.bottom - animation.clip.top,
2399                         left: animation.clip.left,
2400                         top: animation.clip.top
2401                 };
2402         },
2403 
2404         // Injects recently queued functions to be first in line (after "inprogress")
2405         unshift: function( element, queueLength, count ) {
2406                 var queue = element.queue();
2407 
2408                 if ( queueLength > 1 ) {
2409                         queue.splice.apply( queue,
2410                                 [ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2411                 }
2412                 element.dequeue();
2413         },
2414 
2415         saveStyle: function( element ) {
2416                 element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2417         },
2418 
2419         restoreStyle: function( element ) {
2420                 element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2421                 element.removeData( dataSpaceStyle );
2422         },
2423 
2424         mode: function( element, mode ) {
2425                 var hidden = element.is( ":hidden" );
2426 
2427                 if ( mode === "toggle" ) {
2428                         mode = hidden ? "show" : "hide";
2429                 }
2430                 if ( hidden ? mode === "hide" : mode === "show" ) {
2431                         mode = "none";
2432                 }
2433                 return mode;
2434         },
2435 
2436         // Translates a [top,left] array into a baseline value
2437         getBaseline: function( origin, original ) {
2438                 var y, x;
2439 
2440                 switch ( origin[ 0 ] ) {
2441                 case "top":
2442                         y = 0;
2443                         break;
2444                 case "middle":
2445                         y = 0.5;
2446                         break;
2447                 case "bottom":
2448                         y = 1;
2449                         break;
2450                 default:
2451                         y = origin[ 0 ] / original.height;
2452                 }
2453 
2454                 switch ( origin[ 1 ] ) {
2455                 case "left":
2456                         x = 0;
2457                         break;
2458                 case "center":
2459                         x = 0.5;
2460                         break;
2461                 case "right":
2462                         x = 1;
2463                         break;
2464                 default:
2465                         x = origin[ 1 ] / original.width;
2466                 }
2467 
2468                 return {
2469                         x: x,
2470                         y: y
2471                 };
2472         },
2473 
2474         // Creates a placeholder element so that the original element can be made absolute
2475         createPlaceholder: function( element ) {
2476                 var placeholder,
2477                         cssPosition = element.css( "position" ),
2478                         position = element.position();
2479 
2480                 // Lock in margins first to account for form elements, which
2481                 // will change margin if you explicitly set height
2482                 // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2483                 // Support: Safari
2484                 element.css( {
2485                         marginTop: element.css( "marginTop" ),
2486                         marginBottom: element.css( "marginBottom" ),
2487                         marginLeft: element.css( "marginLeft" ),
2488                         marginRight: element.css( "marginRight" )
2489                 } )
2490                 .outerWidth( element.outerWidth() )
2491                 .outerHeight( element.outerHeight() );
2492 
2493                 if ( /^(static|relative)/.test( cssPosition ) ) {
2494                         cssPosition = "absolute";
2495 
2496                         placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2497 
2498                                 // Convert inline to inline block to account for inline elements
2499                                 // that turn to inline block based on content (like img)
2500                                 display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2501                                         "inline-block" :
2502                                         "block",
2503                                 visibility: "hidden",
2504 
2505                                 // Margins need to be set to account for margin collapse
2506                                 marginTop: element.css( "marginTop" ),
2507                                 marginBottom: element.css( "marginBottom" ),
2508                                 marginLeft: element.css( "marginLeft" ),
2509                                 marginRight: element.css( "marginRight" ),
2510                                 "float": element.css( "float" )
2511                         } )
2512                         .outerWidth( element.outerWidth() )
2513                         .outerHeight( element.outerHeight() )
2514                         .addClass( "ui-effects-placeholder" );
2515 
2516                         element.data( dataSpace + "placeholder", placeholder );
2517                 }
2518 
2519                 element.css( {
2520                         position: cssPosition,
2521                         left: position.left,
2522                         top: position.top
2523                 } );
2524 
2525                 return placeholder;
2526         },
2527 
2528         removePlaceholder: function( element ) {
2529                 var dataKey = dataSpace + "placeholder",
2530                                 placeholder = element.data( dataKey );
2531 
2532                 if ( placeholder ) {
2533                         placeholder.remove();
2534                         element.removeData( dataKey );
2535                 }
2536         },
2537 
2538         // Removes a placeholder if it exists and restores
2539         // properties that were modified during placeholder creation
2540         cleanUp: function( element ) {
2541                 $.effects.restoreStyle( element );
2542                 $.effects.removePlaceholder( element );
2543         },
2544 
2545         setTransition: function( element, list, factor, value ) {
2546                 value = value || {};
2547                 $.each( list, function( i, x ) {
2548                         var unit = element.cssUnit( x );
2549                         if ( unit[ 0 ] > 0 ) {
2550                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2551                         }
2552                 } );
2553                 return value;
2554         }
2555 } );
2556 
2557 // Return an effect options object for the given parameters:
2558 function _normalizeArguments( effect, options, speed, callback ) {
2559 
2560         // Allow passing all options as the first parameter
2561         if ( $.isPlainObject( effect ) ) {
2562                 options = effect;
2563                 effect = effect.effect;
2564         }
2565 
2566         // Convert to an object
2567         effect = { effect: effect };
2568 
2569         // Catch (effect, null, ...)
2570         if ( options == null ) {
2571                 options = {};
2572         }
2573 
2574         // Catch (effect, callback)
2575         if ( $.isFunction( options ) ) {
2576                 callback = options;
2577                 speed = null;
2578                 options = {};
2579         }
2580 
2581         // Catch (effect, speed, ?)
2582         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2583                 callback = speed;
2584                 speed = options;
2585                 options = {};
2586         }
2587 
2588         // Catch (effect, options, callback)
2589         if ( $.isFunction( speed ) ) {
2590                 callback = speed;
2591                 speed = null;
2592         }
2593 
2594         // Add options to effect
2595         if ( options ) {
2596                 $.extend( effect, options );
2597         }
2598 
2599         speed = speed || options.duration;
2600         effect.duration = $.fx.off ? 0 :
2601                 typeof speed === "number" ? speed :
2602                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2603                 $.fx.speeds._default;
2604 
2605         effect.complete = callback || options.complete;
2606 
2607         return effect;
2608 }
2609 
2610 function standardAnimationOption( option ) {
2611 
2612         // Valid standard speeds (nothing, number, named speed)
2613         if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2614                 return true;
2615         }
2616 
2617         // Invalid strings - treat as "normal" speed
2618         if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2619                 return true;
2620         }
2621 
2622         // Complete callback
2623         if ( $.isFunction( option ) ) {
2624                 return true;
2625         }
2626 
2627         // Options hash (but not naming an effect)
2628         if ( typeof option === "object" && !option.effect ) {
2629                 return true;
2630         }
2631 
2632         // Didn't match any standard API
2633         return false;
2634 }
2635 
2636 $.fn.extend( {
2637         effect: function( /* effect, options, speed, callback */ ) {
2638                 var args = _normalizeArguments.apply( this, arguments ),
2639                         effectMethod = $.effects.effect[ args.effect ],
2640                         defaultMode = effectMethod.mode,
2641                         queue = args.queue,
2642                         queueName = queue || "fx",
2643                         complete = args.complete,
2644                         mode = args.mode,
2645                         modes = [],
2646                         prefilter = function( next ) {
2647                                 var el = $( this ),
2648                                         normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2649 
2650                                 // Sentinel for duck-punching the :animated psuedo-selector
2651                                 el.data( dataSpaceAnimated, true );
2652 
2653                                 // Save effect mode for later use,
2654                                 // we can't just call $.effects.mode again later,
2655                                 // as the .show() below destroys the initial state
2656                                 modes.push( normalizedMode );
2657 
2658                                 // See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2659                                 if ( defaultMode && ( normalizedMode === "show" ||
2660                                                 ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2661                                         el.show();
2662                                 }
2663 
2664                                 if ( !defaultMode || normalizedMode !== "none" ) {
2665                                         $.effects.saveStyle( el );
2666                                 }
2667 
2668                                 if ( $.isFunction( next ) ) {
2669                                         next();
2670                                 }
2671                         };
2672 
2673                 if ( $.fx.off || !effectMethod ) {
2674 
2675                         // Delegate to the original method (e.g., .show()) if possible
2676                         if ( mode ) {
2677                                 return this[ mode ]( args.duration, complete );
2678                         } else {
2679                                 return this.each( function() {
2680                                         if ( complete ) {
2681                                                 complete.call( this );
2682                                         }
2683                                 } );
2684                         }
2685                 }
2686 
2687                 function run( next ) {
2688                         var elem = $( this );
2689 
2690                         function cleanup() {
2691                                 elem.removeData( dataSpaceAnimated );
2692 
2693                                 $.effects.cleanUp( elem );
2694 
2695                                 if ( args.mode === "hide" ) {
2696                                         elem.hide();
2697                                 }
2698 
2699                                 done();
2700                         }
2701 
2702                         function done() {
2703                                 if ( $.isFunction( complete ) ) {
2704                                         complete.call( elem[ 0 ] );
2705                                 }
2706 
2707                                 if ( $.isFunction( next ) ) {
2708                                         next();
2709                                 }
2710                         }
2711 
2712                         // Override mode option on a per element basis,
2713                         // as toggle can be either show or hide depending on element state
2714                         args.mode = modes.shift();
2715 
2716                         if ( $.uiBackCompat !== false && !defaultMode ) {
2717                                 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2718 
2719                                         // Call the core method to track "olddisplay" properly
2720                                         elem[ mode ]();
2721                                         done();
2722                                 } else {
2723                                         effectMethod.call( elem[ 0 ], args, done );
2724                                 }
2725                         } else {
2726                                 if ( args.mode === "none" ) {
2727 
2728                                         // Call the core method to track "olddisplay" properly
2729                                         elem[ mode ]();
2730                                         done();
2731                                 } else {
2732                                         effectMethod.call( elem[ 0 ], args, cleanup );
2733                                 }
2734                         }
2735                 }
2736 
2737                 // Run prefilter on all elements first to ensure that
2738                 // any showing or hiding happens before placeholder creation,
2739                 // which ensures that any layout changes are correctly captured.
2740                 return queue === false ?
2741                         this.each( prefilter ).each( run ) :
2742                         this.queue( queueName, prefilter ).queue( queueName, run );
2743         },
2744 
2745         show: ( function( orig ) {
2746                 return function( option ) {
2747                         if ( standardAnimationOption( option ) ) {
2748                                 return orig.apply( this, arguments );
2749                         } else {
2750                                 var args = _normalizeArguments.apply( this, arguments );
2751                                 args.mode = "show";
2752                                 return this.effect.call( this, args );
2753                         }
2754                 };
2755         } )( $.fn.show ),
2756 
2757         hide: ( function( orig ) {
2758                 return function( option ) {
2759                         if ( standardAnimationOption( option ) ) {
2760                                 return orig.apply( this, arguments );
2761                         } else {
2762                                 var args = _normalizeArguments.apply( this, arguments );
2763                                 args.mode = "hide";
2764                                 return this.effect.call( this, args );
2765                         }
2766                 };
2767         } )( $.fn.hide ),
2768 
2769         toggle: ( function( orig ) {
2770                 return function( option ) {
2771                         if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2772                                 return orig.apply( this, arguments );
2773                         } else {
2774                                 var args = _normalizeArguments.apply( this, arguments );
2775                                 args.mode = "toggle";
2776                                 return this.effect.call( this, args );
2777                         }
2778                 };
2779         } )( $.fn.toggle ),
2780 
2781         cssUnit: function( key ) {
2782                 var style = this.css( key ),
2783                         val = [];
2784 
2785                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2786                         if ( style.indexOf( unit ) > 0 ) {
2787                                 val = [ parseFloat( style ), unit ];
2788                         }
2789                 } );
2790                 return val;
2791         },
2792 
2793         cssClip: function( clipObj ) {
2794                 if ( clipObj ) {
2795                         return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2796                                 clipObj.bottom + "px " + clipObj.left + "px)" );
2797                 }
2798                 return parseClip( this.css( "clip" ), this );
2799         },
2800 
2801         transfer: function( options, done ) {
2802                 var element = $( this ),
2803                         target = $( options.to ),
2804                         targetFixed = target.css( "position" ) === "fixed",
2805                         body = $( "body" ),
2806                         fixTop = targetFixed ? body.scrollTop() : 0,
2807                         fixLeft = targetFixed ? body.scrollLeft() : 0,
2808                         endPosition = target.offset(),
2809                         animation = {
2810                                 top: endPosition.top - fixTop,
2811                                 left: endPosition.left - fixLeft,
2812                                 height: target.innerHeight(),
2813                                 width: target.innerWidth()
2814                         },
2815                         startPosition = element.offset(),
2816                         transfer = $( "<div class='ui-effects-transfer'></div>" )
2817                                 .appendTo( "body" )
2818                                 .addClass( options.className )
2819                                 .css( {
2820                                         top: startPosition.top - fixTop,
2821                                         left: startPosition.left - fixLeft,
2822                                         height: element.innerHeight(),
2823                                         width: element.innerWidth(),
2824                                         position: targetFixed ? "fixed" : "absolute"
2825                                 } )
2826                                 .animate( animation, options.duration, options.easing, function() {
2827                                         transfer.remove();
2828                                         if ( $.isFunction( done ) ) {
2829                                                 done();
2830                                         }
2831                                 } );
2832         }
2833 } );
2834 
2835 function parseClip( str, element ) {
2836                 var outerWidth = element.outerWidth(),
2837                         outerHeight = element.outerHeight(),
2838                         clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
2839                         values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2840 
2841                 return {
2842                         top: parseFloat( values[ 1 ] ) || 0,
2843                         right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2844                         bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2845                         left: parseFloat( values[ 4 ] ) || 0
2846                 };
2847 }
2848 
2849 $.fx.step.clip = function( fx ) {
2850         if ( !fx.clipInit ) {
2851                 fx.start = $( fx.elem ).cssClip();
2852                 if ( typeof fx.end === "string" ) {
2853                         fx.end = parseClip( fx.end, fx.elem );
2854                 }
2855                 fx.clipInit = true;
2856         }
2857 
2858         $( fx.elem ).cssClip( {
2859                 top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2860                 right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2861                 bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2862                 left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2863         } );
2864 };
2865 
2866 } )();
2867 
2868 /******************************************************************************/
2869 /*********************************** EASING ***********************************/
2870 /******************************************************************************/
2871 
2872 ( function() {
2873 
2874 // Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2875 
2876 var baseEasings = {};
2877 
2878 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2879         baseEasings[ name ] = function( p ) {
2880                 return Math.pow( p, i + 2 );
2881         };
2882 } );
2883 
2884 $.extend( baseEasings, {
2885         Sine: function( p ) {
2886                 return 1 - Math.cos( p * Math.PI / 2 );
2887         },
2888         Circ: function( p ) {
2889                 return 1 - Math.sqrt( 1 - p * p );
2890         },
2891         Elastic: function( p ) {
2892                 return p === 0 || p === 1 ? p :
2893                         -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2894         },
2895         Back: function( p ) {
2896                 return p * p * ( 3 * p - 2 );
2897         },
2898         Bounce: function( p ) {
2899                 var pow2,
2900                         bounce = 4;
2901 
2902                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2903                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2904         }
2905 } );
2906 
2907 $.each( baseEasings, function( name, easeIn ) {
2908         $.easing[ "easeIn" + name ] = easeIn;
2909         $.easing[ "easeOut" + name ] = function( p ) {
2910                 return 1 - easeIn( 1 - p );
2911         };
2912         $.easing[ "easeInOut" + name ] = function( p ) {
2913                 return p < 0.5 ?
2914                         easeIn( p * 2 ) / 2 :
2915                         1 - easeIn( p * -2 + 2 ) / 2;
2916         };
2917 } );
2918 
2919 } )();
2920 
2921 var effect = $.effects;
2922 
2923 
2924 /*!
2925  * jQuery UI Effects Blind 1.12.1
2926  * http://jqueryui.com
2927  *
2928  * Copyright jQuery Foundation and other contributors
2929  * Released under the MIT license.
2930  * http://jquery.org/license
2931  */
2932 
2933 //>>label: Blind Effect
2934 //>>group: Effects
2935 //>>description: Blinds the element.
2936 //>>docs: http://api.jqueryui.com/blind-effect/
2937 //>>demos: http://jqueryui.com/effect/
2938 
2939 
2940 
2941 var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2942         var map = {
2943                         up: [ "bottom", "top" ],
2944                         vertical: [ "bottom", "top" ],
2945                         down: [ "top", "bottom" ],
2946                         left: [ "right", "left" ],
2947                         horizontal: [ "right", "left" ],
2948                         right: [ "left", "right" ]
2949                 },
2950                 element = $( this ),
2951                 direction = options.direction || "up",
2952                 start = element.cssClip(),
2953                 animate = { clip: $.extend( {}, start ) },
2954                 placeholder = $.effects.createPlaceholder( element );
2955 
2956         animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2957 
2958         if ( options.mode === "show" ) {
2959                 element.cssClip( animate.clip );
2960                 if ( placeholder ) {
2961                         placeholder.css( $.effects.clipToBox( animate ) );
2962                 }
2963 
2964                 animate.clip = start;
2965         }
2966 
2967         if ( placeholder ) {
2968                 placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2969         }
2970 
2971         element.animate( animate, {
2972                 queue: false,
2973                 duration: options.duration,
2974                 easing: options.easing,
2975                 complete: done
2976         } );
2977 } );
2978 
2979 
2980 /*!
2981  * jQuery UI Effects Bounce 1.12.1
2982  * http://jqueryui.com
2983  *
2984  * Copyright jQuery Foundation and other contributors
2985  * Released under the MIT license.
2986  * http://jquery.org/license
2987  */
2988 
2989 //>>label: Bounce Effect
2990 //>>group: Effects
2991 //>>description: Bounces an element horizontally or vertically n times.
2992 //>>docs: http://api.jqueryui.com/bounce-effect/
2993 //>>demos: http://jqueryui.com/effect/
2994 
2995 
2996 
2997 var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2998         var upAnim, downAnim, refValue,
2999                 element = $( this ),
3000 
3001                 // Defaults:
3002                 mode = options.mode,
3003                 hide = mode === "hide",
3004                 show = mode === "show",
3005                 direction = options.direction || "up",
3006                 distance = options.distance,
3007                 times = options.times || 5,
3008 
3009                 // Number of internal animations
3010                 anims = times * 2 + ( show || hide ? 1 : 0 ),
3011                 speed = options.duration / anims,
3012                 easing = options.easing,
3013 
3014                 // Utility:
3015                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3016                 motion = ( direction === "up" || direction === "left" ),
3017                 i = 0,
3018 
3019                 queuelen = element.queue().length;
3020 
3021         $.effects.createPlaceholder( element );
3022 
3023         refValue = element.css( ref );
3024 
3025         // Default distance for the BIGGEST bounce is the outer Distance / 3
3026         if ( !distance ) {
3027                 distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3028         }
3029 
3030         if ( show ) {
3031                 downAnim = { opacity: 1 };
3032                 downAnim[ ref ] = refValue;
3033 
3034                 // If we are showing, force opacity 0 and set the initial position
3035                 // then do the "first" animation
3036                 element
3037                         .css( "opacity", 0 )
3038                         .css( ref, motion ? -distance * 2 : distance * 2 )
3039                         .animate( downAnim, speed, easing );
3040         }
3041 
3042         // Start at the smallest distance if we are hiding
3043         if ( hide ) {
3044                 distance = distance / Math.pow( 2, times - 1 );
3045         }
3046 
3047         downAnim = {};
3048         downAnim[ ref ] = refValue;
3049 
3050         // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3051         for ( ; i < times; i++ ) {
3052                 upAnim = {};
3053                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3054 
3055                 element
3056                         .animate( upAnim, speed, easing )
3057                         .animate( downAnim, speed, easing );
3058 
3059                 distance = hide ? distance * 2 : distance / 2;
3060         }
3061 
3062         // Last Bounce when Hiding
3063         if ( hide ) {
3064                 upAnim = { opacity: 0 };
3065                 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3066 
3067                 element.animate( upAnim, speed, easing );
3068         }
3069 
3070         element.queue( done );
3071 
3072         $.effects.unshift( element, queuelen, anims + 1 );
3073 } );
3074 
3075 
3076 /*!
3077  * jQuery UI Effects Clip 1.12.1
3078  * http://jqueryui.com
3079  *
3080  * Copyright jQuery Foundation and other contributors
3081  * Released under the MIT license.
3082  * http://jquery.org/license
3083  */
3084 
3085 //>>label: Clip Effect
3086 //>>group: Effects
3087 //>>description: Clips the element on and off like an old TV.
3088 //>>docs: http://api.jqueryui.com/clip-effect/
3089 //>>demos: http://jqueryui.com/effect/
3090 
3091 
3092 
3093 var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3094         var start,
3095                 animate = {},
3096                 element = $( this ),
3097                 direction = options.direction || "vertical",
3098                 both = direction === "both",
3099                 horizontal = both || direction === "horizontal",
3100                 vertical = both || direction === "vertical";
3101 
3102         start = element.cssClip();
3103         animate.clip = {
3104                 top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3105                 right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3106                 bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3107                 left: horizontal ? ( start.right - start.left ) / 2 : start.left
3108         };
3109 
3110         $.effects.createPlaceholder( element );
3111 
3112         if ( options.mode === "show" ) {
3113                 element.cssClip( animate.clip );
3114                 animate.clip = start;
3115         }
3116 
3117         element.animate( animate, {
3118                 queue: false,
3119                 duration: options.duration,
3120                 easing: options.easing,
3121                 complete: done
3122         } );
3123 
3124 } );
3125 
3126 
3127 /*!
3128  * jQuery UI Effects Drop 1.12.1
3129  * http://jqueryui.com
3130  *
3131  * Copyright jQuery Foundation and other contributors
3132  * Released under the MIT license.
3133  * http://jquery.org/license
3134  */
3135 
3136 //>>label: Drop Effect
3137 //>>group: Effects
3138 //>>description: Moves an element in one direction and hides it at the same time.
3139 //>>docs: http://api.jqueryui.com/drop-effect/
3140 //>>demos: http://jqueryui.com/effect/
3141 
3142 
3143 
3144 var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3145 
3146         var distance,
3147                 element = $( this ),
3148                 mode = options.mode,
3149                 show = mode === "show",
3150                 direction = options.direction || "left",
3151                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3152                 motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3153                 oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3154                 animation = {
3155                         opacity: 0
3156                 };
3157 
3158         $.effects.createPlaceholder( element );
3159 
3160         distance = options.distance ||
3161                 element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3162 
3163         animation[ ref ] = motion + distance;
3164 
3165         if ( show ) {
3166                 element.css( animation );
3167 
3168                 animation[ ref ] = oppositeMotion + distance;
3169                 animation.opacity = 1;
3170         }
3171 
3172         // Animate
3173         element.animate( animation, {
3174                 queue: false,
3175                 duration: options.duration,
3176                 easing: options.easing,
3177                 complete: done
3178         } );
3179 } );
3180 
3181 
3182 /*!
3183  * jQuery UI Effects Explode 1.12.1
3184  * http://jqueryui.com
3185  *
3186  * Copyright jQuery Foundation and other contributors
3187  * Released under the MIT license.
3188  * http://jquery.org/license
3189  */
3190 
3191 //>>label: Explode Effect
3192 //>>group: Effects
3193 // jscs:disable maximumLineLength
3194 //>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3195 // jscs:enable maximumLineLength
3196 //>>docs: http://api.jqueryui.com/explode-effect/
3197 //>>demos: http://jqueryui.com/effect/
3198 
3199 
3200 
3201 var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3202 
3203         var i, j, left, top, mx, my,
3204                 rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3205                 cells = rows,
3206                 element = $( this ),
3207                 mode = options.mode,
3208                 show = mode === "show",
3209 
3210                 // Show and then visibility:hidden the element before calculating offset
3211                 offset = element.show().css( "visibility", "hidden" ).offset(),
3212 
3213                 // Width and height of a piece
3214                 width = Math.ceil( element.outerWidth() / cells ),
3215                 height = Math.ceil( element.outerHeight() / rows ),
3216                 pieces = [];
3217 
3218         // Children animate complete:
3219         function childComplete() {
3220                 pieces.push( this );
3221                 if ( pieces.length === rows * cells ) {
3222                         animComplete();
3223                 }
3224         }
3225 
3226         // Clone the element for each row and cell.
3227         for ( i = 0; i < rows; i++ ) { // ===>
3228                 top = offset.top + i * height;
3229                 my = i - ( rows - 1 ) / 2;
3230 
3231                 for ( j = 0; j < cells; j++ ) { // |||
3232                         left = offset.left + j * width;
3233                         mx = j - ( cells - 1 ) / 2;
3234 
3235                         // Create a clone of the now hidden main element that will be absolute positioned
3236                         // within a wrapper div off the -left and -top equal to size of our pieces
3237                         element
3238                                 .clone()
3239                                 .appendTo( "body" )
3240                                 .wrap( "<div></div>" )
3241                                 .css( {
3242                                         position: "absolute",
3243                                         visibility: "visible",
3244                                         left: -j * width,
3245                                         top: -i * height
3246                                 } )
3247 
3248                                 // Select the wrapper - make it overflow: hidden and absolute positioned based on
3249                                 // where the original was located +left and +top equal to the size of pieces
3250                                 .parent()
3251                                         .addClass( "ui-effects-explode" )
3252                                         .css( {
3253                                                 position: "absolute",
3254                                                 overflow: "hidden",
3255                                                 width: width,
3256                                                 height: height,
3257                                                 left: left + ( show ? mx * width : 0 ),
3258                                                 top: top + ( show ? my * height : 0 ),
3259                                                 opacity: show ? 0 : 1
3260                                         } )
3261                                         .animate( {
3262                                                 left: left + ( show ? 0 : mx * width ),
3263                                                 top: top + ( show ? 0 : my * height ),
3264                                                 opacity: show ? 1 : 0
3265                                         }, options.duration || 500, options.easing, childComplete );
3266                 }
3267         }
3268 
3269         function animComplete() {
3270                 element.css( {
3271                         visibility: "visible"
3272                 } );
3273                 $( pieces ).remove();
3274                 done();
3275         }
3276 } );
3277 
3278 
3279 /*!
3280  * jQuery UI Effects Fade 1.12.1
3281  * http://jqueryui.com
3282  *
3283  * Copyright jQuery Foundation and other contributors
3284  * Released under the MIT license.
3285  * http://jquery.org/license
3286  */
3287 
3288 //>>label: Fade Effect
3289 //>>group: Effects
3290 //>>description: Fades the element.
3291 //>>docs: http://api.jqueryui.com/fade-effect/
3292 //>>demos: http://jqueryui.com/effect/
3293 
3294 
3295 
3296 var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3297         var show = options.mode === "show";
3298 
3299         $( this )
3300                 .css( "opacity", show ? 0 : 1 )
3301                 .animate( {
3302                         opacity: show ? 1 : 0
3303                 }, {
3304                         queue: false,
3305                         duration: options.duration,
3306                         easing: options.easing,
3307                         complete: done
3308                 } );
3309 } );
3310 
3311 
3312 /*!
3313  * jQuery UI Effects Fold 1.12.1
3314  * http://jqueryui.com
3315  *
3316  * Copyright jQuery Foundation and other contributors
3317  * Released under the MIT license.
3318  * http://jquery.org/license
3319  */
3320 
3321 //>>label: Fold Effect
3322 //>>group: Effects
3323 //>>description: Folds an element first horizontally and then vertically.
3324 //>>docs: http://api.jqueryui.com/fold-effect/
3325 //>>demos: http://jqueryui.com/effect/
3326 
3327 
3328 
3329 var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3330 
3331         // Create element
3332         var element = $( this ),
3333                 mode = options.mode,
3334                 show = mode === "show",
3335                 hide = mode === "hide",
3336                 size = options.size || 15,
3337                 percent = /([0-9]+)%/.exec( size ),
3338                 horizFirst = !!options.horizFirst,
3339                 ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3340                 duration = options.duration / 2,
3341 
3342                 placeholder = $.effects.createPlaceholder( element ),
3343 
3344                 start = element.cssClip(),
3345                 animation1 = { clip: $.extend( {}, start ) },
3346                 animation2 = { clip: $.extend( {}, start ) },
3347 
3348                 distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3349 
3350                 queuelen = element.queue().length;
3351 
3352         if ( percent ) {
3353                 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3354         }
3355         animation1.clip[ ref[ 0 ] ] = size;
3356         animation2.clip[ ref[ 0 ] ] = size;
3357         animation2.clip[ ref[ 1 ] ] = 0;
3358 
3359         if ( show ) {
3360                 element.cssClip( animation2.clip );
3361                 if ( placeholder ) {
3362                         placeholder.css( $.effects.clipToBox( animation2 ) );
3363                 }
3364 
3365                 animation2.clip = start;
3366         }
3367 
3368         // Animate
3369         element
3370                 .queue( function( next ) {
3371                         if ( placeholder ) {
3372                                 placeholder
3373                                         .animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3374                                         .animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3375                         }
3376 
3377                         next();
3378                 } )
3379                 .animate( animation1, duration, options.easing )
3380                 .animate( animation2, duration, options.easing )
3381                 .queue( done );
3382 
3383         $.effects.unshift( element, queuelen, 4 );
3384 } );
3385 
3386 
3387 /*!
3388  * jQuery UI Effects Highlight 1.12.1
3389  * http://jqueryui.com
3390  *
3391  * Copyright jQuery Foundation and other contributors
3392  * Released under the MIT license.
3393  * http://jquery.org/license
3394  */
3395 
3396 //>>label: Highlight Effect
3397 //>>group: Effects
3398 //>>description: Highlights the background of an element in a defined color for a custom duration.
3399 //>>docs: http://api.jqueryui.com/highlight-effect/
3400 //>>demos: http://jqueryui.com/effect/
3401 
3402 
3403 
3404 var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3405         var element = $( this ),
3406                 animation = {
3407                         backgroundColor: element.css( "backgroundColor" )
3408                 };
3409 
3410         if ( options.mode === "hide" ) {
3411                 animation.opacity = 0;
3412         }
3413 
3414         $.effects.saveStyle( element );
3415 
3416         element
3417                 .css( {
3418                         backgroundImage: "none",
3419                         backgroundColor: options.color || "#ffff99"
3420                 } )
3421                 .animate( animation, {
3422                         queue: false,
3423                         duration: options.duration,
3424                         easing: options.easing,
3425                         complete: done
3426                 } );
3427 } );
3428 
3429 
3430 /*!
3431  * jQuery UI Effects Size 1.12.1
3432  * http://jqueryui.com
3433  *
3434  * Copyright jQuery Foundation and other contributors
3435  * Released under the MIT license.
3436  * http://jquery.org/license
3437  */
3438 
3439 //>>label: Size Effect
3440 //>>group: Effects
3441 //>>description: Resize an element to a specified width and height.
3442 //>>docs: http://api.jqueryui.com/size-effect/
3443 //>>demos: http://jqueryui.com/effect/
3444 
3445 
3446 
3447 var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3448 
3449         // Create element
3450         var baseline, factor, temp,
3451                 element = $( this ),
3452 
3453                 // Copy for children
3454                 cProps = [ "fontSize" ],
3455                 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3456                 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3457 
3458                 // Set options
3459                 mode = options.mode,
3460                 restore = mode !== "effect",
3461                 scale = options.scale || "both",
3462                 origin = options.origin || [ "middle", "center" ],
3463                 position = element.css( "position" ),
3464                 pos = element.position(),
3465                 original = $.effects.scaledDimensions( element ),
3466                 from = options.from || original,
3467                 to = options.to || $.effects.scaledDimensions( element, 0 );
3468 
3469         $.effects.createPlaceholder( element );
3470 
3471         if ( mode === "show" ) {
3472                 temp = from;
3473                 from = to;
3474                 to = temp;
3475         }
3476 
3477         // Set scaling factor
3478         factor = {
3479                 from: {
3480                         y: from.height / original.height,
3481                         x: from.width / original.width
3482                 },
3483                 to: {
3484                         y: to.height / original.height,
3485                         x: to.width / original.width
3486                 }
3487         };
3488 
3489         // Scale the css box
3490         if ( scale === "box" || scale === "both" ) {
3491 
3492                 // Vertical props scaling
3493                 if ( factor.from.y !== factor.to.y ) {
3494                         from = $.effects.setTransition( element, vProps, factor.from.y, from );
3495                         to = $.effects.setTransition( element, vProps, factor.to.y, to );
3496                 }
3497 
3498                 // Horizontal props scaling
3499                 if ( factor.from.x !== factor.to.x ) {
3500                         from = $.effects.setTransition( element, hProps, factor.from.x, from );
3501                         to = $.effects.setTransition( element, hProps, factor.to.x, to );
3502                 }
3503         }
3504 
3505         // Scale the content
3506         if ( scale === "content" || scale === "both" ) {
3507 
3508                 // Vertical props scaling
3509                 if ( factor.from.y !== factor.to.y ) {
3510                         from = $.effects.setTransition( element, cProps, factor.from.y, from );
3511                         to = $.effects.setTransition( element, cProps, factor.to.y, to );
3512                 }
3513         }
3514 
3515         // Adjust the position properties based on the provided origin points
3516         if ( origin ) {
3517                 baseline = $.effects.getBaseline( origin, original );
3518                 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3519                 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3520                 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3521                 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3522         }
3523         element.css( from );
3524 
3525         // Animate the children if desired
3526         if ( scale === "content" || scale === "both" ) {
3527 
3528                 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3529                 hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3530 
3531                 // Only animate children with width attributes specified
3532                 // TODO: is this right? should we include anything with css width specified as well
3533                 element.find( "*[width]" ).each( function() {
3534                         var child = $( this ),
3535                                 childOriginal = $.effects.scaledDimensions( child ),
3536                                 childFrom = {
3537                                         height: childOriginal.height * factor.from.y,
3538                                         width: childOriginal.width * factor.from.x,
3539                                         outerHeight: childOriginal.outerHeight * factor.from.y,
3540                                         outerWidth: childOriginal.outerWidth * factor.from.x
3541                                 },
3542                                 childTo = {
3543                                         height: childOriginal.height * factor.to.y,
3544                                         width: childOriginal.width * factor.to.x,
3545                                         outerHeight: childOriginal.height * factor.to.y,
3546                                         outerWidth: childOriginal.width * factor.to.x
3547                                 };
3548 
3549                         // Vertical props scaling
3550                         if ( factor.from.y !== factor.to.y ) {
3551                                 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3552                                 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3553                         }
3554 
3555                         // Horizontal props scaling
3556                         if ( factor.from.x !== factor.to.x ) {
3557                                 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3558                                 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3559                         }
3560 
3561                         if ( restore ) {
3562                                 $.effects.saveStyle( child );
3563                         }
3564 
3565                         // Animate children
3566                         child.css( childFrom );
3567                         child.animate( childTo, options.duration, options.easing, function() {
3568 
3569                                 // Restore children
3570                                 if ( restore ) {
3571                                         $.effects.restoreStyle( child );
3572                                 }
3573                         } );
3574                 } );
3575         }
3576 
3577         // Animate
3578         element.animate( to, {
3579                 queue: false,
3580                 duration: options.duration,
3581                 easing: options.easing,
3582                 complete: function() {
3583 
3584                         var offset = element.offset();
3585 
3586                         if ( to.opacity === 0 ) {
3587                                 element.css( "opacity", from.opacity );
3588                         }
3589 
3590                         if ( !restore ) {
3591                                 element
3592                                         .css( "position", position === "static" ? "relative" : position )
3593                                         .offset( offset );
3594 
3595                                 // Need to save style here so that automatic style restoration
3596                                 // doesn't restore to the original styles from before the animation.
3597                                 $.effects.saveStyle( element );
3598                         }
3599 
3600                         done();
3601                 }
3602         } );
3603 
3604 } );
3605 
3606 
3607 /*!
3608  * jQuery UI Effects Scale 1.12.1
3609  * http://jqueryui.com
3610  *
3611  * Copyright jQuery Foundation and other contributors
3612  * Released under the MIT license.
3613  * http://jquery.org/license
3614  */
3615 
3616 //>>label: Scale Effect
3617 //>>group: Effects
3618 //>>description: Grows or shrinks an element and its content.
3619 //>>docs: http://api.jqueryui.com/scale-effect/
3620 //>>demos: http://jqueryui.com/effect/
3621 
3622 
3623 
3624 var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3625 
3626         // Create element
3627         var el = $( this ),
3628                 mode = options.mode,
3629                 percent = parseInt( options.percent, 10 ) ||
3630                         ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3631 
3632                 newOptions = $.extend( true, {
3633                         from: $.effects.scaledDimensions( el ),
3634                         to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3635                         origin: options.origin || [ "middle", "center" ]
3636                 }, options );
3637 
3638         // Fade option to support puff
3639         if ( options.fade ) {
3640                 newOptions.from.opacity = 1;
3641                 newOptions.to.opacity = 0;
3642         }
3643 
3644         $.effects.effect.size.call( this, newOptions, done );
3645 } );
3646 
3647 
3648 /*!
3649  * jQuery UI Effects Puff 1.12.1
3650  * http://jqueryui.com
3651  *
3652  * Copyright jQuery Foundation and other contributors
3653  * Released under the MIT license.
3654  * http://jquery.org/license
3655  */
3656 
3657 //>>label: Puff Effect
3658 //>>group: Effects
3659 //>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3660 //>>docs: http://api.jqueryui.com/puff-effect/
3661 //>>demos: http://jqueryui.com/effect/
3662 
3663 
3664 
3665 var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3666         var newOptions = $.extend( true, {}, options, {
3667                 fade: true,
3668                 percent: parseInt( options.percent, 10 ) || 150
3669         } );
3670 
3671         $.effects.effect.scale.call( this, newOptions, done );
3672 } );
3673 
3674 
3675 /*!
3676  * jQuery UI Effects Pulsate 1.12.1
3677  * http://jqueryui.com
3678  *
3679  * Copyright jQuery Foundation and other contributors
3680  * Released under the MIT license.
3681  * http://jquery.org/license
3682  */
3683 
3684 //>>label: Pulsate Effect
3685 //>>group: Effects
3686 //>>description: Pulsates an element n times by changing the opacity to zero and back.
3687 //>>docs: http://api.jqueryui.com/pulsate-effect/
3688 //>>demos: http://jqueryui.com/effect/
3689 
3690 
3691 
3692 var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3693         var element = $( this ),
3694                 mode = options.mode,
3695                 show = mode === "show",
3696                 hide = mode === "hide",
3697                 showhide = show || hide,
3698 
3699                 // Showing or hiding leaves off the "last" animation
3700                 anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3701                 duration = options.duration / anims,
3702                 animateTo = 0,
3703                 i = 1,
3704                 queuelen = element.queue().length;
3705 
3706         if ( show || !element.is( ":visible" ) ) {
3707                 element.css( "opacity", 0 ).show();
3708                 animateTo = 1;
3709         }
3710 
3711         // Anims - 1 opacity "toggles"
3712         for ( ; i < anims; i++ ) {
3713                 element.animate( { opacity: animateTo }, duration, options.easing );
3714                 animateTo = 1 - animateTo;
3715         }
3716 
3717         element.animate( { opacity: animateTo }, duration, options.easing );
3718 
3719         element.queue( done );
3720 
3721         $.effects.unshift( element, queuelen, anims + 1 );
3722 } );
3723 
3724 
3725 /*!
3726  * jQuery UI Effects Shake 1.12.1
3727  * http://jqueryui.com
3728  *
3729  * Copyright jQuery Foundation and other contributors
3730  * Released under the MIT license.
3731  * http://jquery.org/license
3732  */
3733 
3734 //>>label: Shake Effect
3735 //>>group: Effects
3736 //>>description: Shakes an element horizontally or vertically n times.
3737 //>>docs: http://api.jqueryui.com/shake-effect/
3738 //>>demos: http://jqueryui.com/effect/
3739 
3740 
3741 
3742 var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3743 
3744         var i = 1,
3745                 element = $( this ),
3746                 direction = options.direction || "left",
3747                 distance = options.distance || 20,
3748                 times = options.times || 3,
3749                 anims = times * 2 + 1,
3750                 speed = Math.round( options.duration / anims ),
3751                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3752                 positiveMotion = ( direction === "up" || direction === "left" ),
3753                 animation = {},
3754                 animation1 = {},
3755                 animation2 = {},
3756 
3757                 queuelen = element.queue().length;
3758 
3759         $.effects.createPlaceholder( element );
3760 
3761         // Animation
3762         animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3763         animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3764         animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3765 
3766         // Animate
3767         element.animate( animation, speed, options.easing );
3768 
3769         // Shakes
3770         for ( ; i < times; i++ ) {
3771                 element
3772                         .animate( animation1, speed, options.easing )
3773                         .animate( animation2, speed, options.easing );
3774         }
3775 
3776         element
3777                 .animate( animation1, speed, options.easing )
3778                 .animate( animation, speed / 2, options.easing )
3779                 .queue( done );
3780 
3781         $.effects.unshift( element, queuelen, anims + 1 );
3782 } );
3783 
3784 
3785 /*!
3786  * jQuery UI Effects Slide 1.12.1
3787  * http://jqueryui.com
3788  *
3789  * Copyright jQuery Foundation and other contributors
3790  * Released under the MIT license.
3791  * http://jquery.org/license
3792  */
3793 
3794 //>>label: Slide Effect
3795 //>>group: Effects
3796 //>>description: Slides an element in and out of the viewport.
3797 //>>docs: http://api.jqueryui.com/slide-effect/
3798 //>>demos: http://jqueryui.com/effect/
3799 
3800 
3801 
3802 var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3803         var startClip, startRef,
3804                 element = $( this ),
3805                 map = {
3806                         up: [ "bottom", "top" ],
3807                         down: [ "top", "bottom" ],
3808                         left: [ "right", "left" ],
3809                         right: [ "left", "right" ]
3810                 },
3811                 mode = options.mode,
3812                 direction = options.direction || "left",
3813                 ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3814                 positiveMotion = ( direction === "up" || direction === "left" ),
3815                 distance = options.distance ||
3816                         element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3817                 animation = {};
3818 
3819         $.effects.createPlaceholder( element );
3820 
3821         startClip = element.cssClip();
3822         startRef = element.position()[ ref ];
3823 
3824         // Define hide animation
3825         animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3826         animation.clip = element.cssClip();
3827         animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3828 
3829         // Reverse the animation if we're showing
3830         if ( mode === "show" ) {
3831                 element.cssClip( animation.clip );
3832                 element.css( ref, animation[ ref ] );
3833                 animation.clip = startClip;
3834                 animation[ ref ] = startRef;
3835         }
3836 
3837         // Actually animate
3838         element.animate( animation, {
3839                 queue: false,
3840                 duration: options.duration,
3841                 easing: options.easing,
3842                 complete: done
3843         } );
3844 } );
3845 
3846 
3847 /*!
3848  * jQuery UI Effects Transfer 1.12.1
3849  * http://jqueryui.com
3850  *
3851  * Copyright jQuery Foundation and other contributors
3852  * Released under the MIT license.
3853  * http://jquery.org/license
3854  */
3855 
3856 //>>label: Transfer Effect
3857 //>>group: Effects
3858 //>>description: Displays a transfer effect from one element to another.
3859 //>>docs: http://api.jqueryui.com/transfer-effect/
3860 //>>demos: http://jqueryui.com/effect/
3861 
3862 
3863 
3864 var effect;
3865 if ( $.uiBackCompat !== false ) {
3866         effect = $.effects.define( "transfer", function( options, done ) {
3867                 $( this ).transfer( options, done );
3868         } );
3869 }
3870 var effectsEffectTransfer = effect;
3871 
3872 
3873 /*!
3874  * jQuery UI Focusable 1.12.1
3875  * http://jqueryui.com
3876  *
3877  * Copyright jQuery Foundation and other contributors
3878  * Released under the MIT license.
3879  * http://jquery.org/license
3880  */
3881 
3882 //>>label: :focusable Selector
3883 //>>group: Core
3884 //>>description: Selects elements which can be focused.
3885 //>>docs: http://api.jqueryui.com/focusable-selector/
3886 
3887 
3888 
3889 // Selectors
3890 $.ui.focusable = function( element, hasTabindex ) {
3891         var map, mapName, img, focusableIfVisible, fieldset,
3892                 nodeName = element.nodeName.toLowerCase();
3893 
3894         if ( "area" === nodeName ) {
3895                 map = element.parentNode;
3896                 mapName = map.name;
3897                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3898                         return false;
3899                 }
3900                 img = $( "img[usemap='#" + mapName + "']" );
3901                 return img.length > 0 && img.is( ":visible" );
3902         }
3903 
3904         if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3905                 focusableIfVisible = !element.disabled;
3906 
3907                 if ( focusableIfVisible ) {
3908 
3909                         // Form controls within a disabled fieldset are disabled.
3910                         // However, controls within the fieldset's legend do not get disabled.
3911                         // Since controls generally aren't placed inside legends, we skip
3912                         // this portion of the check.
3913                         fieldset = $( element ).closest( "fieldset" )[ 0 ];
3914                         if ( fieldset ) {
3915                                 focusableIfVisible = !fieldset.disabled;
3916                         }
3917                 }
3918         } else if ( "a" === nodeName ) {
3919                 focusableIfVisible = element.href || hasTabindex;
3920         } else {
3921                 focusableIfVisible = hasTabindex;
3922         }
3923 
3924         return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3925 };
3926 
3927 // Support: IE 8 only
3928 // IE 8 doesn't resolve inherit to visible/hidden for computed values
3929 function visible( element ) {
3930         var visibility = element.css( "visibility" );
3931         while ( visibility === "inherit" ) {
3932                 element = element.parent();
3933                 visibility = element.css( "visibility" );
3934         }
3935         return visibility !== "hidden";
3936 }
3937 
3938 $.extend( $.expr[ ":" ], {
3939         focusable: function( element ) {
3940                 return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3941         }
3942 } );
3943 
3944 var focusable = $.ui.focusable;
3945 
3946 
3947 
3948 
3949 // Support: IE8 Only
3950 // IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3951 // with a string, so we need to find the proper form.
3952 var form = $.fn.form = function() {
3953         return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3954 };
3955 
3956 
3957 /*!
3958  * jQuery UI Form Reset Mixin 1.12.1
3959  * http://jqueryui.com
3960  *
3961  * Copyright jQuery Foundation and other contributors
3962  * Released under the MIT license.
3963  * http://jquery.org/license
3964  */
3965 
3966 //>>label: Form Reset Mixin
3967 //>>group: Core
3968 //>>description: Refresh input widgets when their form is reset
3969 //>>docs: http://api.jqueryui.com/form-reset-mixin/
3970 
3971 
3972 
3973 var formResetMixin = $.ui.formResetMixin = {
3974         _formResetHandler: function() {
3975                 var form = $( this );
3976 
3977                 // Wait for the form reset to actually happen before refreshing
3978                 setTimeout( function() {
3979                         var instances = form.data( "ui-form-reset-instances" );
3980                         $.each( instances, function() {
3981                                 this.refresh();
3982                         } );
3983                 } );
3984         },
3985 
3986         _bindFormResetHandler: function() {
3987                 this.form = this.element.form();
3988                 if ( !this.form.length ) {
3989                         return;
3990                 }
3991 
3992                 var instances = this.form.data( "ui-form-reset-instances" ) || [];
3993                 if ( !instances.length ) {
3994 
3995                         // We don't use _on() here because we use a single event handler per form
3996                         this.form.on( "reset.ui-form-reset", this._formResetHandler );
3997                 }
3998                 instances.push( this );
3999                 this.form.data( "ui-form-reset-instances", instances );
4000         },
4001 
4002         _unbindFormResetHandler: function() {
4003                 if ( !this.form.length ) {
4004                         return;
4005                 }
4006 
4007                 var instances = this.form.data( "ui-form-reset-instances" );
4008                 instances.splice( $.inArray( this, instances ), 1 );
4009                 if ( instances.length ) {
4010                         this.form.data( "ui-form-reset-instances", instances );
4011                 } else {
4012                         this.form
4013                                 .removeData( "ui-form-reset-instances" )
4014                                 .off( "reset.ui-form-reset" );
4015                 }
4016         }
4017 };
4018 
4019 
4020 /*!
4021  * jQuery UI Support for jQuery core 1.7.x 1.12.1
4022  * http://jqueryui.com
4023  *
4024  * Copyright jQuery Foundation and other contributors
4025  * Released under the MIT license.
4026  * http://jquery.org/license
4027  *
4028  */
4029 
4030 //>>label: jQuery 1.7 Support
4031 //>>group: Core
4032 //>>description: Support version 1.7.x of jQuery core
4033 
4034 
4035 
4036 // Support: jQuery 1.7 only
4037 // Not a great way to check versions, but since we only support 1.7+ and only
4038 // need to detect <1.8, this is a simple check that should suffice. Checking
4039 // for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4040 // and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4041 // 1.7 anymore). See #11197 for why we're not using feature detection.
4042 if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4043 
4044         // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4045         // Unlike jQuery Core 1.8+, these only support numeric values to set the
4046         // dimensions in pixels
4047         $.each( [ "Width", "Height" ], function( i, name ) {
4048                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4049                         type = name.toLowerCase(),
4050                         orig = {
4051                                 innerWidth: $.fn.innerWidth,
4052                                 innerHeight: $.fn.innerHeight,
4053                                 outerWidth: $.fn.outerWidth,
4054                                 outerHeight: $.fn.outerHeight
4055                         };
4056 
4057                 function reduce( elem, size, border, margin ) {
4058                         $.each( side, function() {
4059                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4060                                 if ( border ) {
4061                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4062                                 }
4063                                 if ( margin ) {
4064                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4065                                 }
4066                         } );
4067                         return size;
4068                 }
4069 
4070                 $.fn[ "inner" + name ] = function( size ) {
4071                         if ( size === undefined ) {
4072                                 return orig[ "inner" + name ].call( this );
4073                         }
4074 
4075                         return this.each( function() {
4076                                 $( this ).css( type, reduce( this, size ) + "px" );
4077                         } );
4078                 };
4079 
4080                 $.fn[ "outer" + name ] = function( size, margin ) {
4081                         if ( typeof size !== "number" ) {
4082                                 return orig[ "outer" + name ].call( this, size );
4083                         }
4084 
4085                         return this.each( function() {
4086                                 $( this ).css( type, reduce( this, size, true, margin ) + "px" );
4087                         } );
4088                 };
4089         } );
4090 
4091         $.fn.addBack = function( selector ) {
4092                 return this.add( selector == null ?
4093                         this.prevObject : this.prevObject.filter( selector )
4094                 );
4095         };
4096 }
4097 
4098 ;
4099 /*!
4100  * jQuery UI Keycode 1.12.1
4101  * http://jqueryui.com
4102  *
4103  * Copyright jQuery Foundation and other contributors
4104  * Released under the MIT license.
4105  * http://jquery.org/license
4106  */
4107 
4108 //>>label: Keycode
4109 //>>group: Core
4110 //>>description: Provide keycodes as keynames
4111 //>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4112 
4113 
4114 var keycode = $.ui.keyCode = {
4115         BACKSPACE: 8,
4116         COMMA: 188,
4117         DELETE: 46,
4118         DOWN: 40,
4119         END: 35,
4120         ENTER: 13,
4121         ESCAPE: 27,
4122         HOME: 36,
4123         LEFT: 37,
4124         PAGE_DOWN: 34,
4125         PAGE_UP: 33,
4126         PERIOD: 190,
4127         RIGHT: 39,
4128         SPACE: 32,
4129         TAB: 9,
4130         UP: 38
4131 };
4132 
4133 
4134 
4135 
4136 // Internal use only
4137 var escapeSelector = $.ui.escapeSelector = ( function() {
4138         var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4139         return function( selector ) {
4140                 return selector.replace( selectorEscape, "\\$1" );
4141         };
4142 } )();
4143 
4144 
4145 /*!
4146  * jQuery UI Labels 1.12.1
4147  * http://jqueryui.com
4148  *
4149  * Copyright jQuery Foundation and other contributors
4150  * Released under the MIT license.
4151  * http://jquery.org/license
4152  */
4153 
4154 //>>label: labels
4155 //>>group: Core
4156 //>>description: Find all the labels associated with a given input
4157 //>>docs: http://api.jqueryui.com/labels/
4158 
4159 
4160 
4161 var labels = $.fn.labels = function() {
4162         var ancestor, selector, id, labels, ancestors;
4163 
4164         // Check control.labels first
4165         if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4166                 return this.pushStack( this[ 0 ].labels );
4167         }
4168 
4169         // Support: IE <= 11, FF <= 37, Android <= 2.3 only
4170         // Above browsers do not support control.labels. Everything below is to support them
4171         // as well as document fragments. control.labels does not work on document fragments
4172         labels = this.eq( 0 ).parents( "label" );
4173 
4174         // Look for the label based on the id
4175         id = this.attr( "id" );
4176         if ( id ) {
4177 
4178                 // We don't search against the document in case the element
4179                 // is disconnected from the DOM
4180                 ancestor = this.eq( 0 ).parents().last();
4181 
4182                 // Get a full set of top level ancestors
4183                 ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4184 
4185                 // Create a selector for the label based on the id
4186                 selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4187 
4188                 labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4189 
4190         }
4191 
4192         // Return whatever we have found for labels
4193         return this.pushStack( labels );
4194 };
4195 
4196 
4197 /*!
4198  * jQuery UI Scroll Parent 1.12.1
4199  * http://jqueryui.com
4200  *
4201  * Copyright jQuery Foundation and other contributors
4202  * Released under the MIT license.
4203  * http://jquery.org/license
4204  */
4205 
4206 //>>label: scrollParent
4207 //>>group: Core
4208 //>>description: Get the closest ancestor element that is scrollable.
4209 //>>docs: http://api.jqueryui.com/scrollParent/
4210 
4211 
4212 
4213 var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4214         var position = this.css( "position" ),
4215                 excludeStaticParent = position === "absolute",
4216                 overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4217                 scrollParent = this.parents().filter( function() {
4218                         var parent = $( this );
4219                         if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4220                                 return false;
4221                         }
4222                         return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4223                                 parent.css( "overflow-x" ) );
4224                 } ).eq( 0 );
4225 
4226         return position === "fixed" || !scrollParent.length ?
4227                 $( this[ 0 ].ownerDocument || document ) :
4228                 scrollParent;
4229 };
4230 
4231 
4232 /*!
4233  * jQuery UI Tabbable 1.12.1
4234  * http://jqueryui.com
4235  *
4236  * Copyright jQuery Foundation and other contributors
4237  * Released under the MIT license.
4238  * http://jquery.org/license
4239  */
4240 
4241 //>>label: :tabbable Selector
4242 //>>group: Core
4243 //>>description: Selects elements which can be tabbed to.
4244 //>>docs: http://api.jqueryui.com/tabbable-selector/
4245 
4246 
4247 
4248 var tabbable = $.extend( $.expr[ ":" ], {
4249         tabbable: function( element ) {
4250                 var tabIndex = $.attr( element, "tabindex" ),
4251                         hasTabindex = tabIndex != null;
4252                 return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4253         }
4254 } );
4255 
4256 
4257 /*!
4258  * jQuery UI Unique ID 1.12.1
4259  * http://jqueryui.com
4260  *
4261  * Copyright jQuery Foundation and other contributors
4262  * Released under the MIT license.
4263  * http://jquery.org/license
4264  */
4265 
4266 //>>label: uniqueId
4267 //>>group: Core
4268 //>>description: Functions to generate and remove uniqueId's
4269 //>>docs: http://api.jqueryui.com/uniqueId/
4270 
4271 
4272 
4273 var uniqueId = $.fn.extend( {
4274         uniqueId: ( function() {
4275                 var uuid = 0;
4276 
4277                 return function() {
4278                         return this.each( function() {
4279                                 if ( !this.id ) {
4280                                         this.id = "ui-id-" + ( ++uuid );
4281                                 }
4282                         } );
4283                 };
4284         } )(),
4285 
4286         removeUniqueId: function() {
4287                 return this.each( function() {
4288                         if ( /^ui-id-\d+$/.test( this.id ) ) {
4289                                 $( this ).removeAttr( "id" );
4290                         }
4291                 } );
4292         }
4293 } );
4294 
4295 
4296 /*!
4297  * jQuery UI Accordion 1.12.1
4298  * http://jqueryui.com
4299  *
4300  * Copyright jQuery Foundation and other contributors
4301  * Released under the MIT license.
4302  * http://jquery.org/license
4303  */
4304 
4305 //>>label: Accordion
4306 //>>group: Widgets
4307 // jscs:disable maximumLineLength
4308 //>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4309 // jscs:enable maximumLineLength
4310 //>>docs: http://api.jqueryui.com/accordion/
4311 //>>demos: http://jqueryui.com/accordion/
4312 //>>css.structure: ../../themes/base/core.css
4313 //>>css.structure: ../../themes/base/accordion.css
4314 //>>css.theme: ../../themes/base/theme.css
4315 
4316 
4317 
4318 var widgetsAccordion = $.widget( "ui.accordion", {
4319         version: "1.12.1",
4320         options: {
4321                 active: 0,
4322                 animate: {},
4323                 classes: {
4324                         "ui-accordion-header": "ui-corner-top",
4325                         "ui-accordion-header-collapsed": "ui-corner-all",
4326                         "ui-accordion-content": "ui-corner-bottom"
4327                 },
4328                 collapsible: false,
4329                 event: "click",
4330                 header: "> li > :first-child, > :not(li):even",
4331                 heightStyle: "auto",
4332                 icons: {
4333                         activeHeader: "ui-icon-triangle-1-s",
4334                         header: "ui-icon-triangle-1-e"
4335                 },
4336 
4337                 // Callbacks
4338                 activate: null,
4339                 beforeActivate: null
4340         },
4341 
4342         hideProps: {
4343                 borderTopWidth: "hide",
4344                 borderBottomWidth: "hide",
4345                 paddingTop: "hide",
4346                 paddingBottom: "hide",
4347                 height: "hide"
4348         },
4349 
4350         showProps: {
4351                 borderTopWidth: "show",
4352                 borderBottomWidth: "show",
4353                 paddingTop: "show",
4354                 paddingBottom: "show",
4355                 height: "show"
4356         },
4357 
4358         _create: function() {
4359                 var options = this.options;
4360 
4361                 this.prevShow = this.prevHide = $();
4362                 this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4363                 this.element.attr( "role", "tablist" );
4364 
4365                 // Don't allow collapsible: false and active: false / null
4366                 if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4367                         options.active = 0;
4368                 }
4369 
4370                 this._processPanels();
4371 
4372                 // handle negative values
4373                 if ( options.active < 0 ) {
4374                         options.active += this.headers.length;
4375                 }
4376                 this._refresh();
4377         },
4378 
4379         _getCreateEventData: function() {
4380                 return {
4381                         header: this.active,
4382                         panel: !this.active.length ? $() : this.active.next()
4383                 };
4384         },
4385 
4386         _createIcons: function() {
4387                 var icon, children,
4388                         icons = this.options.icons;
4389 
4390                 if ( icons ) {
4391                         icon = $( "<span>" );
4392                         this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4393                         icon.prependTo( this.headers );
4394                         children = this.active.children( ".ui-accordion-header-icon" );
4395                         this._removeClass( children, icons.header )
4396                                 ._addClass( children, null, icons.activeHeader )
4397                                 ._addClass( this.headers, "ui-accordion-icons" );
4398                 }
4399         },
4400 
4401         _destroyIcons: function() {
4402                 this._removeClass( this.headers, "ui-accordion-icons" );
4403                 this.headers.children( ".ui-accordion-header-icon" ).remove();
4404         },
4405 
4406         _destroy: function() {
4407                 var contents;
4408 
4409                 // Clean up main element
4410                 this.element.removeAttr( "role" );
4411 
4412                 // Clean up headers
4413                 this.headers
4414                         .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4415                         .removeUniqueId();
4416 
4417                 this._destroyIcons();
4418 
4419                 // Clean up content panels
4420                 contents = this.headers.next()
4421                         .css( "display", "" )
4422                         .removeAttr( "role aria-hidden aria-labelledby" )
4423                         .removeUniqueId();
4424 
4425                 if ( this.options.heightStyle !== "content" ) {
4426                         contents.css( "height", "" );
4427                 }
4428         },
4429 
4430         _setOption: function( key, value ) {
4431                 if ( key === "active" ) {
4432 
4433                         // _activate() will handle invalid values and update this.options
4434                         this._activate( value );
4435                         return;
4436                 }
4437 
4438                 if ( key === "event" ) {
4439                         if ( this.options.event ) {
4440                                 this._off( this.headers, this.options.event );
4441                         }
4442                         this._setupEvents( value );
4443                 }
4444 
4445                 this._super( key, value );
4446 
4447                 // Setting collapsible: false while collapsed; open first panel
4448                 if ( key === "collapsible" && !value && this.options.active === false ) {
4449                         this._activate( 0 );
4450                 }
4451 
4452                 if ( key === "icons" ) {
4453                         this._destroyIcons();
4454                         if ( value ) {
4455                                 this._createIcons();
4456                         }
4457                 }
4458         },
4459 
4460         _setOptionDisabled: function( value ) {
4461                 this._super( value );
4462 
4463                 this.element.attr( "aria-disabled", value );
4464 
4465                 // Support: IE8 Only
4466                 // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4467                 // so we need to add the disabled class to the headers and panels
4468                 this._toggleClass( null, "ui-state-disabled", !!value );
4469                 this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4470                         !!value );
4471         },
4472 
4473         _keydown: function( event ) {
4474                 if ( event.altKey || event.ctrlKey ) {
4475                         return;
4476                 }
4477 
4478                 var keyCode = $.ui.keyCode,
4479                         length = this.headers.length,
4480                         currentIndex = this.headers.index( event.target ),
4481                         toFocus = false;
4482 
4483                 switch ( event.keyCode ) {
4484                 case keyCode.RIGHT:
4485                 case keyCode.DOWN:
4486                         toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4487                         break;
4488                 case keyCode.LEFT:
4489                 case keyCode.UP:
4490                         toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4491                         break;
4492                 case keyCode.SPACE:
4493                 case keyCode.ENTER:
4494                         this._eventHandler( event );
4495                         break;
4496                 case keyCode.HOME:
4497                         toFocus = this.headers[ 0 ];
4498                         break;
4499                 case keyCode.END:
4500                         toFocus = this.headers[ length - 1 ];
4501                         break;
4502                 }
4503 
4504                 if ( toFocus ) {
4505                         $( event.target ).attr( "tabIndex", -1 );
4506                         $( toFocus ).attr( "tabIndex", 0 );
4507                         $( toFocus ).trigger( "focus" );
4508                         event.preventDefault();
4509                 }
4510         },
4511 
4512         _panelKeyDown: function( event ) {
4513                 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4514                         $( event.currentTarget ).prev().trigger( "focus" );
4515                 }
4516         },
4517 
4518         refresh: function() {
4519                 var options = this.options;
4520                 this._processPanels();
4521 
4522                 // Was collapsed or no panel
4523                 if ( ( options.active === false && options.collapsible === true ) ||
4524                                 !this.headers.length ) {
4525                         options.active = false;
4526                         this.active = $();
4527 
4528                 // active false only when collapsible is true
4529                 } else if ( options.active === false ) {
4530                         this._activate( 0 );
4531 
4532                 // was active, but active panel is gone
4533                 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4534 
4535                         // all remaining panel are disabled
4536                         if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4537                                 options.active = false;
4538                                 this.active = $();
4539 
4540                         // activate previous panel
4541                         } else {
4542                                 this._activate( Math.max( 0, options.active - 1 ) );
4543                         }
4544 
4545                 // was active, active panel still exists
4546                 } else {
4547 
4548                         // make sure active index is correct
4549                         options.active = this.headers.index( this.active );
4550                 }
4551 
4552                 this._destroyIcons();
4553 
4554                 this._refresh();
4555         },
4556 
4557         _processPanels: function() {
4558                 var prevHeaders = this.headers,
4559                         prevPanels = this.panels;
4560 
4561                 this.headers = this.element.find( this.options.header );
4562                 this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4563                         "ui-state-default" );
4564 
4565                 this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4566                 this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4567 
4568                 // Avoid memory leaks (#10056)
4569                 if ( prevPanels ) {
4570                         this._off( prevHeaders.not( this.headers ) );
4571                         this._off( prevPanels.not( this.panels ) );
4572                 }
4573         },
4574 
4575         _refresh: function() {
4576                 var maxHeight,
4577                         options = this.options,
4578                         heightStyle = options.heightStyle,
4579                         parent = this.element.parent();
4580 
4581                 this.active = this._findActive( options.active );
4582                 this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4583                         ._removeClass( this.active, "ui-accordion-header-collapsed" );
4584                 this._addClass( this.active.next(), "ui-accordion-content-active" );
4585                 this.active.next().show();
4586 
4587                 this.headers
4588                         .attr( "role", "tab" )
4589                         .each( function() {
4590                                 var header = $( this ),
4591                                         headerId = header.uniqueId().attr( "id" ),
4592                                         panel = header.next(),
4593                                         panelId = panel.uniqueId().attr( "id" );
4594                                 header.attr( "aria-controls", panelId );
4595                                 panel.attr( "aria-labelledby", headerId );
4596                         } )
4597                         .next()
4598                                 .attr( "role", "tabpanel" );
4599 
4600                 this.headers
4601                         .not( this.active )
4602                                 .attr( {
4603                                         "aria-selected": "false",
4604                                         "aria-expanded": "false",
4605                                         tabIndex: -1
4606                                 } )
4607                                 .next()
4608                                         .attr( {
4609                                                 "aria-hidden": "true"
4610                                         } )
4611                                         .hide();
4612 
4613                 // Make sure at least one header is in the tab order
4614                 if ( !this.active.length ) {
4615                         this.headers.eq( 0 ).attr( "tabIndex", 0 );
4616                 } else {
4617                         this.active.attr( {
4618                                 "aria-selected": "true",
4619                                 "aria-expanded": "true",
4620                                 tabIndex: 0
4621                         } )
4622                                 .next()
4623                                         .attr( {
4624                                                 "aria-hidden": "false"
4625                                         } );
4626                 }
4627 
4628                 this._createIcons();
4629 
4630                 this._setupEvents( options.event );
4631 
4632                 if ( heightStyle === "fill" ) {
4633                         maxHeight = parent.height();
4634                         this.element.siblings( ":visible" ).each( function() {
4635                                 var elem = $( this ),
4636                                         position = elem.css( "position" );
4637 
4638                                 if ( position === "absolute" || position === "fixed" ) {
4639                                         return;
4640                                 }
4641                                 maxHeight -= elem.outerHeight( true );
4642                         } );
4643 
4644                         this.headers.each( function() {
4645                                 maxHeight -= $( this ).outerHeight( true );
4646                         } );
4647 
4648                         this.headers.next()
4649                                 .each( function() {
4650                                         $( this ).height( Math.max( 0, maxHeight -
4651                                                 $( this ).innerHeight() + $( this ).height() ) );
4652                                 } )
4653                                 .css( "overflow", "auto" );
4654                 } else if ( heightStyle === "auto" ) {
4655                         maxHeight = 0;
4656                         this.headers.next()
4657                                 .each( function() {
4658                                         var isVisible = $( this ).is( ":visible" );
4659                                         if ( !isVisible ) {
4660                                                 $( this ).show();
4661                                         }
4662                                         maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4663                                         if ( !isVisible ) {
4664                                                 $( this ).hide();
4665                                         }
4666                                 } )
4667                                 .height( maxHeight );
4668                 }
4669         },
4670 
4671         _activate: function( index ) {
4672                 var active = this._findActive( index )[ 0 ];
4673 
4674                 // Trying to activate the already active panel
4675                 if ( active === this.active[ 0 ] ) {
4676                         return;
4677                 }
4678 
4679                 // Trying to collapse, simulate a click on the currently active header
4680                 active = active || this.active[ 0 ];
4681 
4682                 this._eventHandler( {
4683                         target: active,
4684                         currentTarget: active,
4685                         preventDefault: $.noop
4686                 } );
4687         },
4688 
4689         _findActive: function( selector ) {
4690                 return typeof selector === "number" ? this.headers.eq( selector ) : $();
4691         },
4692 
4693         _setupEvents: function( event ) {
4694                 var events = {
4695                         keydown: "_keydown"
4696                 };
4697                 if ( event ) {
4698                         $.each( event.split( " " ), function( index, eventName ) {
4699                                 events[ eventName ] = "_eventHandler";
4700                         } );
4701                 }
4702 
4703                 this._off( this.headers.add( this.headers.next() ) );
4704                 this._on( this.headers, events );
4705                 this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4706                 this._hoverable( this.headers );
4707                 this._focusable( this.headers );
4708         },
4709 
4710         _eventHandler: function( event ) {
4711                 var activeChildren, clickedChildren,
4712                         options = this.options,
4713                         active = this.active,
4714                         clicked = $( event.currentTarget ),
4715                         clickedIsActive = clicked[ 0 ] === active[ 0 ],
4716                         collapsing = clickedIsActive && options.collapsible,
4717                         toShow = collapsing ? $() : clicked.next(),
4718                         toHide = active.next(),
4719                         eventData = {
4720                                 oldHeader: active,
4721                                 oldPanel: toHide,
4722                                 newHeader: collapsing ? $() : clicked,
4723                                 newPanel: toShow
4724                         };
4725 
4726                 event.preventDefault();
4727 
4728                 if (
4729 
4730                                 // click on active header, but not collapsible
4731                                 ( clickedIsActive && !options.collapsible ) ||
4732 
4733                                 // allow canceling activation
4734                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4735                         return;
4736                 }
4737 
4738                 options.active = collapsing ? false : this.headers.index( clicked );
4739 
4740                 // When the call to ._toggle() comes after the class changes
4741                 // it causes a very odd bug in IE 8 (see #6720)
4742                 this.active = clickedIsActive ? $() : clicked;
4743                 this._toggle( eventData );
4744 
4745                 // Switch classes
4746                 // corner classes on the previously active header stay after the animation
4747                 this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4748                 if ( options.icons ) {
4749                         activeChildren = active.children( ".ui-accordion-header-icon" );
4750                         this._removeClass( activeChildren, null, options.icons.activeHeader )
4751                                 ._addClass( activeChildren, null, options.icons.header );
4752                 }
4753 
4754                 if ( !clickedIsActive ) {
4755                         this._removeClass( clicked, "ui-accordion-header-collapsed" )
4756                                 ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4757                         if ( options.icons ) {
4758                                 clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4759                                 this._removeClass( clickedChildren, null, options.icons.header )
4760                                         ._addClass( clickedChildren, null, options.icons.activeHeader );
4761                         }
4762 
4763                         this._addClass( clicked.next(), "ui-accordion-content-active" );
4764                 }
4765         },
4766 
4767         _toggle: function( data ) {
4768                 var toShow = data.newPanel,
4769                         toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4770 
4771                 // Handle activating a panel during the animation for another activation
4772                 this.prevShow.add( this.prevHide ).stop( true, true );
4773                 this.prevShow = toShow;
4774                 this.prevHide = toHide;
4775 
4776                 if ( this.options.animate ) {
4777                         this._animate( toShow, toHide, data );
4778                 } else {
4779                         toHide.hide();
4780                         toShow.show();
4781                         this._toggleComplete( data );
4782                 }
4783 
4784                 toHide.attr( {
4785                         "aria-hidden": "true"
4786                 } );
4787                 toHide.prev().attr( {
4788                         "aria-selected": "false",
4789                         "aria-expanded": "false"
4790                 } );
4791 
4792                 // if we're switching panels, remove the old header from the tab order
4793                 // if we're opening from collapsed state, remove the previous header from the tab order
4794                 // if we're collapsing, then keep the collapsing header in the tab order
4795                 if ( toShow.length && toHide.length ) {
4796                         toHide.prev().attr( {
4797                                 "tabIndex": -1,
4798                                 "aria-expanded": "false"
4799                         } );
4800                 } else if ( toShow.length ) {
4801                         this.headers.filter( function() {
4802                                 return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4803                         } )
4804                                 .attr( "tabIndex", -1 );
4805                 }
4806 
4807                 toShow
4808                         .attr( "aria-hidden", "false" )
4809                         .prev()
4810                                 .attr( {
4811                                         "aria-selected": "true",
4812                                         "aria-expanded": "true",
4813                                         tabIndex: 0
4814                                 } );
4815         },
4816 
4817         _animate: function( toShow, toHide, data ) {
4818                 var total, easing, duration,
4819                         that = this,
4820                         adjust = 0,
4821                         boxSizing = toShow.css( "box-sizing" ),
4822                         down = toShow.length &&
4823                                 ( !toHide.length || ( toShow.index() < toHide.index() ) ),
4824                         animate = this.options.animate || {},
4825                         options = down && animate.down || animate,
4826                         complete = function() {
4827                                 that._toggleComplete( data );
4828                         };
4829 
4830                 if ( typeof options === "number" ) {
4831                         duration = options;
4832                 }
4833                 if ( typeof options === "string" ) {
4834                         easing = options;
4835                 }
4836 
4837                 // fall back from options to animation in case of partial down settings
4838                 easing = easing || options.easing || animate.easing;
4839                 duration = duration || options.duration || animate.duration;
4840 
4841                 if ( !toHide.length ) {
4842                         return toShow.animate( this.showProps, duration, easing, complete );
4843                 }
4844                 if ( !toShow.length ) {
4845                         return toHide.animate( this.hideProps, duration, easing, complete );
4846                 }
4847 
4848                 total = toShow.show().outerHeight();
4849                 toHide.animate( this.hideProps, {
4850                         duration: duration,
4851                         easing: easing,
4852                         step: function( now, fx ) {
4853                                 fx.now = Math.round( now );
4854                         }
4855                 } );
4856                 toShow
4857                         .hide()
4858                         .animate( this.showProps, {
4859                                 duration: duration,
4860                                 easing: easing,
4861                                 complete: complete,
4862                                 step: function( now, fx ) {
4863                                         fx.now = Math.round( now );
4864                                         if ( fx.prop !== "height" ) {
4865                                                 if ( boxSizing === "content-box" ) {
4866                                                         adjust += fx.now;
4867                                                 }
4868                                         } else if ( that.options.heightStyle !== "content" ) {
4869                                                 fx.now = Math.round( total - toHide.outerHeight() - adjust );
4870                                                 adjust = 0;
4871                                         }
4872                                 }
4873                         } );
4874         },
4875 
4876         _toggleComplete: function( data ) {
4877                 var toHide = data.oldPanel,
4878                         prev = toHide.prev();
4879 
4880                 this._removeClass( toHide, "ui-accordion-content-active" );
4881                 this._removeClass( prev, "ui-accordion-header-active" )
4882                         ._addClass( prev, "ui-accordion-header-collapsed" );
4883 
4884                 // Work around for rendering bug in IE (#5421)
4885                 if ( toHide.length ) {
4886                         toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4887                 }
4888                 this._trigger( "activate", null, data );
4889         }
4890 } );
4891 
4892 
4893 
4894 var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4895         var activeElement;
4896 
4897         // Support: IE 9 only
4898         // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4899         try {
4900                 activeElement = document.activeElement;
4901         } catch ( error ) {
4902                 activeElement = document.body;
4903         }
4904 
4905         // Support: IE 9 - 11 only
4906         // IE may return null instead of an element
4907         // Interestingly, this only seems to occur when NOT in an iframe
4908         if ( !activeElement ) {
4909                 activeElement = document.body;
4910         }
4911 
4912         // Support: IE 11 only
4913         // IE11 returns a seemingly empty object in some cases when accessing
4914         // document.activeElement from an <iframe>
4915         if ( !activeElement.nodeName ) {
4916                 activeElement = document.body;
4917         }
4918 
4919         return activeElement;
4920 };
4921 
4922 
4923 /*!
4924  * jQuery UI Menu 1.12.1
4925  * http://jqueryui.com
4926  *
4927  * Copyright jQuery Foundation and other contributors
4928  * Released under the MIT license.
4929  * http://jquery.org/license
4930  */
4931 
4932 //>>label: Menu
4933 //>>group: Widgets
4934 //>>description: Creates nestable menus.
4935 //>>docs: http://api.jqueryui.com/menu/
4936 //>>demos: http://jqueryui.com/menu/
4937 //>>css.structure: ../../themes/base/core.css
4938 //>>css.structure: ../../themes/base/menu.css
4939 //>>css.theme: ../../themes/base/theme.css
4940 
4941 
4942 
4943 var widgetsMenu = $.widget( "ui.menu", {
4944         version: "1.12.1",
4945         defaultElement: "<ul>",
4946         delay: 300,
4947         options: {
4948                 icons: {
4949                         submenu: "ui-icon-caret-1-e"
4950                 },
4951                 items: "> *",
4952                 menus: "ul",
4953                 position: {
4954                         my: "left top",
4955                         at: "right top"
4956                 },
4957                 role: "menu",
4958 
4959                 // Callbacks
4960                 blur: null,
4961                 focus: null,
4962                 select: null
4963         },
4964 
4965         _create: function() {
4966                 this.activeMenu = this.element;
4967 
4968                 // Flag used to prevent firing of the click handler
4969                 // as the event bubbles up through nested menus
4970                 this.mouseHandled = false;
4971                 this.element
4972                         .uniqueId()
4973                         .attr( {
4974                                 role: this.options.role,
4975                                 tabIndex: 0
4976                         } );
4977 
4978                 this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4979                 this._on( {
4980 
4981                         // Prevent focus from sticking to links inside menu after clicking
4982                         // them (focus should always stay on UL during navigation).
4983                         "mousedown .ui-menu-item": function( event ) {
4984                                 event.preventDefault();
4985                         },
4986                         "click .ui-menu-item": function( event ) {
4987                                 var target = $( event.target );
4988                                 var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4989                                 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4990                                         this.select( event );
4991 
4992                                         // Only set the mouseHandled flag if the event will bubble, see #9469.
4993                                         if ( !event.isPropagationStopped() ) {
4994                                                 this.mouseHandled = true;
4995                                         }
4996 
4997                                         // Open submenu on click
4998                                         if ( target.has( ".ui-menu" ).length ) {
4999                                                 this.expand( event );
5000                                         } else if ( !this.element.is( ":focus" ) &&
5001                                                         active.closest( ".ui-menu" ).length ) {
5002 
5003                                                 // Redirect focus to the menu
5004                                                 this.element.trigger( "focus", [ true ] );
5005 
5006                                                 // If the active item is on the top level, let it stay active.
5007                                                 // Otherwise, blur the active item since it is no longer visible.
5008                                                 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5009                                                         clearTimeout( this.timer );
5010                                                 }
5011                                         }
5012                                 }
5013                         },
5014                         "mouseenter .ui-menu-item": function( event ) {
5015 
5016                                 // Ignore mouse events while typeahead is active, see #10458.
5017                                 // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5018                                 // is over an item in the menu
5019                                 if ( this.previousFilter ) {
5020                                         return;
5021                                 }
5022 
5023                                 var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5024                                         target = $( event.currentTarget );
5025 
5026                                 // Ignore bubbled events on parent items, see #11641
5027                                 if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5028                                         return;
5029                                 }
5030 
5031                                 // Remove ui-state-active class from siblings of the newly focused menu item
5032                                 // to avoid a jump caused by adjacent elements both having a class with a border
5033                                 this._removeClass( target.siblings().children( ".ui-state-active" ),
5034                                         null, "ui-state-active" );
5035                                 this.focus( event, target );
5036                         },
5037                         mouseleave: "collapseAll",
5038                         "mouseleave .ui-menu": "collapseAll",
5039                         focus: function( event, keepActiveItem ) {
5040 
5041                                 // If there's already an active item, keep it active
5042                                 // If not, activate the first item
5043                                 var item = this.active || this.element.find( this.options.items ).eq( 0 );
5044 
5045                                 if ( !keepActiveItem ) {
5046                                         this.focus( event, item );
5047                                 }
5048                         },
5049                         blur: function( event ) {
5050                                 this._delay( function() {
5051                                         var notContained = !$.contains(
5052                                                 this.element[ 0 ],
5053                                                 $.ui.safeActiveElement( this.document[ 0 ] )
5054                                         );
5055                                         if ( notContained ) {
5056                                                 this.collapseAll( event );
5057                                         }
5058                                 } );
5059                         },
5060                         keydown: "_keydown"
5061                 } );
5062 
5063                 this.refresh();
5064 
5065                 // Clicks outside of a menu collapse any open menus
5066                 this._on( this.document, {
5067                         click: function( event ) {
5068                                 if ( this._closeOnDocumentClick( event ) ) {
5069                                         this.collapseAll( event );
5070                                 }
5071 
5072                                 // Reset the mouseHandled flag
5073                                 this.mouseHandled = false;
5074                         }
5075                 } );
5076         },
5077 
5078         _destroy: function() {
5079                 var items = this.element.find( ".ui-menu-item" )
5080                                 .removeAttr( "role aria-disabled" ),
5081                         submenus = items.children( ".ui-menu-item-wrapper" )
5082                                 .removeUniqueId()
5083                                 .removeAttr( "tabIndex role aria-haspopup" );
5084 
5085                 // Destroy (sub)menus
5086                 this.element
5087                         .removeAttr( "aria-activedescendant" )
5088                         .find( ".ui-menu" ).addBack()
5089                                 .removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5090                                         "tabIndex" )
5091                                 .removeUniqueId()
5092                                 .show();
5093 
5094                 submenus.children().each( function() {
5095                         var elem = $( this );
5096                         if ( elem.data( "ui-menu-submenu-caret" ) ) {
5097                                 elem.remove();
5098                         }
5099                 } );
5100         },
5101 
5102         _keydown: function( event ) {
5103                 var match, prev, character, skip,
5104                         preventDefault = true;
5105 
5106                 switch ( event.keyCode ) {
5107                 case $.ui.keyCode.PAGE_UP:
5108                         this.previousPage( event );
5109                         break;
5110                 case $.ui.keyCode.PAGE_DOWN:
5111                         this.nextPage( event );
5112                         break;
5113                 case $.ui.keyCode.HOME:
5114                         this._move( "first", "first", event );
5115                         break;
5116                 case $.ui.keyCode.END:
5117                         this._move( "last", "last", event );
5118                         break;
5119                 case $.ui.keyCode.UP:
5120                         this.previous( event );
5121                         break;
5122                 case $.ui.keyCode.DOWN:
5123                         this.next( event );
5124                         break;
5125                 case $.ui.keyCode.LEFT:
5126                         this.collapse( event );
5127                         break;
5128                 case $.ui.keyCode.RIGHT:
5129                         if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5130                                 this.expand( event );
5131                         }
5132                         break;
5133                 case $.ui.keyCode.ENTER:
5134                 case $.ui.keyCode.SPACE:
5135                         this._activate( event );
5136                         break;
5137                 case $.ui.keyCode.ESCAPE:
5138                         this.collapse( event );
5139                         break;
5140                 default:
5141                         preventDefault = false;
5142                         prev = this.previousFilter || "";
5143                         skip = false;
5144 
5145                         // Support number pad values
5146                         character = event.keyCode >= 96 && event.keyCode <= 105 ?
5147                                 ( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5148 
5149                         clearTimeout( this.filterTimer );
5150 
5151                         if ( character === prev ) {
5152                                 skip = true;
5153                         } else {
5154                                 character = prev + character;
5155                         }
5156 
5157                         match = this._filterMenuItems( character );
5158                         match = skip && match.index( this.active.next() ) !== -1 ?
5159                                 this.active.nextAll( ".ui-menu-item" ) :
5160                                 match;
5161 
5162                         // If no matches on the current filter, reset to the last character pressed
5163                         // to move down the menu to the first item that starts with that character
5164                         if ( !match.length ) {
5165                                 character = String.fromCharCode( event.keyCode );
5166                                 match = this._filterMenuItems( character );
5167                         }
5168 
5169                         if ( match.length ) {
5170                                 this.focus( event, match );
5171                                 this.previousFilter = character;
5172                                 this.filterTimer = this._delay( function() {
5173                                         delete this.previousFilter;
5174                                 }, 1000 );
5175                         } else {
5176                                 delete this.previousFilter;
5177                         }
5178                 }
5179 
5180                 if ( preventDefault ) {
5181                         event.preventDefault();
5182                 }
5183         },
5184 
5185         _activate: function( event ) {
5186                 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5187                         if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5188                                 this.expand( event );
5189                         } else {
5190                                 this.select( event );
5191                         }
5192                 }
5193         },
5194 
5195         refresh: function() {
5196                 var menus, items, newSubmenus, newItems, newWrappers,
5197                         that = this,
5198                         icon = this.options.icons.submenu,
5199                         submenus = this.element.find( this.options.menus );
5200 
5201                 this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5202 
5203                 // Initialize nested menus
5204                 newSubmenus = submenus.filter( ":not(.ui-menu)" )
5205                         .hide()
5206                         .attr( {
5207                                 role: this.options.role,
5208                                 "aria-hidden": "true",
5209                                 "aria-expanded": "false"
5210                         } )
5211                         .each( function() {
5212                                 var menu = $( this ),
5213                                         item = menu.prev(),
5214                                         submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5215 
5216                                 that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5217                                 item
5218                                         .attr( "aria-haspopup", "true" )
5219                                         .prepend( submenuCaret );
5220                                 menu.attr( "aria-labelledby", item.attr( "id" ) );
5221                         } );
5222 
5223                 this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5224 
5225                 menus = submenus.add( this.element );
5226                 items = menus.find( this.options.items );
5227 
5228                 // Initialize menu-items containing spaces and/or dashes only as dividers
5229                 items.not( ".ui-menu-item" ).each( function() {
5230                         var item = $( this );
5231                         if ( that._isDivider( item ) ) {
5232                                 that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5233                         }
5234                 } );
5235 
5236                 // Don't refresh list items that are already adapted
5237                 newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5238                 newWrappers = newItems.children()
5239                         .not( ".ui-menu" )
5240                                 .uniqueId()
5241                                 .attr( {
5242                                         tabIndex: -1,
5243                                         role: this._itemRole()
5244                                 } );
5245                 this._addClass( newItems, "ui-menu-item" )
5246                         ._addClass( newWrappers, "ui-menu-item-wrapper" );
5247 
5248                 // Add aria-disabled attribute to any disabled menu item
5249                 items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5250 
5251                 // If the active item has been removed, blur the menu
5252                 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5253                         this.blur();
5254                 }
5255         },
5256 
5257         _itemRole: function() {
5258                 return {
5259                         menu: "menuitem",
5260                         listbox: "option"
5261                 }[ this.options.role ];
5262         },
5263 
5264         _setOption: function( key, value ) {
5265                 if ( key === "icons" ) {
5266                         var icons = this.element.find( ".ui-menu-icon" );
5267                         this._removeClass( icons, null, this.options.icons.submenu )
5268                                 ._addClass( icons, null, value.submenu );
5269                 }
5270                 this._super( key, value );
5271         },
5272 
5273         _setOptionDisabled: function( value ) {
5274                 this._super( value );
5275 
5276                 this.element.attr( "aria-disabled", String( value ) );
5277                 this._toggleClass( null, "ui-state-disabled", !!value );
5278         },
5279 
5280         focus: function( event, item ) {
5281                 var nested, focused, activeParent;
5282                 this.blur( event, event && event.type === "focus" );
5283 
5284                 this._scrollIntoView( item );
5285 
5286                 this.active = item.first();
5287 
5288                 focused = this.active.children( ".ui-menu-item-wrapper" );
5289                 this._addClass( focused, null, "ui-state-active" );
5290 
5291                 // Only update aria-activedescendant if there's a role
5292                 // otherwise we assume focus is managed elsewhere
5293                 if ( this.options.role ) {
5294                         this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5295                 }
5296 
5297                 // Highlight active parent menu item, if any
5298                 activeParent = this.active
5299                         .parent()
5300                                 .closest( ".ui-menu-item" )
5301                                         .children( ".ui-menu-item-wrapper" );
5302                 this._addClass( activeParent, null, "ui-state-active" );
5303 
5304                 if ( event && event.type === "keydown" ) {
5305                         this._close();
5306                 } else {
5307                         this.timer = this._delay( function() {
5308                                 this._close();
5309                         }, this.delay );
5310                 }
5311 
5312                 nested = item.children( ".ui-menu" );
5313                 if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314                         this._startOpening( nested );
5315                 }
5316                 this.activeMenu = item.parent();
5317 
5318                 this._trigger( "focus", event, { item: item } );
5319         },
5320 
5321         _scrollIntoView: function( item ) {
5322                 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323                 if ( this._hasScroll() ) {
5324                         borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5325                         paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5326                         offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327                         scroll = this.activeMenu.scrollTop();
5328                         elementHeight = this.activeMenu.height();
5329                         itemHeight = item.outerHeight();
5330 
5331                         if ( offset < 0 ) {
5332                                 this.activeMenu.scrollTop( scroll + offset );
5333                         } else if ( offset + itemHeight > elementHeight ) {
5334                                 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335                         }
5336                 }
5337         },
5338 
5339         blur: function( event, fromFocus ) {
5340                 if ( !fromFocus ) {
5341                         clearTimeout( this.timer );
5342                 }
5343 
5344                 if ( !this.active ) {
5345                         return;
5346                 }
5347 
5348                 this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5349                         null, "ui-state-active" );
5350 
5351                 this._trigger( "blur", event, { item: this.active } );
5352                 this.active = null;
5353         },
5354 
5355         _startOpening: function( submenu ) {
5356                 clearTimeout( this.timer );
5357 
5358                 // Don't open if already open fixes a Firefox bug that caused a .5 pixel
5359                 // shift in the submenu position when mousing over the caret icon
5360                 if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5361                         return;
5362                 }
5363 
5364                 this.timer = this._delay( function() {
5365                         this._close();
5366                         this._open( submenu );
5367                 }, this.delay );
5368         },
5369 
5370         _open: function( submenu ) {
5371                 var position = $.extend( {
5372                         of: this.active
5373                 }, this.options.position );
5374 
5375                 clearTimeout( this.timer );
5376                 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5377                         .hide()
5378                         .attr( "aria-hidden", "true" );
5379 
5380                 submenu
5381                         .show()
5382                         .removeAttr( "aria-hidden" )
5383                         .attr( "aria-expanded", "true" )
5384                         .position( position );
5385         },
5386 
5387         collapseAll: function( event, all ) {
5388                 clearTimeout( this.timer );
5389                 this.timer = this._delay( function() {
5390 
5391                         // If we were passed an event, look for the submenu that contains the event
5392                         var currentMenu = all ? this.element :
5393                                 $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5394 
5395                         // If we found no valid submenu ancestor, use the main menu to close all
5396                         // sub menus anyway
5397                         if ( !currentMenu.length ) {
5398                                 currentMenu = this.element;
5399                         }
5400 
5401                         this._close( currentMenu );
5402 
5403                         this.blur( event );
5404 
5405                         // Work around active item staying active after menu is blurred
5406                         this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5407 
5408                         this.activeMenu = currentMenu;
5409                 }, this.delay );
5410         },
5411 
5412         // With no arguments, closes the currently active menu - if nothing is active
5413         // it closes all menus.  If passed an argument, it will search for menus BELOW
5414         _close: function( startMenu ) {
5415                 if ( !startMenu ) {
5416                         startMenu = this.active ? this.active.parent() : this.element;
5417                 }
5418 
5419                 startMenu.find( ".ui-menu" )
5420                         .hide()
5421                         .attr( "aria-hidden", "true" )
5422                         .attr( "aria-expanded", "false" );
5423         },
5424 
5425         _closeOnDocumentClick: function( event ) {
5426                 return !$( event.target ).closest( ".ui-menu" ).length;
5427         },
5428 
5429         _isDivider: function( item ) {
5430 
5431                 // Match hyphen, em dash, en dash
5432                 return !/[^\-\u2014\u2013\s]/.test( item.text() );
5433         },
5434 
5435         collapse: function( event ) {
5436                 var newItem = this.active &&
5437                         this.active.parent().closest( ".ui-menu-item", this.element );
5438                 if ( newItem && newItem.length ) {
5439                         this._close();
5440                         this.focus( event, newItem );
5441                 }
5442         },
5443 
5444         expand: function( event ) {
5445                 var newItem = this.active &&
5446                         this.active
5447                                 .children( ".ui-menu " )
5448                                         .find( this.options.items )
5449                                                 .first();
5450 
5451                 if ( newItem && newItem.length ) {
5452                         this._open( newItem.parent() );
5453 
5454                         // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5455                         this._delay( function() {
5456                                 this.focus( event, newItem );
5457                         } );
5458                 }
5459         },
5460 
5461         next: function( event ) {
5462                 this._move( "next", "first", event );
5463         },
5464 
5465         previous: function( event ) {
5466                 this._move( "prev", "last", event );
5467         },
5468 
5469         isFirstItem: function() {
5470                 return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5471         },
5472 
5473         isLastItem: function() {
5474                 return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5475         },
5476 
5477         _move: function( direction, filter, event ) {
5478                 var next;
5479                 if ( this.active ) {
5480                         if ( direction === "first" || direction === "last" ) {
5481                                 next = this.active
5482                                         [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5483                                         .eq( -1 );
5484                         } else {
5485                                 next = this.active
5486                                         [ direction + "All" ]( ".ui-menu-item" )
5487                                         .eq( 0 );
5488                         }
5489                 }
5490                 if ( !next || !next.length || !this.active ) {
5491                         next = this.activeMenu.find( this.options.items )[ filter ]();
5492                 }
5493 
5494                 this.focus( event, next );
5495         },
5496 
5497         nextPage: function( event ) {
5498                 var item, base, height;
5499 
5500                 if ( !this.active ) {
5501                         this.next( event );
5502                         return;
5503                 }
5504                 if ( this.isLastItem() ) {
5505                         return;
5506                 }
5507                 if ( this._hasScroll() ) {
5508                         base = this.active.offset().top;
5509                         height = this.element.height();
5510                         this.active.nextAll( ".ui-menu-item" ).each( function() {
5511                                 item = $( this );
5512                                 return item.offset().top - base - height < 0;
5513                         } );
5514 
5515                         this.focus( event, item );
5516                 } else {
5517                         this.focus( event, this.activeMenu.find( this.options.items )
5518                                 [ !this.active ? "first" : "last" ]() );
5519                 }
5520         },
5521 
5522         previousPage: function( event ) {
5523                 var item, base, height;
5524                 if ( !this.active ) {
5525                         this.next( event );
5526                         return;
5527                 }
5528                 if ( this.isFirstItem() ) {
5529                         return;
5530                 }
5531                 if ( this._hasScroll() ) {
5532                         base = this.active.offset().top;
5533                         height = this.element.height();
5534                         this.active.prevAll( ".ui-menu-item" ).each( function() {
5535                                 item = $( this );
5536                                 return item.offset().top - base + height > 0;
5537                         } );
5538 
5539                         this.focus( event, item );
5540                 } else {
5541                         this.focus( event, this.activeMenu.find( this.options.items ).first() );
5542                 }
5543         },
5544 
5545         _hasScroll: function() {
5546                 return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5547         },
5548 
5549         select: function( event ) {
5550 
5551                 // TODO: It should never be possible to not have an active item at this
5552                 // point, but the tests don't trigger mouseenter before click.
5553                 this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5554                 var ui = { item: this.active };
5555                 if ( !this.active.has( ".ui-menu" ).length ) {
5556                         this.collapseAll( event, true );
5557                 }
5558                 this._trigger( "select", event, ui );
5559         },
5560 
5561         _filterMenuItems: function( character ) {
5562                 var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5563                         regex = new RegExp( "^" + escapedCharacter, "i" );
5564 
5565                 return this.activeMenu
5566                         .find( this.options.items )
5567 
5568                                 // Only match on items, not dividers or other content (#10571)
5569                                 .filter( ".ui-menu-item" )
5570                                         .filter( function() {
5571                                                 return regex.test(
5572                                                         $.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5573                                         } );
5574         }
5575 } );
5576 
5577 
5578 /*!
5579  * jQuery UI Autocomplete 1.12.1
5580  * http://jqueryui.com
5581  *
5582  * Copyright jQuery Foundation and other contributors
5583  * Released under the MIT license.
5584  * http://jquery.org/license
5585  */
5586 
5587 //>>label: Autocomplete
5588 //>>group: Widgets
5589 //>>description: Lists suggested words as the user is typing.
5590 //>>docs: http://api.jqueryui.com/autocomplete/
5591 //>>demos: http://jqueryui.com/autocomplete/
5592 //>>css.structure: ../../themes/base/core.css
5593 //>>css.structure: ../../themes/base/autocomplete.css
5594 //>>css.theme: ../../themes/base/theme.css
5595 
5596 
5597 
5598 $.widget( "ui.autocomplete", {
5599         version: "1.12.1",
5600         defaultElement: "<input>",
5601         options: {
5602                 appendTo: null,
5603                 autoFocus: false,
5604                 delay: 300,
5605                 minLength: 1,
5606                 position: {
5607                         my: "left top",
5608                         at: "left bottom",
5609                         collision: "none"
5610                 },
5611                 source: null,
5612 
5613                 // Callbacks
5614                 change: null,
5615                 close: null,
5616                 focus: null,
5617                 open: null,
5618                 response: null,
5619                 search: null,
5620                 select: null
5621         },
5622 
5623         requestIndex: 0,
5624         pending: 0,
5625 
5626         _create: function() {
5627 
5628                 // Some browsers only repeat keydown events, not keypress events,
5629                 // so we use the suppressKeyPress flag to determine if we've already
5630                 // handled the keydown event. #7269
5631                 // Unfortunately the code for & in keypress is the same as the up arrow,
5632                 // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5633                 // events when we know the keydown event was used to modify the
5634                 // search term. #7799
5635                 var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5636                         nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5637                         isTextarea = nodeName === "textarea",
5638                         isInput = nodeName === "input";
5639 
5640                 // Textareas are always multi-line
5641                 // Inputs are always single-line, even if inside a contentEditable element
5642                 // IE also treats inputs as contentEditable
5643                 // All other element types are determined by whether or not they're contentEditable
5644                 this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5645 
5646                 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5647                 this.isNewMenu = true;
5648 
5649                 this._addClass( "ui-autocomplete-input" );
5650                 this.element.attr( "autocomplete", "off" );
5651 
5652                 this._on( this.element, {
5653                         keydown: function( event ) {
5654                                 if ( this.element.prop( "readOnly" ) ) {
5655                                         suppressKeyPress = true;
5656                                         suppressInput = true;
5657                                         suppressKeyPressRepeat = true;
5658                                         return;
5659                                 }
5660 
5661                                 suppressKeyPress = false;
5662                                 suppressInput = false;
5663                                 suppressKeyPressRepeat = false;
5664                                 var keyCode = $.ui.keyCode;
5665                                 switch ( event.keyCode ) {
5666                                 case keyCode.PAGE_UP:
5667                                         suppressKeyPress = true;
5668                                         this._move( "previousPage", event );
5669                                         break;
5670                                 case keyCode.PAGE_DOWN:
5671                                         suppressKeyPress = true;
5672                                         this._move( "nextPage", event );
5673                                         break;
5674                                 case keyCode.UP:
5675                                         suppressKeyPress = true;
5676                                         this._keyEvent( "previous", event );
5677                                         break;
5678                                 case keyCode.DOWN:
5679                                         suppressKeyPress = true;
5680                                         this._keyEvent( "next", event );
5681                                         break;
5682                                 case keyCode.ENTER:
5683 
5684                                         // when menu is open and has focus
5685                                         if ( this.menu.active ) {
5686 
5687                                                 // #6055 - Opera still allows the keypress to occur
5688                                                 // which causes forms to submit
5689                                                 suppressKeyPress = true;
5690                                                 event.preventDefault();
5691                                                 this.menu.select( event );
5692                                         }
5693                                         break;
5694                                 case keyCode.TAB:
5695                                         if ( this.menu.active ) {
5696                                                 this.menu.select( event );
5697                                         }
5698                                         break;
5699                                 case keyCode.ESCAPE:
5700                                         if ( this.menu.element.is( ":visible" ) ) {
5701                                                 if ( !this.isMultiLine ) {
5702                                                         this._value( this.term );
5703                                                 }
5704                                                 this.close( event );
5705 
5706                                                 // Different browsers have different default behavior for escape
5707                                                 // Single press can mean undo or clear
5708                                                 // Double press in IE means clear the whole form
5709                                                 event.preventDefault();
5710                                         }
5711                                         break;
5712                                 default:
5713                                         suppressKeyPressRepeat = true;
5714 
5715                                         // search timeout should be triggered before the input value is changed
5716                                         this._searchTimeout( event );
5717                                         break;
5718                                 }
5719                         },
5720                         keypress: function( event ) {
5721                                 if ( suppressKeyPress ) {
5722                                         suppressKeyPress = false;
5723                                         if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5724                                                 event.preventDefault();
5725                                         }
5726                                         return;
5727                                 }
5728                                 if ( suppressKeyPressRepeat ) {
5729                                         return;
5730                                 }
5731 
5732                                 // Replicate some key handlers to allow them to repeat in Firefox and Opera
5733                                 var keyCode = $.ui.keyCode;
5734                                 switch ( event.keyCode ) {
5735                                 case keyCode.PAGE_UP:
5736                                         this._move( "previousPage", event );
5737                                         break;
5738                                 case keyCode.PAGE_DOWN:
5739                                         this._move( "nextPage", event );
5740                                         break;
5741                                 case keyCode.UP:
5742                                         this._keyEvent( "previous", event );
5743                                         break;
5744                                 case keyCode.DOWN:
5745                                         this._keyEvent( "next", event );
5746                                         break;
5747                                 }
5748                         },
5749                         input: function( event ) {
5750                                 if ( suppressInput ) {
5751                                         suppressInput = false;
5752                                         event.preventDefault();
5753                                         return;
5754                                 }
5755                                 this._searchTimeout( event );
5756                         },
5757                         focus: function() {
5758                                 this.selectedItem = null;
5759                                 this.previous = this._value();
5760                         },
5761                         blur: function( event ) {
5762                                 if ( this.cancelBlur ) {
5763                                         delete this.cancelBlur;
5764                                         return;
5765                                 }
5766 
5767                                 clearTimeout( this.searching );
5768                                 this.close( event );
5769                                 this._change( event );
5770                         }
5771                 } );
5772 
5773                 this._initSource();
5774                 this.menu = $( "<ul>" )
5775                         .appendTo( this._appendTo() )
5776                         .menu( {
5777 
5778                                 // disable ARIA support, the live region takes care of that
5779                                 role: null
5780                         } )
5781                         .hide()
5782                         .menu( "instance" );
5783 
5784                 this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5785                 this._on( this.menu.element, {
5786                         mousedown: function( event ) {
5787 
5788                                 // prevent moving focus out of the text field
5789                                 event.preventDefault();
5790 
5791                                 // IE doesn't prevent moving focus even with event.preventDefault()
5792                                 // so we set a flag to know when we should ignore the blur event
5793                                 this.cancelBlur = true;
5794                                 this._delay( function() {
5795                                         delete this.cancelBlur;
5796 
5797                                         // Support: IE 8 only
5798                                         // Right clicking a menu item or selecting text from the menu items will
5799                                         // result in focus moving out of the input. However, we've already received
5800                                         // and ignored the blur event because of the cancelBlur flag set above. So
5801                                         // we restore focus to ensure that the menu closes properly based on the user's
5802                                         // next actions.
5803                                         if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5804                                                 this.element.trigger( "focus" );
5805                                         }
5806                                 } );
5807                         },
5808                         menufocus: function( event, ui ) {
5809                                 var label, item;
5810 
5811                                 // support: Firefox
5812                                 // Prevent accidental activation of menu items in Firefox (#7024 #9118)
5813                                 if ( this.isNewMenu ) {
5814                                         this.isNewMenu = false;
5815                                         if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5816                                                 this.menu.blur();
5817 
5818                                                 this.document.one( "mousemove", function() {
5819                                                         $( event.target ).trigger( event.originalEvent );
5820                                                 } );
5821 
5822                                                 return;
5823                                         }
5824                                 }
5825 
5826                                 item = ui.item.data( "ui-autocomplete-item" );
5827                                 if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828 
5829                                         // use value to match what will end up in the input, if it was a key event
5830                                         if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831                                                 this._value( item.value );
5832                                         }
5833                                 }
5834 
5835                                 // Announce the value in the liveRegion
5836                                 label = ui.item.attr( "aria-label" ) || item.value;
5837                                 if ( label && $.trim( label ).length ) {
5838                                         this.liveRegion.children().hide();
5839                                         $( "<div>" ).text( label ).appendTo( this.liveRegion );
5840                                 }
5841                         },
5842                         menuselect: function( event, ui ) {
5843                                 var item = ui.item.data( "ui-autocomplete-item" ),
5844                                         previous = this.previous;
5845 
5846                                 // Only trigger when focus was lost (click on menu)
5847                                 if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5848                                         this.element.trigger( "focus" );
5849                                         this.previous = previous;
5850 
5851                                         // #6109 - IE triggers two focus events and the second
5852                                         // is asynchronous, so we need to reset the previous
5853                                         // term synchronously and asynchronously :-(
5854                                         this._delay( function() {
5855                                                 this.previous = previous;
5856                                                 this.selectedItem = item;
5857                                         } );
5858                                 }
5859 
5860                                 if ( false !== this._trigger( "select", event, { item: item } ) ) {
5861                                         this._value( item.value );
5862                                 }
5863 
5864                                 // reset the term after the select event
5865                                 // this allows custom select handling to work properly
5866                                 this.term = this._value();
5867 
5868                                 this.close( event );
5869                                 this.selectedItem = item;
5870                         }
5871                 } );
5872 
5873                 this.liveRegion = $( "<div>", {
5874                         role: "status",
5875                         "aria-live": "assertive",
5876                         "aria-relevant": "additions"
5877                 } )
5878                         .appendTo( this.document[ 0 ].body );
5879 
5880                 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5881 
5882                 // Turning off autocomplete prevents the browser from remembering the
5883                 // value when navigating through history, so we re-enable autocomplete
5884                 // if the page is unloaded before the widget is destroyed. #7790
5885                 this._on( this.window, {
5886                         beforeunload: function() {
5887                                 this.element.removeAttr( "autocomplete" );
5888                         }
5889                 } );
5890         },
5891 
5892         _destroy: function() {
5893                 clearTimeout( this.searching );
5894                 this.element.removeAttr( "autocomplete" );
5895                 this.menu.element.remove();
5896                 this.liveRegion.remove();
5897         },
5898 
5899         _setOption: function( key, value ) {
5900                 this._super( key, value );
5901                 if ( key === "source" ) {
5902                         this._initSource();
5903                 }
5904                 if ( key === "appendTo" ) {
5905                         this.menu.element.appendTo( this._appendTo() );
5906                 }
5907                 if ( key === "disabled" && value && this.xhr ) {
5908                         this.xhr.abort();
5909                 }
5910         },
5911 
5912         _isEventTargetInWidget: function( event ) {
5913                 var menuElement = this.menu.element[ 0 ];
5914 
5915                 return event.target === this.element[ 0 ] ||
5916                         event.target === menuElement ||
5917                         $.contains( menuElement, event.target );
5918         },
5919 
5920         _closeOnClickOutside: function( event ) {
5921                 if ( !this._isEventTargetInWidget( event ) ) {
5922                         this.close();
5923                 }
5924         },
5925 
5926         _appendTo: function() {
5927                 var element = this.options.appendTo;
5928 
5929                 if ( element ) {
5930                         element = element.jquery || element.nodeType ?
5931                                 $( element ) :
5932                                 this.document.find( element ).eq( 0 );
5933                 }
5934 
5935                 if ( !element || !element[ 0 ] ) {
5936                         element = this.element.closest( ".ui-front, dialog" );
5937                 }
5938 
5939                 if ( !element.length ) {
5940                         element = this.document[ 0 ].body;
5941                 }
5942 
5943                 return element;
5944         },
5945 
5946         _initSource: function() {
5947                 var array, url,
5948                         that = this;
5949                 if ( $.isArray( this.options.source ) ) {
5950                         array = this.options.source;
5951                         this.source = function( request, response ) {
5952                                 response( $.ui.autocomplete.filter( array, request.term ) );
5953                         };
5954                 } else if ( typeof this.options.source === "string" ) {
5955                         url = this.options.source;
5956                         this.source = function( request, response ) {
5957                                 if ( that.xhr ) {
5958                                         that.xhr.abort();
5959                                 }
5960                                 that.xhr = $.ajax( {
5961                                         url: url,
5962                                         data: request,
5963                                         dataType: "json",
5964                                         success: function( data ) {
5965                                                 response( data );
5966                                         },
5967                                         error: function() {
5968                                                 response( [] );
5969                                         }
5970                                 } );
5971                         };
5972                 } else {
5973                         this.source = this.options.source;
5974                 }
5975         },
5976 
5977         _searchTimeout: function( event ) {
5978                 clearTimeout( this.searching );
5979                 this.searching = this._delay( function() {
5980 
5981                         // Search if the value has changed, or if the user retypes the same value (see #7434)
5982                         var equalValues = this.term === this._value(),
5983                                 menuVisible = this.menu.element.is( ":visible" ),
5984                                 modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5985 
5986                         if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5987                                 this.selectedItem = null;
5988                                 this.search( null, event );
5989                         }
5990                 }, this.options.delay );
5991         },
5992 
5993         search: function( value, event ) {
5994                 value = value != null ? value : this._value();
5995 
5996                 // Always save the actual value, not the one passed as an argument
5997                 this.term = this._value();
5998 
5999                 if ( value.length < this.options.minLength ) {
6000                         return this.close( event );
6001                 }
6002 
6003                 if ( this._trigger( "search", event ) === false ) {
6004                         return;
6005                 }
6006 
6007                 return this._search( value );
6008         },
6009 
6010         _search: function( value ) {
6011                 this.pending++;
6012                 this._addClass( "ui-autocomplete-loading" );
6013                 this.cancelSearch = false;
6014 
6015                 this.source( { term: value }, this._response() );
6016         },
6017 
6018         _response: function() {
6019                 var index = ++this.requestIndex;
6020 
6021                 return $.proxy( function( content ) {
6022                         if ( index === this.requestIndex ) {
6023                                 this.__response( content );
6024                         }
6025 
6026                         this.pending--;
6027                         if ( !this.pending ) {
6028                                 this._removeClass( "ui-autocomplete-loading" );
6029                         }
6030                 }, this );
6031         },
6032 
6033         __response: function( content ) {
6034                 if ( content ) {
6035                         content = this._normalize( content );
6036                 }
6037                 this._trigger( "response", null, { content: content } );
6038                 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6039                         this._suggest( content );
6040                         this._trigger( "open" );
6041                 } else {
6042 
6043                         // use ._close() instead of .close() so we don't cancel future searches
6044                         this._close();
6045                 }
6046         },
6047 
6048         close: function( event ) {
6049                 this.cancelSearch = true;
6050                 this._close( event );
6051         },
6052 
6053         _close: function( event ) {
6054 
6055                 // Remove the handler that closes the menu on outside clicks
6056                 this._off( this.document, "mousedown" );
6057 
6058                 if ( this.menu.element.is( ":visible" ) ) {
6059                         this.menu.element.hide();
6060                         this.menu.blur();
6061                         this.isNewMenu = true;
6062                         this._trigger( "close", event );
6063                 }
6064         },
6065 
6066         _change: function( event ) {
6067                 if ( this.previous !== this._value() ) {
6068                         this._trigger( "change", event, { item: this.selectedItem } );
6069                 }
6070         },
6071 
6072         _normalize: function( items ) {
6073 
6074                 // assume all items have the right format when the first item is complete
6075                 if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6076                         return items;
6077                 }
6078                 return $.map( items, function( item ) {
6079                         if ( typeof item === "string" ) {
6080                                 return {
6081                                         label: item,
6082                                         value: item
6083                                 };
6084                         }
6085                         return $.extend( {}, item, {
6086                                 label: item.label || item.value,
6087                                 value: item.value || item.label
6088                         } );
6089                 } );
6090         },
6091 
6092         _suggest: function( items ) {
6093                 var ul = this.menu.element.empty();
6094                 this._renderMenu( ul, items );
6095                 this.isNewMenu = true;
6096                 this.menu.refresh();
6097 
6098                 // Size and position menu
6099                 ul.show();
6100                 this._resizeMenu();
6101                 ul.position( $.extend( {
6102                         of: this.element
6103                 }, this.options.position ) );
6104 
6105                 if ( this.options.autoFocus ) {
6106                         this.menu.next();
6107                 }
6108 
6109                 // Listen for interactions outside of the widget (#6642)
6110                 this._on( this.document, {
6111                         mousedown: "_closeOnClickOutside"
6112                 } );
6113         },
6114 
6115         _resizeMenu: function() {
6116                 var ul = this.menu.element;
6117                 ul.outerWidth( Math.max(
6118 
6119                         // Firefox wraps long text (possibly a rounding bug)
6120                         // so we add 1px to avoid the wrapping (#7513)
6121                         ul.width( "" ).outerWidth() + 1,
6122                         this.element.outerWidth()
6123                 ) );
6124         },
6125 
6126         _renderMenu: function( ul, items ) {
6127                 var that = this;
6128                 $.each( items, function( index, item ) {
6129                         that._renderItemData( ul, item );
6130                 } );
6131         },
6132 
6133         _renderItemData: function( ul, item ) {
6134                 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6135         },
6136 
6137         _renderItem: function( ul, item ) {
6138                 return $( "<li>" )
6139                         .append( $( "<div>" ).text( item.label ) )
6140                         .appendTo( ul );
6141         },
6142 
6143         _move: function( direction, event ) {
6144                 if ( !this.menu.element.is( ":visible" ) ) {
6145                         this.search( null, event );
6146                         return;
6147                 }
6148                 if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6149                                 this.menu.isLastItem() && /^next/.test( direction ) ) {
6150 
6151                         if ( !this.isMultiLine ) {
6152                                 this._value( this.term );
6153                         }
6154 
6155                         this.menu.blur();
6156                         return;
6157                 }
6158                 this.menu[ direction ]( event );
6159         },
6160 
6161         widget: function() {
6162                 return this.menu.element;
6163         },
6164 
6165         _value: function() {
6166                 return this.valueMethod.apply( this.element, arguments );
6167         },
6168 
6169         _keyEvent: function( keyEvent, event ) {
6170                 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6171                         this._move( keyEvent, event );
6172 
6173                         // Prevents moving cursor to beginning/end of the text field in some browsers
6174                         event.preventDefault();
6175                 }
6176         },
6177 
6178         // Support: Chrome <=50
6179         // We should be able to just use this.element.prop( "isContentEditable" )
6180         // but hidden elements always report false in Chrome.
6181         // https://code.google.com/p/chromium/issues/detail?id=313082
6182         _isContentEditable: function( element ) {
6183                 if ( !element.length ) {
6184                         return false;
6185                 }
6186 
6187                 var editable = element.prop( "contentEditable" );
6188 
6189                 if ( editable === "inherit" ) {
6190                   return this._isContentEditable( element.parent() );
6191                 }
6192 
6193                 return editable === "true";
6194         }
6195 } );
6196 
6197 $.extend( $.ui.autocomplete, {
6198         escapeRegex: function( value ) {
6199                 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6200         },
6201         filter: function( array, term ) {
6202                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6203                 return $.grep( array, function( value ) {
6204                         return matcher.test( value.label || value.value || value );
6205                 } );
6206         }
6207 } );
6208 
6209 // Live region extension, adding a `messages` option
6210 // NOTE: This is an experimental API. We are still investigating
6211 // a full solution for string manipulation and internationalization.
6212 $.widget( "ui.autocomplete", $.ui.autocomplete, {
6213         options: {
6214                 messages: {
6215                         noResults: "No search results.",
6216                         results: function( amount ) {
6217                                 return amount + ( amount > 1 ? " results are" : " result is" ) +
6218                                         " available, use up and down arrow keys to navigate.";
6219                         }
6220                 }
6221         },
6222 
6223         __response: function( content ) {
6224                 var message;
6225                 this._superApply( arguments );
6226                 if ( this.options.disabled || this.cancelSearch ) {
6227                         return;
6228                 }
6229                 if ( content && content.length ) {
6230                         message = this.options.messages.results( content.length );
6231                 } else {
6232                         message = this.options.messages.noResults;
6233                 }
6234                 this.liveRegion.children().hide();
6235                 $( "<div>" ).text( message ).appendTo( this.liveRegion );
6236         }
6237 } );
6238 
6239 var widgetsAutocomplete = $.ui.autocomplete;
6240 
6241 
6242 /*!
6243  * jQuery UI Controlgroup 1.12.1
6244  * http://jqueryui.com
6245  *
6246  * Copyright jQuery Foundation and other contributors
6247  * Released under the MIT license.
6248  * http://jquery.org/license
6249  */
6250 
6251 //>>label: Controlgroup
6252 //>>group: Widgets
6253 //>>description: Visually groups form control widgets
6254 //>>docs: http://api.jqueryui.com/controlgroup/
6255 //>>demos: http://jqueryui.com/controlgroup/
6256 //>>css.structure: ../../themes/base/core.css
6257 //>>css.structure: ../../themes/base/controlgroup.css
6258 //>>css.theme: ../../themes/base/theme.css
6259 
6260 
6261 var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6262 
6263 var widgetsControlgroup = $.widget( "ui.controlgroup", {
6264         version: "1.12.1",
6265         defaultElement: "<div>",
6266         options: {
6267                 direction: "horizontal",
6268                 disabled: null,
6269                 onlyVisible: true,
6270                 items: {
6271                         "button": "input[type=button], input[type=submit], input[type=reset], button, a",
6272                         "controlgroupLabel": ".ui-controlgroup-label",
6273                         "checkboxradio": "input[type='checkbox'], input[type='radio']",
6274                         "selectmenu": "select",
6275                         "spinner": ".ui-spinner-input"
6276                 }
6277         },
6278 
6279         _create: function() {
6280                 this._enhance();
6281         },
6282 
6283         // To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6284         _enhance: function() {
6285                 this.element.attr( "role", "toolbar" );
6286                 this.refresh();
6287         },
6288 
6289         _destroy: function() {
6290                 this._callChildMethod( "destroy" );
6291                 this.childWidgets.removeData( "ui-controlgroup-data" );
6292                 this.element.removeAttr( "role" );
6293                 if ( this.options.items.controlgroupLabel ) {
6294                         this.element
6295                                 .find( this.options.items.controlgroupLabel )
6296                                 .find( ".ui-controlgroup-label-contents" )
6297                                 .contents().unwrap();
6298                 }
6299         },
6300 
6301         _initWidgets: function() {
6302                 var that = this,
6303                         childWidgets = [];
6304 
6305                 // First we iterate over each of the items options
6306                 $.each( this.options.items, function( widget, selector ) {
6307                         var labels;
6308                         var options = {};
6309 
6310                         // Make sure the widget has a selector set
6311                         if ( !selector ) {
6312                                 return;
6313                         }
6314 
6315                         if ( widget === "controlgroupLabel" ) {
6316                                 labels = that.element.find( selector );
6317                                 labels.each( function() {
6318                                         var element = $( this );
6319 
6320                                         if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6321                                                 return;
6322                                         }
6323                                         element.contents()
6324                                                 .wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6325                                 } );
6326                                 that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6327                                 childWidgets = childWidgets.concat( labels.get() );
6328                                 return;
6329                         }
6330 
6331                         // Make sure the widget actually exists
6332                         if ( !$.fn[ widget ] ) {
6333                                 return;
6334                         }
6335 
6336                         // We assume everything is in the middle to start because we can't determine
6337                         // first / last elements until all enhancments are done.
6338                         if ( that[ "_" + widget + "Options" ] ) {
6339                                 options = that[ "_" + widget + "Options" ]( "middle" );
6340                         } else {
6341                                 options = { classes: {} };
6342                         }
6343 
6344                         // Find instances of this widget inside controlgroup and init them
6345                         that.element
6346                                 .find( selector )
6347                                 .each( function() {
6348                                         var element = $( this );
6349                                         var instance = element[ widget ]( "instance" );
6350 
6351                                         // We need to clone the default options for this type of widget to avoid
6352                                         // polluting the variable options which has a wider scope than a single widget.
6353                                         var instanceOptions = $.widget.extend( {}, options );
6354 
6355                                         // If the button is the child of a spinner ignore it
6356                                         // TODO: Find a more generic solution
6357                                         if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6358                                                 return;
6359                                         }
6360 
6361                                         // Create the widget if it doesn't exist
6362                                         if ( !instance ) {
6363                                                 instance = element[ widget ]()[ widget ]( "instance" );
6364                                         }
6365                                         if ( instance ) {
6366                                                 instanceOptions.classes =
6367                                                         that._resolveClassesValues( instanceOptions.classes, instance );
6368                                         }
6369                                         element[ widget ]( instanceOptions );
6370 
6371                                         // Store an instance of the controlgroup to be able to reference
6372                                         // from the outermost element for changing options and refresh
6373                                         var widgetElement = element[ widget ]( "widget" );
6374                                         $.data( widgetElement[ 0 ], "ui-controlgroup-data",
6375                                                 instance ? instance : element[ widget ]( "instance" ) );
6376 
6377                                         childWidgets.push( widgetElement[ 0 ] );
6378                                 } );
6379                 } );
6380 
6381                 this.childWidgets = $( $.unique( childWidgets ) );
6382                 this._addClass( this.childWidgets, "ui-controlgroup-item" );
6383         },
6384 
6385         _callChildMethod: function( method ) {
6386                 this.childWidgets.each( function() {
6387                         var element = $( this ),
6388                                 data = element.data( "ui-controlgroup-data" );
6389                         if ( data && data[ method ] ) {
6390                                 data[ method ]();
6391                         }
6392                 } );
6393         },
6394 
6395         _updateCornerClass: function( element, position ) {
6396                 var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6397                 var add = this._buildSimpleOptions( position, "label" ).classes.label;
6398 
6399                 this._removeClass( element, null, remove );
6400                 this._addClass( element, null, add );
6401         },
6402 
6403         _buildSimpleOptions: function( position, key ) {
6404                 var direction = this.options.direction === "vertical";
6405                 var result = {
6406                         classes: {}
6407                 };
6408                 result.classes[ key ] = {
6409                         "middle": "",
6410                         "first": "ui-corner-" + ( direction ? "top" : "left" ),
6411                         "last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6412                         "only": "ui-corner-all"
6413                 }[ position ];
6414 
6415                 return result;
6416         },
6417 
6418         _spinnerOptions: function( position ) {
6419                 var options = this._buildSimpleOptions( position, "ui-spinner" );
6420 
6421                 options.classes[ "ui-spinner-up" ] = "";
6422                 options.classes[ "ui-spinner-down" ] = "";
6423 
6424                 return options;
6425         },
6426 
6427         _buttonOptions: function( position ) {
6428                 return this._buildSimpleOptions( position, "ui-button" );
6429         },
6430 
6431         _checkboxradioOptions: function( position ) {
6432                 return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6433         },
6434 
6435         _selectmenuOptions: function( position ) {
6436                 var direction = this.options.direction === "vertical";
6437                 return {
6438                         width: direction ? "auto" : false,
6439                         classes: {
6440                                 middle: {
6441                                         "ui-selectmenu-button-open": "",
6442                                         "ui-selectmenu-button-closed": ""
6443                                 },
6444                                 first: {
6445                                         "ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6446                                         "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6447                                 },
6448                                 last: {
6449                                         "ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6450                                         "ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6451                                 },
6452                                 only: {
6453                                         "ui-selectmenu-button-open": "ui-corner-top",
6454                                         "ui-selectmenu-button-closed": "ui-corner-all"
6455                                 }
6456 
6457                         }[ position ]
6458                 };
6459         },
6460 
6461         _resolveClassesValues: function( classes, instance ) {
6462                 var result = {};
6463                 $.each( classes, function( key ) {
6464                         var current = instance.options.classes[ key ] || "";
6465                         current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6466                         result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6467                 } );
6468                 return result;
6469         },
6470 
6471         _setOption: function( key, value ) {
6472                 if ( key === "direction" ) {
6473                         this._removeClass( "ui-controlgroup-" + this.options.direction );
6474                 }
6475 
6476                 this._super( key, value );
6477                 if ( key === "disabled" ) {
6478                         this._callChildMethod( value ? "disable" : "enable" );
6479                         return;
6480                 }
6481 
6482                 this.refresh();
6483         },
6484 
6485         refresh: function() {
6486                 var children,
6487                         that = this;
6488 
6489                 this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6490 
6491                 if ( this.options.direction === "horizontal" ) {
6492                         this._addClass( null, "ui-helper-clearfix" );
6493                 }
6494                 this._initWidgets();
6495 
6496                 children = this.childWidgets;
6497 
6498                 // We filter here because we need to track all childWidgets not just the visible ones
6499                 if ( this.options.onlyVisible ) {
6500                         children = children.filter( ":visible" );
6501                 }
6502 
6503                 if ( children.length ) {
6504 
6505                         // We do this last because we need to make sure all enhancment is done
6506                         // before determining first and last
6507                         $.each( [ "first", "last" ], function( index, value ) {
6508                                 var instance = children[ value ]().data( "ui-controlgroup-data" );
6509 
6510                                 if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6511                                         var options = that[ "_" + instance.widgetName + "Options" ](
6512                                                 children.length === 1 ? "only" : value
6513                                         );
6514                                         options.classes = that._resolveClassesValues( options.classes, instance );
6515                                         instance.element[ instance.widgetName ]( options );
6516                                 } else {
6517                                         that._updateCornerClass( children[ value ](), value );
6518                                 }
6519                         } );
6520 
6521                         // Finally call the refresh method on each of the child widgets.
6522                         this._callChildMethod( "refresh" );
6523                 }
6524         }
6525 } );
6526 
6527 /*!
6528  * jQuery UI Checkboxradio 1.12.1
6529  * http://jqueryui.com
6530  *
6531  * Copyright jQuery Foundation and other contributors
6532  * Released under the MIT license.
6533  * http://jquery.org/license
6534  */
6535 
6536 //>>label: Checkboxradio
6537 //>>group: Widgets
6538 //>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6539 //>>docs: http://api.jqueryui.com/checkboxradio/
6540 //>>demos: http://jqueryui.com/checkboxradio/
6541 //>>css.structure: ../../themes/base/core.css
6542 //>>css.structure: ../../themes/base/button.css
6543 //>>css.structure: ../../themes/base/checkboxradio.css
6544 //>>css.theme: ../../themes/base/theme.css
6545 
6546 
6547 
6548 $.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6549         version: "1.12.1",
6550         options: {
6551                 disabled: null,
6552                 label: null,
6553                 icon: true,
6554                 classes: {
6555                         "ui-checkboxradio-label": "ui-corner-all",
6556                         "ui-checkboxradio-icon": "ui-corner-all"
6557                 }
6558         },
6559 
6560         _getCreateOptions: function() {
6561                 var disabled, labels;
6562                 var that = this;
6563                 var options = this._super() || {};
6564 
6565                 // We read the type here, because it makes more sense to throw a element type error first,
6566                 // rather then the error for lack of a label. Often if its the wrong type, it
6567                 // won't have a label (e.g. calling on a div, btn, etc)
6568                 this._readType();
6569 
6570                 labels = this.element.labels();
6571 
6572                 // If there are multiple labels, use the last one
6573                 this.label = $( labels[ labels.length - 1 ] );
6574                 if ( !this.label.length ) {
6575                         $.error( "No label found for checkboxradio widget" );
6576                 }
6577 
6578                 this.originalLabel = "";
6579 
6580                 // We need to get the label text but this may also need to make sure it does not contain the
6581                 // input itself.
6582                 this.label.contents().not( this.element[ 0 ] ).each( function() {
6583 
6584                         // The label contents could be text, html, or a mix. We concat each element to get a
6585                         // string representation of the label, without the input as part of it.
6586                         that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6587                 } );
6588 
6589                 // Set the label option if we found label text
6590                 if ( this.originalLabel ) {
6591                         options.label = this.originalLabel;
6592                 }
6593 
6594                 disabled = this.element[ 0 ].disabled;
6595                 if ( disabled != null ) {
6596                         options.disabled = disabled;
6597                 }
6598                 return options;
6599         },
6600 
6601         _create: function() {
6602                 var checked = this.element[ 0 ].checked;
6603 
6604                 this._bindFormResetHandler();
6605 
6606                 if ( this.options.disabled == null ) {
6607                         this.options.disabled = this.element[ 0 ].disabled;
6608                 }
6609 
6610                 this._setOption( "disabled", this.options.disabled );
6611                 this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6612                 this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6613 
6614                 if ( this.type === "radio" ) {
6615                         this._addClass( this.label, "ui-checkboxradio-radio-label" );
6616                 }
6617 
6618                 if ( this.options.label && this.options.label !== this.originalLabel ) {
6619                         this._updateLabel();
6620                 } else if ( this.originalLabel ) {
6621                         this.options.label = this.originalLabel;
6622                 }
6623 
6624                 this._enhance();
6625 
6626                 if ( checked ) {
6627                         this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6628                         if ( this.icon ) {
6629                                 this._addClass( this.icon, null, "ui-state-hover" );
6630                         }
6631                 }
6632 
6633                 this._on( {
6634                         change: "_toggleClasses",
6635                         focus: function() {
6636                                 this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6637                         },
6638                         blur: function() {
6639                                 this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6640                         }
6641                 } );
6642         },
6643 
6644         _readType: function() {
6645                 var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6646                 this.type = this.element[ 0 ].type;
6647                 if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6648                         $.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6649                                 " and element.type=" + this.type );
6650                 }
6651         },
6652 
6653         // Support jQuery Mobile enhanced option
6654         _enhance: function() {
6655                 this._updateIcon( this.element[ 0 ].checked );
6656         },
6657 
6658         widget: function() {
6659                 return this.label;
6660         },
6661 
6662         _getRadioGroup: function() {
6663                 var group;
6664                 var name = this.element[ 0 ].name;
6665                 var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6666 
6667                 if ( !name ) {
6668                         return $( [] );
6669                 }
6670 
6671                 if ( this.form.length ) {
6672                         group = $( this.form[ 0 ].elements ).filter( nameSelector );
6673                 } else {
6674 
6675                         // Not inside a form, check all inputs that also are not inside a form
6676                         group = $( nameSelector ).filter( function() {
6677                                 return $( this ).form().length === 0;
6678                         } );
6679                 }
6680 
6681                 return group.not( this.element );
6682         },
6683 
6684         _toggleClasses: function() {
6685                 var checked = this.element[ 0 ].checked;
6686                 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6687 
6688                 if ( this.options.icon && this.type === "checkbox" ) {
6689                         this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6690                                 ._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6691                 }
6692 
6693                 if ( this.type === "radio" ) {
6694                         this._getRadioGroup()
6695                                 .each( function() {
6696                                         var instance = $( this ).checkboxradio( "instance" );
6697 
6698                                         if ( instance ) {
6699                                                 instance._removeClass( instance.label,
6700                                                         "ui-checkboxradio-checked", "ui-state-active" );
6701                                         }
6702                                 } );
6703                 }
6704         },
6705 
6706         _destroy: function() {
6707                 this._unbindFormResetHandler();
6708 
6709                 if ( this.icon ) {
6710                         this.icon.remove();
6711                         this.iconSpace.remove();
6712                 }
6713         },
6714 
6715         _setOption: function( key, value ) {
6716 
6717                 // We don't allow the value to be set to nothing
6718                 if ( key === "label" && !value ) {
6719                         return;
6720                 }
6721 
6722                 this._super( key, value );
6723 
6724                 if ( key === "disabled" ) {
6725                         this._toggleClass( this.label, null, "ui-state-disabled", value );
6726                         this.element[ 0 ].disabled = value;
6727 
6728                         // Don't refresh when setting disabled
6729                         return;
6730                 }
6731                 this.refresh();
6732         },
6733 
6734         _updateIcon: function( checked ) {
6735                 var toAdd = "ui-icon ui-icon-background ";
6736 
6737                 if ( this.options.icon ) {
6738                         if ( !this.icon ) {
6739                                 this.icon = $( "<span>" );
6740                                 this.iconSpace = $( "<span> </span>" );
6741                                 this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6742                         }
6743 
6744                         if ( this.type === "checkbox" ) {
6745                                 toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6746                                 this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6747                         } else {
6748                                 toAdd += "ui-icon-blank";
6749                         }
6750                         this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6751                         if ( !checked ) {
6752                                 this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6753                         }
6754                         this.icon.prependTo( this.label ).after( this.iconSpace );
6755                 } else if ( this.icon !== undefined ) {
6756                         this.icon.remove();
6757                         this.iconSpace.remove();
6758                         delete this.icon;
6759                 }
6760         },
6761 
6762         _updateLabel: function() {
6763 
6764                 // Remove the contents of the label ( minus the icon, icon space, and input )
6765                 var contents = this.label.contents().not( this.element[ 0 ] );
6766                 if ( this.icon ) {
6767                         contents = contents.not( this.icon[ 0 ] );
6768                 }
6769                 if ( this.iconSpace ) {
6770                         contents = contents.not( this.iconSpace[ 0 ] );
6771                 }
6772                 contents.remove();
6773 
6774                 this.label.append( this.options.label );
6775         },
6776 
6777         refresh: function() {
6778                 var checked = this.element[ 0 ].checked,
6779                         isDisabled = this.element[ 0 ].disabled;
6780 
6781                 this._updateIcon( checked );
6782                 this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6783                 if ( this.options.label !== null ) {
6784                         this._updateLabel();
6785                 }
6786 
6787                 if ( isDisabled !== this.options.disabled ) {
6788                         this._setOptions( { "disabled": isDisabled } );
6789                 }
6790         }
6791 
6792 } ] );
6793 
6794 var widgetsCheckboxradio = $.ui.checkboxradio;
6795 
6796 
6797 /*!
6798  * jQuery UI Button 1.12.1
6799  * http://jqueryui.com
6800  *
6801  * Copyright jQuery Foundation and other contributors
6802  * Released under the MIT license.
6803  * http://jquery.org/license
6804  */
6805 
6806 //>>label: Button
6807 //>>group: Widgets
6808 //>>description: Enhances a form with themeable buttons.
6809 //>>docs: http://api.jqueryui.com/button/
6810 //>>demos: http://jqueryui.com/button/
6811 //>>css.structure: ../../themes/base/core.css
6812 //>>css.structure: ../../themes/base/button.css
6813 //>>css.theme: ../../themes/base/theme.css
6814 
6815 
6816 
6817 $.widget( "ui.button", {
6818         version: "1.12.1",
6819         defaultElement: "<button>",
6820         options: {
6821                 classes: {
6822                         "ui-button": "ui-corner-all"
6823                 },
6824                 disabled: null,
6825                 icon: null,
6826                 iconPosition: "beginning",
6827                 label: null,
6828                 showLabel: true
6829         },
6830 
6831         _getCreateOptions: function() {
6832                 var disabled,
6833 
6834                         // This is to support cases like in jQuery Mobile where the base widget does have
6835                         // an implementation of _getCreateOptions
6836                         options = this._super() || {};
6837 
6838                 this.isInput = this.element.is( "input" );
6839 
6840                 disabled = this.element[ 0 ].disabled;
6841                 if ( disabled != null ) {
6842                         options.disabled = disabled;
6843                 }
6844 
6845                 this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6846                 if ( this.originalLabel ) {
6847                         options.label = this.originalLabel;
6848                 }
6849 
6850                 return options;
6851         },
6852 
6853         _create: function() {
6854                 if ( !this.option.showLabel & !this.options.icon ) {
6855                         this.options.showLabel = true;
6856                 }
6857 
6858                 // We have to check the option again here even though we did in _getCreateOptions,
6859                 // because null may have been passed on init which would override what was set in
6860                 // _getCreateOptions
6861                 if ( this.options.disabled == null ) {
6862                         this.options.disabled = this.element[ 0 ].disabled || false;
6863                 }
6864 
6865                 this.hasTitle = !!this.element.attr( "title" );
6866 
6867                 // Check to see if the label needs to be set or if its already correct
6868                 if ( this.options.label && this.options.label !== this.originalLabel ) {
6869                         if ( this.isInput ) {
6870                                 this.element.val( this.options.label );
6871                         } else {
6872                                 this.element.html( this.options.label );
6873                         }
6874                 }
6875                 this._addClass( "ui-button", "ui-widget" );
6876                 this._setOption( "disabled", this.options.disabled );
6877                 this._enhance();
6878 
6879                 if ( this.element.is( "a" ) ) {
6880                         this._on( {
6881                                 "keyup": function( event ) {
6882                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
6883                                                 event.preventDefault();
6884 
6885                                                 // Support: PhantomJS <= 1.9, IE 8 Only
6886                                                 // If a native click is available use it so we actually cause navigation
6887                                                 // otherwise just trigger a click event
6888                                                 if ( this.element[ 0 ].click ) {
6889                                                         this.element[ 0 ].click();
6890                                                 } else {
6891                                                         this.element.trigger( "click" );
6892                                                 }
6893                                         }
6894                                 }
6895                         } );
6896                 }
6897         },
6898 
6899         _enhance: function() {
6900                 if ( !this.element.is( "button" ) ) {
6901                         this.element.attr( "role", "button" );
6902                 }
6903 
6904                 if ( this.options.icon ) {
6905                         this._updateIcon( "icon", this.options.icon );
6906                         this._updateTooltip();
6907                 }
6908         },
6909 
6910         _updateTooltip: function() {
6911                 this.title = this.element.attr( "title" );
6912 
6913                 if ( !this.options.showLabel && !this.title ) {
6914                         this.element.attr( "title", this.options.label );
6915                 }
6916         },
6917 
6918         _updateIcon: function( option, value ) {
6919                 var icon = option !== "iconPosition",
6920                         position = icon ? this.options.iconPosition : value,
6921                         displayBlock = position === "top" || position === "bottom";
6922 
6923                 // Create icon
6924                 if ( !this.icon ) {
6925                         this.icon = $( "<span>" );
6926 
6927                         this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6928 
6929                         if ( !this.options.showLabel ) {
6930                                 this._addClass( "ui-button-icon-only" );
6931                         }
6932                 } else if ( icon ) {
6933 
6934                         // If we are updating the icon remove the old icon class
6935                         this._removeClass( this.icon, null, this.options.icon );
6936                 }
6937 
6938                 // If we are updating the icon add the new icon class
6939                 if ( icon ) {
6940                         this._addClass( this.icon, null, value );
6941                 }
6942 
6943                 this._attachIcon( position );
6944 
6945                 // If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6946                 // the iconSpace if there is one.
6947                 if ( displayBlock ) {
6948                         this._addClass( this.icon, null, "ui-widget-icon-block" );
6949                         if ( this.iconSpace ) {
6950                                 this.iconSpace.remove();
6951                         }
6952                 } else {
6953 
6954                         // Position is beginning or end so remove the ui-widget-icon-block class and add the
6955                         // space if it does not exist
6956                         if ( !this.iconSpace ) {
6957                                 this.iconSpace = $( "<span> </span>" );
6958                                 this._addClass( this.iconSpace, "ui-button-icon-space" );
6959                         }
6960                         this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6961                         this._attachIconSpace( position );
6962                 }
6963         },
6964 
6965         _destroy: function() {
6966                 this.element.removeAttr( "role" );
6967 
6968                 if ( this.icon ) {
6969                         this.icon.remove();
6970                 }
6971                 if ( this.iconSpace ) {
6972                         this.iconSpace.remove();
6973                 }
6974                 if ( !this.hasTitle ) {
6975                         this.element.removeAttr( "title" );
6976                 }
6977         },
6978 
6979         _attachIconSpace: function( iconPosition ) {
6980                 this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6981         },
6982 
6983         _attachIcon: function( iconPosition ) {
6984                 this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6985         },
6986 
6987         _setOptions: function( options ) {
6988                 var newShowLabel = options.showLabel === undefined ?
6989                                 this.options.showLabel :
6990                                 options.showLabel,
6991                         newIcon = options.icon === undefined ? this.options.icon : options.icon;
6992 
6993                 if ( !newShowLabel && !newIcon ) {
6994                         options.showLabel = true;
6995                 }
6996                 this._super( options );
6997         },
6998 
6999         _setOption: function( key, value ) {
7000                 if ( key === "icon" ) {
7001                         if ( value ) {
7002                                 this._updateIcon( key, value );
7003                         } else if ( this.icon ) {
7004                                 this.icon.remove();
7005                                 if ( this.iconSpace ) {
7006                                         this.iconSpace.remove();
7007                                 }
7008                         }
7009                 }
7010 
7011                 if ( key === "iconPosition" ) {
7012                         this._updateIcon( key, value );
7013                 }
7014 
7015                 // Make sure we can't end up with a button that has neither text nor icon
7016                 if ( key === "showLabel" ) {
7017                                 this._toggleClass( "ui-button-icon-only", null, !value );
7018                                 this._updateTooltip();
7019                 }
7020 
7021                 if ( key === "label" ) {
7022                         if ( this.isInput ) {
7023                                 this.element.val( value );
7024                         } else {
7025 
7026                                 // If there is an icon, append it, else nothing then append the value
7027                                 // this avoids removal of the icon when setting label text
7028                                 this.element.html( value );
7029                                 if ( this.icon ) {
7030                                         this._attachIcon( this.options.iconPosition );
7031                                         this._attachIconSpace( this.options.iconPosition );
7032                                 }
7033                         }
7034                 }
7035 
7036                 this._super( key, value );
7037 
7038                 if ( key === "disabled" ) {
7039                         this._toggleClass( null, "ui-state-disabled", value );
7040                         this.element[ 0 ].disabled = value;
7041                         if ( value ) {
7042                                 this.element.blur();
7043                         }
7044                 }
7045         },
7046 
7047         refresh: function() {
7048 
7049                 // Make sure to only check disabled if its an element that supports this otherwise
7050                 // check for the disabled class to determine state
7051                 var isDisabled = this.element.is( "input, button" ) ?
7052                         this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7053 
7054                 if ( isDisabled !== this.options.disabled ) {
7055                         this._setOptions( { disabled: isDisabled } );
7056                 }
7057 
7058                 this._updateTooltip();
7059         }
7060 } );
7061 
7062 // DEPRECATED
7063 if ( $.uiBackCompat !== false ) {
7064 
7065         // Text and Icons options
7066         $.widget( "ui.button", $.ui.button, {
7067                 options: {
7068                         text: true,
7069                         icons: {
7070                                 primary: null,
7071                                 secondary: null
7072                         }
7073                 },
7074 
7075                 _create: function() {
7076                         if ( this.options.showLabel && !this.options.text ) {
7077                                 this.options.showLabel = this.options.text;
7078                         }
7079                         if ( !this.options.showLabel && this.options.text ) {
7080                                 this.options.text = this.options.showLabel;
7081                         }
7082                         if ( !this.options.icon && ( this.options.icons.primary ||
7083                                         this.options.icons.secondary ) ) {
7084                                 if ( this.options.icons.primary ) {
7085                                         this.options.icon = this.options.icons.primary;
7086                                 } else {
7087                                         this.options.icon = this.options.icons.secondary;
7088                                         this.options.iconPosition = "end";
7089                                 }
7090                         } else if ( this.options.icon ) {
7091                                 this.options.icons.primary = this.options.icon;
7092                         }
7093                         this._super();
7094                 },
7095 
7096                 _setOption: function( key, value ) {
7097                         if ( key === "text" ) {
7098                                 this._super( "showLabel", value );
7099                                 return;
7100                         }
7101                         if ( key === "showLabel" ) {
7102                                 this.options.text = value;
7103                         }
7104                         if ( key === "icon" ) {
7105                                 this.options.icons.primary = value;
7106                         }
7107                         if ( key === "icons" ) {
7108                                 if ( value.primary ) {
7109                                         this._super( "icon", value.primary );
7110                                         this._super( "iconPosition", "beginning" );
7111                                 } else if ( value.secondary ) {
7112                                         this._super( "icon", value.secondary );
7113                                         this._super( "iconPosition", "end" );
7114                                 }
7115                         }
7116                         this._superApply( arguments );
7117                 }
7118         } );
7119 
7120         $.fn.button = ( function( orig ) {
7121                 return function() {
7122                         if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7123                                         ( this.length && this[ 0 ].tagName === "INPUT" && (
7124                                                 this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7125                                         ) ) ) {
7126                                 return orig.apply( this, arguments );
7127                         }
7128                         if ( !$.ui.checkboxradio ) {
7129                                 $.error( "Checkboxradio widget missing" );
7130                         }
7131                         if ( arguments.length === 0 ) {
7132                                 return this.checkboxradio( {
7133                                         "icon": false
7134                                 } );
7135                         }
7136                         return this.checkboxradio.apply( this, arguments );
7137                 };
7138         } )( $.fn.button );
7139 
7140         $.fn.buttonset = function() {
7141                 if ( !$.ui.controlgroup ) {
7142                         $.error( "Controlgroup widget missing" );
7143                 }
7144                 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7145                         return this.controlgroup.apply( this,
7146                                 [ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7147                 }
7148                 if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7149                         return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7150                 }
7151                 if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7152                         arguments[ 0 ].items = {
7153                                 button: arguments[ 0 ].items
7154                         };
7155                 }
7156                 return this.controlgroup.apply( this, arguments );
7157         };
7158 }
7159 
7160 var widgetsButton = $.ui.button;
7161 
7162 
7163 // jscs:disable maximumLineLength
7164 /* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7165 /*!
7166  * jQuery UI Datepicker 1.12.1
7167  * http://jqueryui.com
7168  *
7169  * Copyright jQuery Foundation and other contributors
7170  * Released under the MIT license.
7171  * http://jquery.org/license
7172  */
7173 
7174 //>>label: Datepicker
7175 //>>group: Widgets
7176 //>>description: Displays a calendar from an input or inline for selecting dates.
7177 //>>docs: http://api.jqueryui.com/datepicker/
7178 //>>demos: http://jqueryui.com/datepicker/
7179 //>>css.structure: ../../themes/base/core.css
7180 //>>css.structure: ../../themes/base/datepicker.css
7181 //>>css.theme: ../../themes/base/theme.css
7182 
7183 
7184 
7185 $.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7186 
7187 var datepicker_instActive;
7188 
7189 function datepicker_getZindex( elem ) {
7190         var position, value;
7191         while ( elem.length && elem[ 0 ] !== document ) {
7192 
7193                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
7194                 // This makes behavior of this function consistent across browsers
7195                 // WebKit always returns auto if the element is positioned
7196                 position = elem.css( "position" );
7197                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7198 
7199                         // IE returns 0 when zIndex is not specified
7200                         // other browsers return a string
7201                         // we ignore the case of nested elements with an explicit value of 0
7202                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7203                         value = parseInt( elem.css( "zIndex" ), 10 );
7204                         if ( !isNaN( value ) && value !== 0 ) {
7205                                 return value;
7206                         }
7207                 }
7208                 elem = elem.parent();
7209         }
7210 
7211         return 0;
7212 }
7213 /* Date picker manager.
7214    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7215    Settings for (groups of) date pickers are maintained in an instance object,
7216    allowing multiple different settings on the same page. */
7217 
7218 function Datepicker() {
7219         this._curInst = null; // The current instance in use
7220         this._keyEvent = false; // If the last event was a key event
7221         this._disabledInputs = []; // List of date picker inputs that have been disabled
7222         this._datepickerShowing = false; // True if the popup picker is showing , false if not
7223         this._inDialog = false; // True if showing within a "dialog", false if not
7224         this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7225         this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7226         this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7227         this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7228         this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7229         this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7230         this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7231         this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7232         this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7233         this.regional = []; // Available regional settings, indexed by language code
7234         this.regional[ "" ] = { // Default regional settings
7235                 closeText: "Done", // Display text for close link
7236                 prevText: "Prev", // Display text for previous month link
7237                 nextText: "Next", // Display text for next month link
7238                 currentText: "Today", // Display text for current month link
7239                 monthNames: [ "January","February","March","April","May","June",
7240                         "July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7241                 monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7242                 dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7243                 dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7244                 dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7245                 weekHeader: "Wk", // Column header for week of the year
7246                 dateFormat: "mm/dd/yy", // See format options on parseDate
7247                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7248                 isRTL: false, // True if right-to-left language, false if left-to-right
7249                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7250                 yearSuffix: "" // Additional text to append to the year in the month headers
7251         };
7252         this._defaults = { // Global defaults for all the date picker instances
7253                 showOn: "focus", // "focus" for popup on focus,
7254                         // "button" for trigger button, or "both" for either
7255                 showAnim: "fadeIn", // Name of jQuery animation for popup
7256                 showOptions: {}, // Options for enhanced animations
7257                 defaultDate: null, // Used when field is blank: actual date,
7258                         // +/-number for offset from today, null for today
7259                 appendText: "", // Display text following the input box, e.g. showing the format
7260                 buttonText: "...", // Text for trigger button
7261                 buttonImage: "", // URL for trigger button image
7262                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7263                 hideIfNoPrevNext: false, // True to hide next/previous month links
7264                         // if not applicable, false to just disable them
7265                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7266                 gotoCurrent: false, // True if today link goes back to current selection instead
7267                 changeMonth: false, // True if month can be selected directly, false if only prev/next
7268                 changeYear: false, // True if year can be selected directly, false if only prev/next
7269                 yearRange: "c-10:c+10", // Range of years to display in drop-down,
7270                         // either relative to today's year (-nn:+nn), relative to currently displayed year
7271                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7272                 showOtherMonths: false, // True to show dates in other months, false to leave blank
7273                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7274                 showWeek: false, // True to show week of the year, false to not show it
7275                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7276                         // takes a Date and returns the number of the week for it
7277                 shortYearCutoff: "+10", // Short year values < this are in the current century,
7278                         // > this are in the previous century,
7279                         // string value starting with "+" for current year + value
7280                 minDate: null, // The earliest selectable date, or null for no limit
7281                 maxDate: null, // The latest selectable date, or null for no limit
7282                 duration: "fast", // Duration of display/closure
7283                 beforeShowDay: null, // Function that takes a date and returns an array with
7284                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7285                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7286                 beforeShow: null, // Function that takes an input field and
7287                         // returns a set of custom settings for the date picker
7288                 onSelect: null, // Define a callback function when a date is selected
7289                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
7290                 onClose: null, // Define a callback function when the datepicker is closed
7291                 numberOfMonths: 1, // Number of months to show at a time
7292                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7293                 stepMonths: 1, // Number of months to step back/forward
7294                 stepBigMonths: 12, // Number of months to step back/forward for the big links
7295                 altField: "", // Selector for an alternate field to store selected dates into
7296                 altFormat: "", // The date format to use for the alternate field
7297                 constrainInput: true, // The input is constrained by the current date format
7298                 showButtonPanel: false, // True to show button panel, false to not show it
7299                 autoSize: false, // True to size the input for the date format, false to leave as is
7300                 disabled: false // The initial disabled state
7301         };
7302         $.extend( this._defaults, this.regional[ "" ] );
7303         this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7304         this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7305         this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7306 }
7307 
7308 $.extend( Datepicker.prototype, {
7309         /* Class name added to elements to indicate already configured with a date picker. */
7310         markerClassName: "hasDatepicker",
7311 
7312         //Keep track of the maximum number of rows displayed (see #7043)
7313         maxRows: 4,
7314 
7315         // TODO rename to "widget" when switching to widget factory
7316         _widgetDatepicker: function() {
7317                 return this.dpDiv;
7318         },
7319 
7320         /* Override the default settings for all instances of the date picker.
7321          * @param  settings  object - the new settings to use as defaults (anonymous object)
7322          * @return the manager object
7323          */
7324         setDefaults: function( settings ) {
7325                 datepicker_extendRemove( this._defaults, settings || {} );
7326                 return this;
7327         },
7328 
7329         /* Attach the date picker to a jQuery selection.
7330          * @param  target       element - the target input field or division or span
7331          * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7332          */
7333         _attachDatepicker: function( target, settings ) {
7334                 var nodeName, inline, inst;
7335                 nodeName = target.nodeName.toLowerCase();
7336                 inline = ( nodeName === "div" || nodeName === "span" );
7337                 if ( !target.id ) {
7338                         this.uuid += 1;
7339                         target.id = "dp" + this.uuid;
7340                 }
7341                 inst = this._newInst( $( target ), inline );
7342                 inst.settings = $.extend( {}, settings || {} );
7343                 if ( nodeName === "input" ) {
7344                         this._connectDatepicker( target, inst );
7345                 } else if ( inline ) {
7346                         this._inlineDatepicker( target, inst );
7347                 }
7348         },
7349 
7350         /* Create a new instance object. */
7351         _newInst: function( target, inline ) {
7352                 var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7353                 return { id: id, input: target, // associated target
7354                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7355                         drawMonth: 0, drawYear: 0, // month being drawn
7356                         inline: inline, // is datepicker inline or not
7357                         dpDiv: ( !inline ? this.dpDiv : // presentation div
7358                         datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7359         },
7360 
7361         /* Attach the date picker to an input field. */
7362         _connectDatepicker: function( target, inst ) {
7363                 var input = $( target );
7364                 inst.append = $( [] );
7365                 inst.trigger = $( [] );
7366                 if ( input.hasClass( this.markerClassName ) ) {
7367                         return;
7368                 }
7369                 this._attachments( input, inst );
7370                 input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7371                         on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7372                 this._autoSize( inst );
7373                 $.data( target, "datepicker", inst );
7374 
7375                 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7376                 if ( inst.settings.disabled ) {
7377                         this._disableDatepicker( target );
7378                 }
7379         },
7380 
7381         /* Make attachments based on settings. */
7382         _attachments: function( input, inst ) {
7383                 var showOn, buttonText, buttonImage,
7384                         appendText = this._get( inst, "appendText" ),
7385                         isRTL = this._get( inst, "isRTL" );
7386 
7387                 if ( inst.append ) {
7388                         inst.append.remove();
7389                 }
7390                 if ( appendText ) {
7391                         inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7392                         input[ isRTL ? "before" : "after" ]( inst.append );
7393                 }
7394 
7395                 input.off( "focus", this._showDatepicker );
7396 
7397                 if ( inst.trigger ) {
7398                         inst.trigger.remove();
7399                 }
7400 
7401                 showOn = this._get( inst, "showOn" );
7402                 if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7403                         input.on( "focus", this._showDatepicker );
7404                 }
7405                 if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7406                         buttonText = this._get( inst, "buttonText" );
7407                         buttonImage = this._get( inst, "buttonImage" );
7408                         inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7409                                 $( "<img/>" ).addClass( this._triggerClass ).
7410                                         attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7411                                 $( "<button type='button'></button>" ).addClass( this._triggerClass ).
7412                                         html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7413                                         { src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7414                         input[ isRTL ? "before" : "after" ]( inst.trigger );
7415                         inst.trigger.on( "click", function() {
7416                                 if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7417                                         $.datepicker._hideDatepicker();
7418                                 } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7419                                         $.datepicker._hideDatepicker();
7420                                         $.datepicker._showDatepicker( input[ 0 ] );
7421                                 } else {
7422                                         $.datepicker._showDatepicker( input[ 0 ] );
7423                                 }
7424                                 return false;
7425                         } );
7426                 }
7427         },
7428 
7429         /* Apply the maximum length for the date format. */
7430         _autoSize: function( inst ) {
7431                 if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7432                         var findMax, max, maxI, i,
7433                                 date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7434                                 dateFormat = this._get( inst, "dateFormat" );
7435 
7436                         if ( dateFormat.match( /[DM]/ ) ) {
7437                                 findMax = function( names ) {
7438                                         max = 0;
7439                                         maxI = 0;
7440                                         for ( i = 0; i < names.length; i++ ) {
7441                                                 if ( names[ i ].length > max ) {
7442                                                         max = names[ i ].length;
7443                                                         maxI = i;
7444                                                 }
7445                                         }
7446                                         return maxI;
7447                                 };
7448                                 date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7449                                         "monthNames" : "monthNamesShort" ) ) ) );
7450                                 date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7451                                         "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7452                         }
7453                         inst.input.attr( "size", this._formatDate( inst, date ).length );
7454                 }
7455         },
7456 
7457         /* Attach an inline date picker to a div. */
7458         _inlineDatepicker: function( target, inst ) {
7459                 var divSpan = $( target );
7460                 if ( divSpan.hasClass( this.markerClassName ) ) {
7461                         return;
7462                 }
7463                 divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7464                 $.data( target, "datepicker", inst );
7465                 this._setDate( inst, this._getDefaultDate( inst ), true );
7466                 this._updateDatepicker( inst );
7467                 this._updateAlternate( inst );
7468 
7469                 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7470                 if ( inst.settings.disabled ) {
7471                         this._disableDatepicker( target );
7472                 }
7473 
7474                 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7475                 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7476                 inst.dpDiv.css( "display", "block" );
7477         },
7478 
7479         /* Pop-up the date picker in a "dialog" box.
7480          * @param  input element - ignored
7481          * @param  date string or Date - the initial date to display
7482          * @param  onSelect  function - the function to call when a date is selected
7483          * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7484          * @param  pos int[2] - coordinates for the dialog's position within the screen or
7485          *                                      event - with x/y coordinates or
7486          *                                      leave empty for default (screen centre)
7487          * @return the manager object
7488          */
7489         _dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7490                 var id, browserWidth, browserHeight, scrollX, scrollY,
7491                         inst = this._dialogInst; // internal instance
7492 
7493                 if ( !inst ) {
7494                         this.uuid += 1;
7495                         id = "dp" + this.uuid;
7496                         this._dialogInput = $( "<input type='text' id='" + id +
7497                                 "' style='position: absolute; top: -100px; width: 0px;'/>" );
7498                         this._dialogInput.on( "keydown", this._doKeyDown );
7499                         $( "body" ).append( this._dialogInput );
7500                         inst = this._dialogInst = this._newInst( this._dialogInput, false );
7501                         inst.settings = {};
7502                         $.data( this._dialogInput[ 0 ], "datepicker", inst );
7503                 }
7504                 datepicker_extendRemove( inst.settings, settings || {} );
7505                 date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7506                 this._dialogInput.val( date );
7507 
7508                 this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7509                 if ( !this._pos ) {
7510                         browserWidth = document.documentElement.clientWidth;
7511                         browserHeight = document.documentElement.clientHeight;
7512                         scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7513                         scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7514                         this._pos = // should use actual width/height below
7515                                 [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7516                 }
7517 
7518                 // Move input on screen for focus, but hidden behind dialog
7519                 this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7520                 inst.settings.onSelect = onSelect;
7521                 this._inDialog = true;
7522                 this.dpDiv.addClass( this._dialogClass );
7523                 this._showDatepicker( this._dialogInput[ 0 ] );
7524                 if ( $.blockUI ) {
7525                         $.blockUI( this.dpDiv );
7526                 }
7527                 $.data( this._dialogInput[ 0 ], "datepicker", inst );
7528                 return this;
7529         },
7530 
7531         /* Detach a datepicker from its control.
7532          * @param  target       element - the target input field or division or span
7533          */
7534         _destroyDatepicker: function( target ) {
7535                 var nodeName,
7536                         $target = $( target ),
7537                         inst = $.data( target, "datepicker" );
7538 
7539                 if ( !$target.hasClass( this.markerClassName ) ) {
7540                         return;
7541                 }
7542 
7543                 nodeName = target.nodeName.toLowerCase();
7544                 $.removeData( target, "datepicker" );
7545                 if ( nodeName === "input" ) {
7546                         inst.append.remove();
7547                         inst.trigger.remove();
7548                         $target.removeClass( this.markerClassName ).
7549                                 off( "focus", this._showDatepicker ).
7550                                 off( "keydown", this._doKeyDown ).
7551                                 off( "keypress", this._doKeyPress ).
7552                                 off( "keyup", this._doKeyUp );
7553                 } else if ( nodeName === "div" || nodeName === "span" ) {
7554                         $target.removeClass( this.markerClassName ).empty();
7555                 }
7556 
7557                 if ( datepicker_instActive === inst ) {
7558                         datepicker_instActive = null;
7559                 }
7560         },
7561 
7562         /* Enable the date picker to a jQuery selection.
7563          * @param  target       element - the target input field or division or span
7564          */
7565         _enableDatepicker: function( target ) {
7566                 var nodeName, inline,
7567                         $target = $( target ),
7568                         inst = $.data( target, "datepicker" );
7569 
7570                 if ( !$target.hasClass( this.markerClassName ) ) {
7571                         return;
7572                 }
7573 
7574                 nodeName = target.nodeName.toLowerCase();
7575                 if ( nodeName === "input" ) {
7576                         target.disabled = false;
7577                         inst.trigger.filter( "button" ).
7578                                 each( function() { this.disabled = false; } ).end().
7579                                 filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7580                 } else if ( nodeName === "div" || nodeName === "span" ) {
7581                         inline = $target.children( "." + this._inlineClass );
7582                         inline.children().removeClass( "ui-state-disabled" );
7583                         inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7584                                 prop( "disabled", false );
7585                 }
7586                 this._disabledInputs = $.map( this._disabledInputs,
7587                         function( value ) { return ( value === target ? null : value ); } ); // delete entry
7588         },
7589 
7590         /* Disable the date picker to a jQuery selection.
7591          * @param  target       element - the target input field or division or span
7592          */
7593         _disableDatepicker: function( target ) {
7594                 var nodeName, inline,
7595                         $target = $( target ),
7596                         inst = $.data( target, "datepicker" );
7597 
7598                 if ( !$target.hasClass( this.markerClassName ) ) {
7599                         return;
7600                 }
7601 
7602                 nodeName = target.nodeName.toLowerCase();
7603                 if ( nodeName === "input" ) {
7604                         target.disabled = true;
7605                         inst.trigger.filter( "button" ).
7606                                 each( function() { this.disabled = true; } ).end().
7607                                 filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7608                 } else if ( nodeName === "div" || nodeName === "span" ) {
7609                         inline = $target.children( "." + this._inlineClass );
7610                         inline.children().addClass( "ui-state-disabled" );
7611                         inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7612                                 prop( "disabled", true );
7613                 }
7614                 this._disabledInputs = $.map( this._disabledInputs,
7615                         function( value ) { return ( value === target ? null : value ); } ); // delete entry
7616                 this._disabledInputs[ this._disabledInputs.length ] = target;
7617         },
7618 
7619         /* Is the first field in a jQuery collection disabled as a datepicker?
7620          * @param  target       element - the target input field or division or span
7621          * @return boolean - true if disabled, false if enabled
7622          */
7623         _isDisabledDatepicker: function( target ) {
7624                 if ( !target ) {
7625                         return false;
7626                 }
7627                 for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7628                         if ( this._disabledInputs[ i ] === target ) {
7629                                 return true;
7630                         }
7631                 }
7632                 return false;
7633         },
7634 
7635         /* Retrieve the instance data for the target control.
7636          * @param  target  element - the target input field or division or span
7637          * @return  object - the associated instance data
7638          * @throws  error if a jQuery problem getting data
7639          */
7640         _getInst: function( target ) {
7641                 try {
7642                         return $.data( target, "datepicker" );
7643                 }
7644                 catch ( err ) {
7645                         throw "Missing instance data for this datepicker";
7646                 }
7647         },
7648 
7649         /* Update or retrieve the settings for a date picker attached to an input field or division.
7650          * @param  target  element - the target input field or division or span
7651          * @param  name object - the new settings to update or
7652          *                              string - the name of the setting to change or retrieve,
7653          *                              when retrieving also "all" for all instance settings or
7654          *                              "defaults" for all global defaults
7655          * @param  value   any - the new value for the setting
7656          *                              (omit if above is an object or to retrieve a value)
7657          */
7658         _optionDatepicker: function( target, name, value ) {
7659                 var settings, date, minDate, maxDate,
7660                         inst = this._getInst( target );
7661 
7662                 if ( arguments.length === 2 && typeof name === "string" ) {
7663                         return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7664                                 ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7665                                 this._get( inst, name ) ) : null ) );
7666                 }
7667 
7668                 settings = name || {};
7669                 if ( typeof name === "string" ) {
7670                         settings = {};
7671                         settings[ name ] = value;
7672                 }
7673 
7674                 if ( inst ) {
7675                         if ( this._curInst === inst ) {
7676                                 this._hideDatepicker();
7677                         }
7678 
7679                         date = this._getDateDatepicker( target, true );
7680                         minDate = this._getMinMaxDate( inst, "min" );
7681                         maxDate = this._getMinMaxDate( inst, "max" );
7682                         datepicker_extendRemove( inst.settings, settings );
7683 
7684                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685                         if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7686                                 inst.settings.minDate = this._formatDate( inst, minDate );
7687                         }
7688                         if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7689                                 inst.settings.maxDate = this._formatDate( inst, maxDate );
7690                         }
7691                         if ( "disabled" in settings ) {
7692                                 if ( settings.disabled ) {
7693                                         this._disableDatepicker( target );
7694                                 } else {
7695                                         this._enableDatepicker( target );
7696                                 }
7697                         }
7698                         this._attachments( $( target ), inst );
7699                         this._autoSize( inst );
7700                         this._setDate( inst, date );
7701                         this._updateAlternate( inst );
7702                         this._updateDatepicker( inst );
7703                 }
7704         },
7705 
7706         // Change method deprecated
7707         _changeDatepicker: function( target, name, value ) {
7708                 this._optionDatepicker( target, name, value );
7709         },
7710 
7711         /* Redraw the date picker attached to an input field or division.
7712          * @param  target  element - the target input field or division or span
7713          */
7714         _refreshDatepicker: function( target ) {
7715                 var inst = this._getInst( target );
7716                 if ( inst ) {
7717                         this._updateDatepicker( inst );
7718                 }
7719         },
7720 
7721         /* Set the dates for a jQuery selection.
7722          * @param  target element - the target input field or division or span
7723          * @param  date Date - the new date
7724          */
7725         _setDateDatepicker: function( target, date ) {
7726                 var inst = this._getInst( target );
7727                 if ( inst ) {
7728                         this._setDate( inst, date );
7729                         this._updateDatepicker( inst );
7730                         this._updateAlternate( inst );
7731                 }
7732         },
7733 
7734         /* Get the date(s) for the first entry in a jQuery selection.
7735          * @param  target element - the target input field or division or span
7736          * @param  noDefault boolean - true if no default date is to be used
7737          * @return Date - the current date
7738          */
7739         _getDateDatepicker: function( target, noDefault ) {
7740                 var inst = this._getInst( target );
7741                 if ( inst && !inst.inline ) {
7742                         this._setDateFromField( inst, noDefault );
7743                 }
7744                 return ( inst ? this._getDate( inst ) : null );
7745         },
7746 
7747         /* Handle keystrokes. */
7748         _doKeyDown: function( event ) {
7749                 var onSelect, dateStr, sel,
7750                         inst = $.datepicker._getInst( event.target ),
7751                         handled = true,
7752                         isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7753 
7754                 inst._keyEvent = true;
7755                 if ( $.datepicker._datepickerShowing ) {
7756                         switch ( event.keyCode ) {
7757                                 case 9: $.datepicker._hideDatepicker();
7758                                                 handled = false;
7759                                                 break; // hide on tab out
7760                                 case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7761                                                                         $.datepicker._currentClass + ")", inst.dpDiv );
7762                                                 if ( sel[ 0 ] ) {
7763                                                         $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7764                                                 }
7765 
7766                                                 onSelect = $.datepicker._get( inst, "onSelect" );
7767                                                 if ( onSelect ) {
7768                                                         dateStr = $.datepicker._formatDate( inst );
7769 
7770                                                         // Trigger custom callback
7771                                                         onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7772                                                 } else {
7773                                                         $.datepicker._hideDatepicker();
7774                                                 }
7775 
7776                                                 return false; // don't submit the form
7777                                 case 27: $.datepicker._hideDatepicker();
7778                                                 break; // hide on escape
7779                                 case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7780                                                         -$.datepicker._get( inst, "stepBigMonths" ) :
7781                                                         -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7782                                                 break; // previous month/year on page up/+ ctrl
7783                                 case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7784                                                         +$.datepicker._get( inst, "stepBigMonths" ) :
7785                                                         +$.datepicker._get( inst, "stepMonths" ) ), "M" );
7786                                                 break; // next month/year on page down/+ ctrl
7787                                 case 35: if ( event.ctrlKey || event.metaKey ) {
7788                                                         $.datepicker._clearDate( event.target );
7789                                                 }
7790                                                 handled = event.ctrlKey || event.metaKey;
7791                                                 break; // clear on ctrl or command +end
7792                                 case 36: if ( event.ctrlKey || event.metaKey ) {
7793                                                         $.datepicker._gotoToday( event.target );
7794                                                 }
7795                                                 handled = event.ctrlKey || event.metaKey;
7796                                                 break; // current on ctrl or command +home
7797                                 case 37: if ( event.ctrlKey || event.metaKey ) {
7798                                                         $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7799                                                 }
7800                                                 handled = event.ctrlKey || event.metaKey;
7801 
7802                                                 // -1 day on ctrl or command +left
7803                                                 if ( event.originalEvent.altKey ) {
7804                                                         $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7805                                                                 -$.datepicker._get( inst, "stepBigMonths" ) :
7806                                                                 -$.datepicker._get( inst, "stepMonths" ) ), "M" );
7807                                                 }
7808 
7809                                                 // next month/year on alt +left on Mac
7810                                                 break;
7811                                 case 38: if ( event.ctrlKey || event.metaKey ) {
7812                                                         $.datepicker._adjustDate( event.target, -7, "D" );
7813                                                 }
7814                                                 handled = event.ctrlKey || event.metaKey;
7815                                                 break; // -1 week on ctrl or command +up
7816                                 case 39: if ( event.ctrlKey || event.metaKey ) {
7817                                                         $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7818                                                 }
7819                                                 handled = event.ctrlKey || event.metaKey;
7820 
7821                                                 // +1 day on ctrl or command +right
7822                                                 if ( event.originalEvent.altKey ) {
7823                                                         $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7824                                                                 +$.datepicker._get( inst, "stepBigMonths" ) :
7825                                                                 +$.datepicker._get( inst, "stepMonths" ) ), "M" );
7826                                                 }
7827 
7828                                                 // next month/year on alt +right
7829                                                 break;
7830                                 case 40: if ( event.ctrlKey || event.metaKey ) {
7831                                                         $.datepicker._adjustDate( event.target, +7, "D" );
7832                                                 }
7833                                                 handled = event.ctrlKey || event.metaKey;
7834                                                 break; // +1 week on ctrl or command +down
7835                                 default: handled = false;
7836                         }
7837                 } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7838                         $.datepicker._showDatepicker( this );
7839                 } else {
7840                         handled = false;
7841                 }
7842 
7843                 if ( handled ) {
7844                         event.preventDefault();
7845                         event.stopPropagation();
7846                 }
7847         },
7848 
7849         /* Filter entered characters - based on date format. */
7850         _doKeyPress: function( event ) {
7851                 var chars, chr,
7852                         inst = $.datepicker._getInst( event.target );
7853 
7854                 if ( $.datepicker._get( inst, "constrainInput" ) ) {
7855                         chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7856                         chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7857                         return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7858                 }
7859         },
7860 
7861         /* Synchronise manual entry and field/alternate field. */
7862         _doKeyUp: function( event ) {
7863                 var date,
7864                         inst = $.datepicker._getInst( event.target );
7865 
7866                 if ( inst.input.val() !== inst.lastVal ) {
7867                         try {
7868                                 date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7869                                         ( inst.input ? inst.input.val() : null ),
7870                                         $.datepicker._getFormatConfig( inst ) );
7871 
7872                                 if ( date ) { // only if valid
7873                                         $.datepicker._setDateFromField( inst );
7874                                         $.datepicker._updateAlternate( inst );
7875                                         $.datepicker._updateDatepicker( inst );
7876                                 }
7877                         }
7878                         catch ( err ) {
7879                         }
7880                 }
7881                 return true;
7882         },
7883 
7884         /* Pop-up the date picker for a given input field.
7885          * If false returned from beforeShow event handler do not show.
7886          * @param  input  element - the input field attached to the date picker or
7887          *                                      event - if triggered by focus
7888          */
7889         _showDatepicker: function( input ) {
7890                 input = input.target || input;
7891                 if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7892                         input = $( "input", input.parentNode )[ 0 ];
7893                 }
7894 
7895                 if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7896                         return;
7897                 }
7898 
7899                 var inst, beforeShow, beforeShowSettings, isFixed,
7900                         offset, showAnim, duration;
7901 
7902                 inst = $.datepicker._getInst( input );
7903                 if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7904                         $.datepicker._curInst.dpDiv.stop( true, true );
7905                         if ( inst && $.datepicker._datepickerShowing ) {
7906                                 $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7907                         }
7908                 }
7909 
7910                 beforeShow = $.datepicker._get( inst, "beforeShow" );
7911                 beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7912                 if ( beforeShowSettings === false ) {
7913                         return;
7914                 }
7915                 datepicker_extendRemove( inst.settings, beforeShowSettings );
7916 
7917                 inst.lastVal = null;
7918                 $.datepicker._lastInput = input;
7919                 $.datepicker._setDateFromField( inst );
7920 
7921                 if ( $.datepicker._inDialog ) { // hide cursor
7922                         input.value = "";
7923                 }
7924                 if ( !$.datepicker._pos ) { // position below input
7925                         $.datepicker._pos = $.datepicker._findPos( input );
7926                         $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7927                 }
7928 
7929                 isFixed = false;
7930                 $( input ).parents().each( function() {
7931                         isFixed |= $( this ).css( "position" ) === "fixed";
7932                         return !isFixed;
7933                 } );
7934 
7935                 offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7936                 $.datepicker._pos = null;
7937 
7938                 //to avoid flashes on Firefox
7939                 inst.dpDiv.empty();
7940 
7941                 // determine sizing offscreen
7942                 inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7943                 $.datepicker._updateDatepicker( inst );
7944 
7945                 // fix width for dynamic number of date pickers
7946                 // and adjust position before showing
7947                 offset = $.datepicker._checkOffset( inst, offset, isFixed );
7948                 inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7949                         "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7950                         left: offset.left + "px", top: offset.top + "px" } );
7951 
7952                 if ( !inst.inline ) {
7953                         showAnim = $.datepicker._get( inst, "showAnim" );
7954                         duration = $.datepicker._get( inst, "duration" );
7955                         inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7956                         $.datepicker._datepickerShowing = true;
7957 
7958                         if ( $.effects && $.effects.effect[ showAnim ] ) {
7959                                 inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7960                         } else {
7961                                 inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7962                         }
7963 
7964                         if ( $.datepicker._shouldFocusInput( inst ) ) {
7965                                 inst.input.trigger( "focus" );
7966                         }
7967 
7968                         $.datepicker._curInst = inst;
7969                 }
7970         },
7971 
7972         /* Generate the date picker content. */
7973         _updateDatepicker: function( inst ) {
7974                 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7975                 datepicker_instActive = inst; // for delegate hover events
7976                 inst.dpDiv.empty().append( this._generateHTML( inst ) );
7977                 this._attachHandlers( inst );
7978 
7979                 var origyearshtml,
7980                         numMonths = this._getNumberOfMonths( inst ),
7981                         cols = numMonths[ 1 ],
7982                         width = 17,
7983                         activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7984 
7985                 if ( activeCell.length > 0 ) {
7986                         datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7987                 }
7988 
7989                 inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7990                 if ( cols > 1 ) {
7991                         inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7992                 }
7993                 inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7994                         "Class" ]( "ui-datepicker-multi" );
7995                 inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7996                         "Class" ]( "ui-datepicker-rtl" );
7997 
7998                 if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7999                         inst.input.trigger( "focus" );
8000                 }
8001 
8002                 // Deffered render of the years select (to avoid flashes on Firefox)
8003                 if ( inst.yearshtml ) {
8004                         origyearshtml = inst.yearshtml;
8005                         setTimeout( function() {
8006 
8007                                 //assure that inst.yearshtml didn't change.
8008                                 if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8009                                         inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8010                                 }
8011                                 origyearshtml = inst.yearshtml = null;
8012                         }, 0 );
8013                 }
8014         },
8015 
8016         // #6694 - don't focus the input if it's already focused
8017         // this breaks the change event in IE
8018         // Support: IE and jQuery <1.9
8019         _shouldFocusInput: function( inst ) {
8020                 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8021         },
8022 
8023         /* Check positioning to remain on screen. */
8024         _checkOffset: function( inst, offset, isFixed ) {
8025                 var dpWidth = inst.dpDiv.outerWidth(),
8026                         dpHeight = inst.dpDiv.outerHeight(),
8027                         inputWidth = inst.input ? inst.input.outerWidth() : 0,
8028                         inputHeight = inst.input ? inst.input.outerHeight() : 0,
8029                         viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8030                         viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8031 
8032                 offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8033                 offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8034                 offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8035 
8036                 // Now check if datepicker is showing outside window viewport - move to a better place if so.
8037                 offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8038                         Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8039                 offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8040                         Math.abs( dpHeight + inputHeight ) : 0 );
8041 
8042                 return offset;
8043         },
8044 
8045         /* Find an object's position on the screen. */
8046         _findPos: function( obj ) {
8047                 var position,
8048                         inst = this._getInst( obj ),
8049                         isRTL = this._get( inst, "isRTL" );
8050 
8051                 while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8052                         obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8053                 }
8054 
8055                 position = $( obj ).offset();
8056                 return [ position.left, position.top ];
8057         },
8058 
8059         /* Hide the date picker from view.
8060          * @param  input  element - the input field attached to the date picker
8061          */
8062         _hideDatepicker: function( input ) {
8063                 var showAnim, duration, postProcess, onClose,
8064                         inst = this._curInst;
8065 
8066                 if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8067                         return;
8068                 }
8069 
8070                 if ( this._datepickerShowing ) {
8071                         showAnim = this._get( inst, "showAnim" );
8072                         duration = this._get( inst, "duration" );
8073                         postProcess = function() {
8074                                 $.datepicker._tidyDialog( inst );
8075                         };
8076 
8077                         // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8078                         if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8079                                 inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8080                         } else {
8081                                 inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8082                                         ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8083                         }
8084 
8085                         if ( !showAnim ) {
8086                                 postProcess();
8087                         }
8088                         this._datepickerShowing = false;
8089 
8090                         onClose = this._get( inst, "onClose" );
8091                         if ( onClose ) {
8092                                 onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8093                         }
8094 
8095                         this._lastInput = null;
8096                         if ( this._inDialog ) {
8097                                 this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8098                                 if ( $.blockUI ) {
8099                                         $.unblockUI();
8100                                         $( "body" ).append( this.dpDiv );
8101                                 }
8102                         }
8103                         this._inDialog = false;
8104                 }
8105         },
8106 
8107         /* Tidy up after a dialog display. */
8108         _tidyDialog: function( inst ) {
8109                 inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8110         },
8111 
8112         /* Close date picker if clicked elsewhere. */
8113         _checkExternalClick: function( event ) {
8114                 if ( !$.datepicker._curInst ) {
8115                         return;
8116                 }
8117 
8118                 var $target = $( event.target ),
8119                         inst = $.datepicker._getInst( $target[ 0 ] );
8120 
8121                 if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8122                                 $target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8123                                 !$target.hasClass( $.datepicker.markerClassName ) &&
8124                                 !$target.closest( "." + $.datepicker._triggerClass ).length &&
8125                                 $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8126                         ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8127                                 $.datepicker._hideDatepicker();
8128                 }
8129         },
8130 
8131         /* Adjust one of the date sub-fields. */
8132         _adjustDate: function( id, offset, period ) {
8133                 var target = $( id ),
8134                         inst = this._getInst( target[ 0 ] );
8135 
8136                 if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8137                         return;
8138                 }
8139                 this._adjustInstDate( inst, offset +
8140                         ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8141                         period );
8142                 this._updateDatepicker( inst );
8143         },
8144 
8145         /* Action for current link. */
8146         _gotoToday: function( id ) {
8147                 var date,
8148                         target = $( id ),
8149                         inst = this._getInst( target[ 0 ] );
8150 
8151                 if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8152                         inst.selectedDay = inst.currentDay;
8153                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154                         inst.drawYear = inst.selectedYear = inst.currentYear;
8155                 } else {
8156                         date = new Date();
8157                         inst.selectedDay = date.getDate();
8158                         inst.drawMonth = inst.selectedMonth = date.getMonth();
8159                         inst.drawYear = inst.selectedYear = date.getFullYear();
8160                 }
8161                 this._notifyChange( inst );
8162                 this._adjustDate( target );
8163         },
8164 
8165         /* Action for selecting a new month/year. */
8166         _selectMonthYear: function( id, select, period ) {
8167                 var target = $( id ),
8168                         inst = this._getInst( target[ 0 ] );
8169 
8170                 inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8171                 inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8172                         parseInt( select.options[ select.selectedIndex ].value, 10 );
8173 
8174                 this._notifyChange( inst );
8175                 this._adjustDate( target );
8176         },
8177 
8178         /* Action for selecting a day. */
8179         _selectDay: function( id, month, year, td ) {
8180                 var inst,
8181                         target = $( id );
8182 
8183                 if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8184                         return;
8185                 }
8186 
8187                 inst = this._getInst( target[ 0 ] );
8188                 inst.selectedDay = inst.currentDay = $( "a", td ).html();
8189                 inst.selectedMonth = inst.currentMonth = month;
8190                 inst.selectedYear = inst.currentYear = year;
8191                 this._selectDate( id, this._formatDate( inst,
8192                         inst.currentDay, inst.currentMonth, inst.currentYear ) );
8193         },
8194 
8195         /* Erase the input field and hide the date picker. */
8196         _clearDate: function( id ) {
8197                 var target = $( id );
8198                 this._selectDate( target, "" );
8199         },
8200 
8201         /* Update the input field with the selected date. */
8202         _selectDate: function( id, dateStr ) {
8203                 var onSelect,
8204                         target = $( id ),
8205                         inst = this._getInst( target[ 0 ] );
8206 
8207                 dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8208                 if ( inst.input ) {
8209                         inst.input.val( dateStr );
8210                 }
8211                 this._updateAlternate( inst );
8212 
8213                 onSelect = this._get( inst, "onSelect" );
8214                 if ( onSelect ) {
8215                         onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8216                 } else if ( inst.input ) {
8217                         inst.input.trigger( "change" ); // fire the change event
8218                 }
8219 
8220                 if ( inst.inline ) {
8221                         this._updateDatepicker( inst );
8222                 } else {
8223                         this._hideDatepicker();
8224                         this._lastInput = inst.input[ 0 ];
8225                         if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8226                                 inst.input.trigger( "focus" ); // restore focus
8227                         }
8228                         this._lastInput = null;
8229                 }
8230         },
8231 
8232         /* Update any alternate field to synchronise with the main field. */
8233         _updateAlternate: function( inst ) {
8234                 var altFormat, date, dateStr,
8235                         altField = this._get( inst, "altField" );
8236 
8237                 if ( altField ) { // update alternate field too
8238                         altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8239                         date = this._getDate( inst );
8240                         dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8241                         $( altField ).val( dateStr );
8242                 }
8243         },
8244 
8245         /* Set as beforeShowDay function to prevent selection of weekends.
8246          * @param  date  Date - the date to customise
8247          * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248          */
8249         noWeekends: function( date ) {
8250                 var day = date.getDay();
8251                 return [ ( day > 0 && day < 6 ), "" ];
8252         },
8253 
8254         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255          * @param  date  Date - the date to get the week for
8256          * @return  number - the number of the week within the year that contains this date
8257          */
8258         iso8601Week: function( date ) {
8259                 var time,
8260                         checkDate = new Date( date.getTime() );
8261 
8262                 // Find Thursday of this week starting on Monday
8263                 checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8264 
8265                 time = checkDate.getTime();
8266                 checkDate.setMonth( 0 ); // Compare with Jan 1
8267                 checkDate.setDate( 1 );
8268                 return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8269         },
8270 
8271         /* Parse a string value into a date object.
8272          * See formatDate below for the possible formats.
8273          *
8274          * @param  format string - the expected format of the date
8275          * @param  value string - the date in the above format
8276          * @param  settings Object - attributes include:
8277          *                                      shortYearCutoff  number - the cutoff year for determining the century (optional)
8278          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8279          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8280          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8281          *                                      monthNames              string[12] - names of the months (optional)
8282          * @return  Date - the extracted date value or null if value is blank
8283          */
8284         parseDate: function( format, value, settings ) {
8285                 if ( format == null || value == null ) {
8286                         throw "Invalid arguments";
8287                 }
8288 
8289                 value = ( typeof value === "object" ? value.toString() : value + "" );
8290                 if ( value === "" ) {
8291                         return null;
8292                 }
8293 
8294                 var iFormat, dim, extra,
8295                         iValue = 0,
8296                         shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8297                         shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8298                                 new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8299                         dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8300                         dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8301                         monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8302                         monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8303                         year = -1,
8304                         month = -1,
8305                         day = -1,
8306                         doy = -1,
8307                         literal = false,
8308                         date,
8309 
8310                         // Check whether a format character is doubled
8311                         lookAhead = function( match ) {
8312                                 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8313                                 if ( matches ) {
8314                                         iFormat++;
8315                                 }
8316                                 return matches;
8317                         },
8318 
8319                         // Extract a number from the string value
8320                         getNumber = function( match ) {
8321                                 var isDoubled = lookAhead( match ),
8322                                         size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8323                                         ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8324                                         minSize = ( match === "y" ? size : 1 ),
8325                                         digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8326                                         num = value.substring( iValue ).match( digits );
8327                                 if ( !num ) {
8328                                         throw "Missing number at position " + iValue;
8329                                 }
8330                                 iValue += num[ 0 ].length;
8331                                 return parseInt( num[ 0 ], 10 );
8332                         },
8333 
8334                         // Extract a name from the string value and convert to an index
8335                         getName = function( match, shortNames, longNames ) {
8336                                 var index = -1,
8337                                         names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8338                                                 return [ [ k, v ] ];
8339                                         } ).sort( function( a, b ) {
8340                                                 return -( a[ 1 ].length - b[ 1 ].length );
8341                                         } );
8342 
8343                                 $.each( names, function( i, pair ) {
8344                                         var name = pair[ 1 ];
8345                                         if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8346                                                 index = pair[ 0 ];
8347                                                 iValue += name.length;
8348                                                 return false;
8349                                         }
8350                                 } );
8351                                 if ( index !== -1 ) {
8352                                         return index + 1;
8353                                 } else {
8354                                         throw "Unknown name at position " + iValue;
8355                                 }
8356                         },
8357 
8358                         // Confirm that a literal character matches the string value
8359                         checkLiteral = function() {
8360                                 if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8361                                         throw "Unexpected literal at position " + iValue;
8362                                 }
8363                                 iValue++;
8364                         };
8365 
8366                 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8367                         if ( literal ) {
8368                                 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8369                                         literal = false;
8370                                 } else {
8371                                         checkLiteral();
8372                                 }
8373                         } else {
8374                                 switch ( format.charAt( iFormat ) ) {
8375                                         case "d":
8376                                                 day = getNumber( "d" );
8377                                                 break;
8378                                         case "D":
8379                                                 getName( "D", dayNamesShort, dayNames );
8380                                                 break;
8381                                         case "o":
8382                                                 doy = getNumber( "o" );
8383                                                 break;
8384                                         case "m":
8385                                                 month = getNumber( "m" );
8386                                                 break;
8387                                         case "M":
8388                                                 month = getName( "M", monthNamesShort, monthNames );
8389                                                 break;
8390                                         case "y":
8391                                                 year = getNumber( "y" );
8392                                                 break;
8393                                         case "@":
8394                                                 date = new Date( getNumber( "@" ) );
8395                                                 year = date.getFullYear();
8396                                                 month = date.getMonth() + 1;
8397                                                 day = date.getDate();
8398                                                 break;
8399                                         case "!":
8400                                                 date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8401                                                 year = date.getFullYear();
8402                                                 month = date.getMonth() + 1;
8403                                                 day = date.getDate();
8404                                                 break;
8405                                         case "'":
8406                                                 if ( lookAhead( "'" ) ) {
8407                                                         checkLiteral();
8408                                                 } else {
8409                                                         literal = true;
8410                                                 }
8411                                                 break;
8412                                         default:
8413                                                 checkLiteral();
8414                                 }
8415                         }
8416                 }
8417 
8418                 if ( iValue < value.length ) {
8419                         extra = value.substr( iValue );
8420                         if ( !/^\s+/.test( extra ) ) {
8421                                 throw "Extra/unparsed characters found in date: " + extra;
8422                         }
8423                 }
8424 
8425                 if ( year === -1 ) {
8426                         year = new Date().getFullYear();
8427                 } else if ( year < 100 ) {
8428                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429                                 ( year <= shortYearCutoff ? 0 : -100 );
8430                 }
8431 
8432                 if ( doy > -1 ) {
8433                         month = 1;
8434                         day = doy;
8435                         do {
8436                                 dim = this._getDaysInMonth( year, month - 1 );
8437                                 if ( day <= dim ) {
8438                                         break;
8439                                 }
8440                                 month++;
8441                                 day -= dim;
8442                         } while ( true );
8443                 }
8444 
8445                 date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8446                 if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8447                         throw "Invalid date"; // E.g. 31/02/00
8448                 }
8449                 return date;
8450         },
8451 
8452         /* Standard date formats. */
8453         ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454         COOKIE: "D, dd M yy",
8455         ISO_8601: "yy-mm-dd",
8456         RFC_822: "D, d M y",
8457         RFC_850: "DD, dd-M-y",
8458         RFC_1036: "D, d M y",
8459         RFC_1123: "D, d M yy",
8460         RFC_2822: "D, d M yy",
8461         RSS: "D, d M y", // RFC 822
8462         TICKS: "!",
8463         TIMESTAMP: "@",
8464         W3C: "yy-mm-dd", // ISO 8601
8465 
8466         _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8467                 Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8468 
8469         /* Format a date object into a string value.
8470          * The format can be combinations of the following:
8471          * d  - day of month (no leading zero)
8472          * dd - day of month (two digit)
8473          * o  - day of year (no leading zeros)
8474          * oo - day of year (three digit)
8475          * D  - day name short
8476          * DD - day name long
8477          * m  - month of year (no leading zero)
8478          * mm - month of year (two digit)
8479          * M  - month name short
8480          * MM - month name long
8481          * y  - year (two digit)
8482          * yy - year (four digit)
8483          * @ - Unix timestamp (ms since 01/01/1970)
8484          * ! - Windows ticks (100ns since 01/01/0001)
8485          * "..." - literal text
8486          * '' - single quote
8487          *
8488          * @param  format string - the desired format of the date
8489          * @param  date Date - the date value to format
8490          * @param  settings Object - attributes include:
8491          *                                      dayNamesShort   string[7] - abbreviated names of the days from Sunday (optional)
8492          *                                      dayNames                string[7] - names of the days from Sunday (optional)
8493          *                                      monthNamesShort string[12] - abbreviated names of the months (optional)
8494          *                                      monthNames              string[12] - names of the months (optional)
8495          * @return  string - the date in the above format
8496          */
8497         formatDate: function( format, date, settings ) {
8498                 if ( !date ) {
8499                         return "";
8500                 }
8501 
8502                 var iFormat,
8503                         dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8504                         dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8505                         monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8506                         monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8507 
8508                         // Check whether a format character is doubled
8509                         lookAhead = function( match ) {
8510                                 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8511                                 if ( matches ) {
8512                                         iFormat++;
8513                                 }
8514                                 return matches;
8515                         },
8516 
8517                         // Format a number, with leading zero if necessary
8518                         formatNumber = function( match, value, len ) {
8519                                 var num = "" + value;
8520                                 if ( lookAhead( match ) ) {
8521                                         while ( num.length < len ) {
8522                                                 num = "0" + num;
8523                                         }
8524                                 }
8525                                 return num;
8526                         },
8527 
8528                         // Format a name, short or long as requested
8529                         formatName = function( match, value, shortNames, longNames ) {
8530                                 return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8531                         },
8532                         output = "",
8533                         literal = false;
8534 
8535                 if ( date ) {
8536                         for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8537                                 if ( literal ) {
8538                                         if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8539                                                 literal = false;
8540                                         } else {
8541                                                 output += format.charAt( iFormat );
8542                                         }
8543                                 } else {
8544                                         switch ( format.charAt( iFormat ) ) {
8545                                                 case "d":
8546                                                         output += formatNumber( "d", date.getDate(), 2 );
8547                                                         break;
8548                                                 case "D":
8549                                                         output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8550                                                         break;
8551                                                 case "o":
8552                                                         output += formatNumber( "o",
8553                                                                 Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8554                                                         break;
8555                                                 case "m":
8556                                                         output += formatNumber( "m", date.getMonth() + 1, 2 );
8557                                                         break;
8558                                                 case "M":
8559                                                         output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8560                                                         break;
8561                                                 case "y":
8562                                                         output += ( lookAhead( "y" ) ? date.getFullYear() :
8563                                                                 ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8564                                                         break;
8565                                                 case "@":
8566                                                         output += date.getTime();
8567                                                         break;
8568                                                 case "!":
8569                                                         output += date.getTime() * 10000 + this._ticksTo1970;
8570                                                         break;
8571                                                 case "'":
8572                                                         if ( lookAhead( "'" ) ) {
8573                                                                 output += "'";
8574                                                         } else {
8575                                                                 literal = true;
8576                                                         }
8577                                                         break;
8578                                                 default:
8579                                                         output += format.charAt( iFormat );
8580                                         }
8581                                 }
8582                         }
8583                 }
8584                 return output;
8585         },
8586 
8587         /* Extract all possible characters from the date format. */
8588         _possibleChars: function( format ) {
8589                 var iFormat,
8590                         chars = "",
8591                         literal = false,
8592 
8593                         // Check whether a format character is doubled
8594                         lookAhead = function( match ) {
8595                                 var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8596                                 if ( matches ) {
8597                                         iFormat++;
8598                                 }
8599                                 return matches;
8600                         };
8601 
8602                 for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8603                         if ( literal ) {
8604                                 if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8605                                         literal = false;
8606                                 } else {
8607                                         chars += format.charAt( iFormat );
8608                                 }
8609                         } else {
8610                                 switch ( format.charAt( iFormat ) ) {
8611                                         case "d": case "m": case "y": case "@":
8612                                                 chars += "0123456789";
8613                                                 break;
8614                                         case "D": case "M":
8615                                                 return null; // Accept anything
8616                                         case "'":
8617                                                 if ( lookAhead( "'" ) ) {
8618                                                         chars += "'";
8619                                                 } else {
8620                                                         literal = true;
8621                                                 }
8622                                                 break;
8623                                         default:
8624                                                 chars += format.charAt( iFormat );
8625                                 }
8626                         }
8627                 }
8628                 return chars;
8629         },
8630 
8631         /* Get a setting value, defaulting if necessary. */
8632         _get: function( inst, name ) {
8633                 return inst.settings[ name ] !== undefined ?
8634                         inst.settings[ name ] : this._defaults[ name ];
8635         },
8636 
8637         /* Parse existing date and initialise date picker. */
8638         _setDateFromField: function( inst, noDefault ) {
8639                 if ( inst.input.val() === inst.lastVal ) {
8640                         return;
8641                 }
8642 
8643                 var dateFormat = this._get( inst, "dateFormat" ),
8644                         dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645                         defaultDate = this._getDefaultDate( inst ),
8646                         date = defaultDate,
8647                         settings = this._getFormatConfig( inst );
8648 
8649                 try {
8650                         date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8651                 } catch ( event ) {
8652                         dates = ( noDefault ? "" : dates );
8653                 }
8654                 inst.selectedDay = date.getDate();
8655                 inst.drawMonth = inst.selectedMonth = date.getMonth();
8656                 inst.drawYear = inst.selectedYear = date.getFullYear();
8657                 inst.currentDay = ( dates ? date.getDate() : 0 );
8658                 inst.currentMonth = ( dates ? date.getMonth() : 0 );
8659                 inst.currentYear = ( dates ? date.getFullYear() : 0 );
8660                 this._adjustInstDate( inst );
8661         },
8662 
8663         /* Retrieve the default date shown on opening. */
8664         _getDefaultDate: function( inst ) {
8665                 return this._restrictMinMax( inst,
8666                         this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8667         },
8668 
8669         /* A date may be specified as an exact value or a relative one. */
8670         _determineDate: function( inst, date, defaultDate ) {
8671                 var offsetNumeric = function( offset ) {
8672                                 var date = new Date();
8673                                 date.setDate( date.getDate() + offset );
8674                                 return date;
8675                         },
8676                         offsetString = function( offset ) {
8677                                 try {
8678                                         return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8679                                                 offset, $.datepicker._getFormatConfig( inst ) );
8680                                 }
8681                                 catch ( e ) {
8682 
8683                                         // Ignore
8684                                 }
8685 
8686                                 var date = ( offset.toLowerCase().match( /^c/ ) ?
8687                                         $.datepicker._getDate( inst ) : null ) || new Date(),
8688                                         year = date.getFullYear(),
8689                                         month = date.getMonth(),
8690                                         day = date.getDate(),
8691                                         pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8692                                         matches = pattern.exec( offset );
8693 
8694                                 while ( matches ) {
8695                                         switch ( matches[ 2 ] || "d" ) {
8696                                                 case "d" : case "D" :
8697                                                         day += parseInt( matches[ 1 ], 10 ); break;
8698                                                 case "w" : case "W" :
8699                                                         day += parseInt( matches[ 1 ], 10 ) * 7; break;
8700                                                 case "m" : case "M" :
8701                                                         month += parseInt( matches[ 1 ], 10 );
8702                                                         day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8703                                                         break;
8704                                                 case "y": case "Y" :
8705                                                         year += parseInt( matches[ 1 ], 10 );
8706                                                         day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8707                                                         break;
8708                                         }
8709                                         matches = pattern.exec( offset );
8710                                 }
8711                                 return new Date( year, month, day );
8712                         },
8713                         newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8714                                 ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8715 
8716                 newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8717                 if ( newDate ) {
8718                         newDate.setHours( 0 );
8719                         newDate.setMinutes( 0 );
8720                         newDate.setSeconds( 0 );
8721                         newDate.setMilliseconds( 0 );
8722                 }
8723                 return this._daylightSavingAdjust( newDate );
8724         },
8725 
8726         /* Handle switch to/from daylight saving.
8727          * Hours may be non-zero on daylight saving cut-over:
8728          * > 12 when midnight changeover, but then cannot generate
8729          * midnight datetime, so jump to 1AM, otherwise reset.
8730          * @param  date  (Date) the date to check
8731          * @return  (Date) the corrected date
8732          */
8733         _daylightSavingAdjust: function( date ) {
8734                 if ( !date ) {
8735                         return null;
8736                 }
8737                 date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8738                 return date;
8739         },
8740 
8741         /* Set the date(s) directly. */
8742         _setDate: function( inst, date, noChange ) {
8743                 var clear = !date,
8744                         origMonth = inst.selectedMonth,
8745                         origYear = inst.selectedYear,
8746                         newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8747 
8748                 inst.selectedDay = inst.currentDay = newDate.getDate();
8749                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8750                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8751                 if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8752                         this._notifyChange( inst );
8753                 }
8754                 this._adjustInstDate( inst );
8755                 if ( inst.input ) {
8756                         inst.input.val( clear ? "" : this._formatDate( inst ) );
8757                 }
8758         },
8759 
8760         /* Retrieve the date(s) directly. */
8761         _getDate: function( inst ) {
8762                 var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8763                         this._daylightSavingAdjust( new Date(
8764                         inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8765                         return startDate;
8766         },
8767 
8768         /* Attach the onxxx handlers.  These are declared statically so
8769          * they work with static code transformers like Caja.
8770          */
8771         _attachHandlers: function( inst ) {
8772                 var stepMonths = this._get( inst, "stepMonths" ),
8773                         id = "#" + inst.id.replace( /\\\\/g, "\\" );
8774                 inst.dpDiv.find( "[data-handler]" ).map( function() {
8775                         var handler = {
8776                                 prev: function() {
8777                                         $.datepicker._adjustDate( id, -stepMonths, "M" );
8778                                 },
8779                                 next: function() {
8780                                         $.datepicker._adjustDate( id, +stepMonths, "M" );
8781                                 },
8782                                 hide: function() {
8783                                         $.datepicker._hideDatepicker();
8784                                 },
8785                                 today: function() {
8786                                         $.datepicker._gotoToday( id );
8787                                 },
8788                                 selectDay: function() {
8789                                         $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8790                                         return false;
8791                                 },
8792                                 selectMonth: function() {
8793                                         $.datepicker._selectMonthYear( id, this, "M" );
8794                                         return false;
8795                                 },
8796                                 selectYear: function() {
8797                                         $.datepicker._selectMonthYear( id, this, "Y" );
8798                                         return false;
8799                                 }
8800                         };
8801                         $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8802                 } );
8803         },
8804 
8805         /* Generate the HTML for the current state of the date picker. */
8806         _generateHTML: function( inst ) {
8807                 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8808                         controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8809                         monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8810                         selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8811                         cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8812                         printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8813                         tempDate = new Date(),
8814                         today = this._daylightSavingAdjust(
8815                                 new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8816                         isRTL = this._get( inst, "isRTL" ),
8817                         showButtonPanel = this._get( inst, "showButtonPanel" ),
8818                         hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8819                         navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8820                         numMonths = this._getNumberOfMonths( inst ),
8821                         showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8822                         stepMonths = this._get( inst, "stepMonths" ),
8823                         isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8824                         currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8825                                 new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8826                         minDate = this._getMinMaxDate( inst, "min" ),
8827                         maxDate = this._getMinMaxDate( inst, "max" ),
8828                         drawMonth = inst.drawMonth - showCurrentAtPos,
8829                         drawYear = inst.drawYear;
8830 
8831                 if ( drawMonth < 0 ) {
8832                         drawMonth += 12;
8833                         drawYear--;
8834                 }
8835                 if ( maxDate ) {
8836                         maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8837                                 maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8838                         maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8839                         while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8840                                 drawMonth--;
8841                                 if ( drawMonth < 0 ) {
8842                                         drawMonth = 11;
8843                                         drawYear--;
8844                                 }
8845                         }
8846                 }
8847                 inst.drawMonth = drawMonth;
8848                 inst.drawYear = drawYear;
8849 
8850                 prevText = this._get( inst, "prevText" );
8851                 prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8852                         this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8853                         this._getFormatConfig( inst ) ) );
8854 
8855                 prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8856                         "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8857                         " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8858                         ( 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>" ) );
8859 
8860                 nextText = this._get( inst, "nextText" );
8861                 nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8862                         this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8863                         this._getFormatConfig( inst ) ) );
8864 
8865                 next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8866                         "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8867                         " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8868                         ( 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>" ) );
8869 
8870                 currentText = this._get( inst, "currentText" );
8871                 gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8872                 currentText = ( !navigationAsDateFormat ? currentText :
8873                         this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8874 
8875                 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'>" +
8876                         this._get( inst, "closeText" ) + "</button>" : "" );
8877 
8878                 buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8879                         ( 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'" +
8880                         ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8881 
8882                 firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8883                 firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8884 
8885                 showWeek = this._get( inst, "showWeek" );
8886                 dayNames = this._get( inst, "dayNames" );
8887                 dayNamesMin = this._get( inst, "dayNamesMin" );
8888                 monthNames = this._get( inst, "monthNames" );
8889                 monthNamesShort = this._get( inst, "monthNamesShort" );
8890                 beforeShowDay = this._get( inst, "beforeShowDay" );
8891                 showOtherMonths = this._get( inst, "showOtherMonths" );
8892                 selectOtherMonths = this._get( inst, "selectOtherMonths" );
8893                 defaultDate = this._getDefaultDate( inst );
8894                 html = "";
8895 
8896                 for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8897                         group = "";
8898                         this.maxRows = 4;
8899                         for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8900                                 selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8901                                 cornerClass = " ui-corner-all";
8902                                 calender = "";
8903                                 if ( isMultiMonth ) {
8904                                         calender += "<div class='ui-datepicker-group";
8905                                         if ( numMonths[ 1 ] > 1 ) {
8906                                                 switch ( col ) {
8907                                                         case 0: calender += " ui-datepicker-group-first";
8908                                                                 cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8909                                                         case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8910                                                                 cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8911                                                         default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8912                                                 }
8913                                         }
8914                                         calender += "'>";
8915                                 }
8916                                 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8917                                         ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8918                                         ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8919                                         this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8920                                         row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8921                                         "</div><table class='ui-datepicker-calendar'><thead>" +
8922                                         "<tr>";
8923                                 thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8924                                 for ( dow = 0; dow < 7; dow++ ) { // days of the week
8925                                         day = ( dow + firstDay ) % 7;
8926                                         thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8927                                                 "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8928                                 }
8929                                 calender += thead + "</tr></thead><tbody>";
8930                                 daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8931                                 if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8932                                         inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8933                                 }
8934                                 leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8935                                 curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8936                                 numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8937                                 this.maxRows = numRows;
8938                                 printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8939                                 for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8940                                         calender += "<tr>";
8941                                         tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8942                                                 this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8943                                         for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8944                                                 daySettings = ( beforeShowDay ?
8945                                                         beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8946                                                 otherMonth = ( printDate.getMonth() !== drawMonth );
8947                                                 unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8948                                                         ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8949                                                 tbody += "<td class='" +
8950                                                         ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8951                                                         ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8952                                                         ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8953                                                         ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8954 
8955                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
8956                                                         " " + this._dayOverClass : "" ) + // highlight selected day
8957                                                         ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8958                                                         ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8959                                                         ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8960                                                         ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8961                                                         ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8962                                                         ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8963                                                         ( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8964                                                         ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8965                                                         ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8966                                                         ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8967                                                         ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8968                                                         "' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8969                                                 printDate.setDate( printDate.getDate() + 1 );
8970                                                 printDate = this._daylightSavingAdjust( printDate );
8971                                         }
8972                                         calender += tbody + "</tr>";
8973                                 }
8974                                 drawMonth++;
8975                                 if ( drawMonth > 11 ) {
8976                                         drawMonth = 0;
8977                                         drawYear++;
8978                                 }
8979                                 calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8980                                                         ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8981                                 group += calender;
8982                         }
8983                         html += group;
8984                 }
8985                 html += buttonPanel;
8986                 inst._keyEvent = false;
8987                 return html;
8988         },
8989 
8990         /* Generate the month and year header. */
8991         _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8992                         secondary, monthNames, monthNamesShort ) {
8993 
8994                 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8995                         changeMonth = this._get( inst, "changeMonth" ),
8996                         changeYear = this._get( inst, "changeYear" ),
8997                         showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8998                         html = "<div class='ui-datepicker-title'>",
8999                         monthHtml = "";
9000 
9001                 // Month selection
9002                 if ( secondary || !changeMonth ) {
9003                         monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9004                 } else {
9005                         inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9006                         inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9007                         monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9008                         for ( month = 0; month < 12; month++ ) {
9009                                 if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9010                                         monthHtml += "<option value='" + month + "'" +
9011                                                 ( month === drawMonth ? " selected='selected'" : "" ) +
9012                                                 ">" + monthNamesShort[ month ] + "</option>";
9013                                 }
9014                         }
9015                         monthHtml += "</select>";
9016                 }
9017 
9018                 if ( !showMonthAfterYear ) {
9019                         html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9020                 }
9021 
9022                 // Year selection
9023                 if ( !inst.yearshtml ) {
9024                         inst.yearshtml = "";
9025                         if ( secondary || !changeYear ) {
9026                                 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9027                         } else {
9028 
9029                                 // determine range of years to display
9030                                 years = this._get( inst, "yearRange" ).split( ":" );
9031                                 thisYear = new Date().getFullYear();
9032                                 determineYear = function( value ) {
9033                                         var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9034                                                 ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9035                                                 parseInt( value, 10 ) ) );
9036                                         return ( isNaN( year ) ? thisYear : year );
9037                                 };
9038                                 year = determineYear( years[ 0 ] );
9039                                 endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9040                                 year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9041                                 endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9042                                 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9043                                 for ( ; year <= endYear; year++ ) {
9044                                         inst.yearshtml += "<option value='" + year + "'" +
9045                                                 ( year === drawYear ? " selected='selected'" : "" ) +
9046                                                 ">" + year + "</option>";
9047                                 }
9048                                 inst.yearshtml += "</select>";
9049 
9050                                 html += inst.yearshtml;
9051                                 inst.yearshtml = null;
9052                         }
9053                 }
9054 
9055                 html += this._get( inst, "yearSuffix" );
9056                 if ( showMonthAfterYear ) {
9057                         html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9058                 }
9059                 html += "</div>"; // Close datepicker_header
9060                 return html;
9061         },
9062 
9063         /* Adjust one of the date sub-fields. */
9064         _adjustInstDate: function( inst, offset, period ) {
9065                 var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9066                         month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9067                         day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9068                         date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9069 
9070                 inst.selectedDay = date.getDate();
9071                 inst.drawMonth = inst.selectedMonth = date.getMonth();
9072                 inst.drawYear = inst.selectedYear = date.getFullYear();
9073                 if ( period === "M" || period === "Y" ) {
9074                         this._notifyChange( inst );
9075                 }
9076         },
9077 
9078         /* Ensure a date is within any min/max bounds. */
9079         _restrictMinMax: function( inst, date ) {
9080                 var minDate = this._getMinMaxDate( inst, "min" ),
9081                         maxDate = this._getMinMaxDate( inst, "max" ),
9082                         newDate = ( minDate && date < minDate ? minDate : date );
9083                 return ( maxDate && newDate > maxDate ? maxDate : newDate );
9084         },
9085 
9086         /* Notify change of month/year. */
9087         _notifyChange: function( inst ) {
9088                 var onChange = this._get( inst, "onChangeMonthYear" );
9089                 if ( onChange ) {
9090                         onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9091                                 [ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9092                 }
9093         },
9094 
9095         /* Determine the number of months to show. */
9096         _getNumberOfMonths: function( inst ) {
9097                 var numMonths = this._get( inst, "numberOfMonths" );
9098                 return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9099         },
9100 
9101         /* Determine the current maximum date - ensure no time components are set. */
9102         _getMinMaxDate: function( inst, minMax ) {
9103                 return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9104         },
9105 
9106         /* Find the number of days in a given month. */
9107         _getDaysInMonth: function( year, month ) {
9108                 return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9109         },
9110 
9111         /* Find the day of the week of the first of a month. */
9112         _getFirstDayOfMonth: function( year, month ) {
9113                 return new Date( year, month, 1 ).getDay();
9114         },
9115 
9116         /* Determines if we should allow a "next/prev" month display change. */
9117         _canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9118                 var numMonths = this._getNumberOfMonths( inst ),
9119                         date = this._daylightSavingAdjust( new Date( curYear,
9120                         curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9121 
9122                 if ( offset < 0 ) {
9123                         date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9124                 }
9125                 return this._isInRange( inst, date );
9126         },
9127 
9128         /* Is the given date in the accepted range? */
9129         _isInRange: function( inst, date ) {
9130                 var yearSplit, currentYear,
9131                         minDate = this._getMinMaxDate( inst, "min" ),
9132                         maxDate = this._getMinMaxDate( inst, "max" ),
9133                         minYear = null,
9134                         maxYear = null,
9135                         years = this._get( inst, "yearRange" );
9136                         if ( years ) {
9137                                 yearSplit = years.split( ":" );
9138                                 currentYear = new Date().getFullYear();
9139                                 minYear = parseInt( yearSplit[ 0 ], 10 );
9140                                 maxYear = parseInt( yearSplit[ 1 ], 10 );
9141                                 if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9142                                         minYear += currentYear;
9143                                 }
9144                                 if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9145                                         maxYear += currentYear;
9146                                 }
9147                         }
9148 
9149                 return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9150                         ( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9151                         ( !minYear || date.getFullYear() >= minYear ) &&
9152                         ( !maxYear || date.getFullYear() <= maxYear ) );
9153         },
9154 
9155         /* Provide the configuration settings for formatting/parsing. */
9156         _getFormatConfig: function( inst ) {
9157                 var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9158                 shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9159                         new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9160                 return { shortYearCutoff: shortYearCutoff,
9161                         dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9162                         monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9163         },
9164 
9165         /* Format the given date for display. */
9166         _formatDate: function( inst, day, month, year ) {
9167                 if ( !day ) {
9168                         inst.currentDay = inst.selectedDay;
9169                         inst.currentMonth = inst.selectedMonth;
9170                         inst.currentYear = inst.selectedYear;
9171                 }
9172                 var date = ( day ? ( typeof day === "object" ? day :
9173                         this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9174                         this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9175                 return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9176         }
9177 } );
9178 
9179 /*
9180  * Bind hover events for datepicker elements.
9181  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9182  * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9183  */
9184 function datepicker_bindHover( dpDiv ) {
9185         var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9186         return dpDiv.on( "mouseout", selector, function() {
9187                         $( this ).removeClass( "ui-state-hover" );
9188                         if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9189                                 $( this ).removeClass( "ui-datepicker-prev-hover" );
9190                         }
9191                         if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9192                                 $( this ).removeClass( "ui-datepicker-next-hover" );
9193                         }
9194                 } )
9195                 .on( "mouseover", selector, datepicker_handleMouseover );
9196 }
9197 
9198 function datepicker_handleMouseover() {
9199         if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9200                 $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9201                 $( this ).addClass( "ui-state-hover" );
9202                 if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9203                         $( this ).addClass( "ui-datepicker-prev-hover" );
9204                 }
9205                 if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9206                         $( this ).addClass( "ui-datepicker-next-hover" );
9207                 }
9208         }
9209 }
9210 
9211 /* jQuery extend now ignores nulls! */
9212 function datepicker_extendRemove( target, props ) {
9213         $.extend( target, props );
9214         for ( var name in props ) {
9215                 if ( props[ name ] == null ) {
9216                         target[ name ] = props[ name ];
9217                 }
9218         }
9219         return target;
9220 }
9221 
9222 /* Invoke the datepicker functionality.
9223    @param  options  string - a command, optionally followed by additional parameters or
9224                                         Object - settings for attaching new datepicker functionality
9225    @return  jQuery object */
9226 $.fn.datepicker = function( options ) {
9227 
9228         /* Verify an empty collection wasn't passed - Fixes #6976 */
9229         if ( !this.length ) {
9230                 return this;
9231         }
9232 
9233         /* Initialise the date picker. */
9234         if ( !$.datepicker.initialized ) {
9235                 $( document ).on( "mousedown", $.datepicker._checkExternalClick );
9236                 $.datepicker.initialized = true;
9237         }
9238 
9239         /* Append datepicker main container to body if not exist. */
9240         if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9241                 $( "body" ).append( $.datepicker.dpDiv );
9242         }
9243 
9244         var otherArgs = Array.prototype.slice.call( arguments, 1 );
9245         if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9246                 return $.datepicker[ "_" + options + "Datepicker" ].
9247                         apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9248         }
9249         if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9250                 return $.datepicker[ "_" + options + "Datepicker" ].
9251                         apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9252         }
9253         return this.each( function() {
9254                 typeof options === "string" ?
9255                         $.datepicker[ "_" + options + "Datepicker" ].
9256                                 apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9257                         $.datepicker._attachDatepicker( this, options );
9258         } );
9259 };
9260 
9261 $.datepicker = new Datepicker(); // singleton instance
9262 $.datepicker.initialized = false;
9263 $.datepicker.uuid = new Date().getTime();
9264 $.datepicker.version = "1.12.1";
9265 
9266 var widgetsDatepicker = $.datepicker;
9267 
9268 
9269 
9270 
9271 // This file is deprecated
9272 var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9273 
9274 /*!
9275  * jQuery UI Mouse 1.12.1
9276  * http://jqueryui.com
9277  *
9278  * Copyright jQuery Foundation and other contributors
9279  * Released under the MIT license.
9280  * http://jquery.org/license
9281  */
9282 
9283 //>>label: Mouse
9284 //>>group: Widgets
9285 //>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9286 //>>docs: http://api.jqueryui.com/mouse/
9287 
9288 
9289 
9290 var mouseHandled = false;
9291 $( document ).on( "mouseup", function() {
9292         mouseHandled = false;
9293 } );
9294 
9295 var widgetsMouse = $.widget( "ui.mouse", {
9296         version: "1.12.1",
9297         options: {
9298                 cancel: "input, textarea, button, select, option",
9299                 distance: 1,
9300                 delay: 0
9301         },
9302         _mouseInit: function() {
9303                 var that = this;
9304 
9305                 this.element
9306                         .on( "mousedown." + this.widgetName, function( event ) {
9307                                 return that._mouseDown( event );
9308                         } )
9309                         .on( "click." + this.widgetName, function( event ) {
9310                                 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9311                                         $.removeData( event.target, that.widgetName + ".preventClickEvent" );
9312                                         event.stopImmediatePropagation();
9313                                         return false;
9314                                 }
9315                         } );
9316 
9317                 this.started = false;
9318         },
9319 
9320         // TODO: make sure destroying one instance of mouse doesn't mess with
9321         // other instances of mouse
9322         _mouseDestroy: function() {
9323                 this.element.off( "." + this.widgetName );
9324                 if ( this._mouseMoveDelegate ) {
9325                         this.document
9326                                 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9327                                 .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9328                 }
9329         },
9330 
9331         _mouseDown: function( event ) {
9332 
9333                 // don't let more than one widget handle mouseStart
9334                 if ( mouseHandled ) {
9335                         return;
9336                 }
9337 
9338                 this._mouseMoved = false;
9339 
9340                 // We may have missed mouseup (out of window)
9341                 ( this._mouseStarted && this._mouseUp( event ) );
9342 
9343                 this._mouseDownEvent = event;
9344 
9345                 var that = this,
9346                         btnIsLeft = ( event.which === 1 ),
9347 
9348                         // event.target.nodeName works around a bug in IE 8 with
9349                         // disabled inputs (#7620)
9350                         elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9351                                 $( event.target ).closest( this.options.cancel ).length : false );
9352                 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9353                         return true;
9354                 }
9355 
9356                 this.mouseDelayMet = !this.options.delay;
9357                 if ( !this.mouseDelayMet ) {
9358                         this._mouseDelayTimer = setTimeout( function() {
9359                                 that.mouseDelayMet = true;
9360                         }, this.options.delay );
9361                 }
9362 
9363                 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9364                         this._mouseStarted = ( this._mouseStart( event ) !== false );
9365                         if ( !this._mouseStarted ) {
9366                                 event.preventDefault();
9367                                 return true;
9368                         }
9369                 }
9370 
9371                 // Click event may never have fired (Gecko & Opera)
9372                 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9373                         $.removeData( event.target, this.widgetName + ".preventClickEvent" );
9374                 }
9375 
9376                 // These delegates are required to keep context
9377                 this._mouseMoveDelegate = function( event ) {
9378                         return that._mouseMove( event );
9379                 };
9380                 this._mouseUpDelegate = function( event ) {
9381                         return that._mouseUp( event );
9382                 };
9383 
9384                 this.document
9385                         .on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9386                         .on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9387 
9388                 event.preventDefault();
9389 
9390                 mouseHandled = true;
9391                 return true;
9392         },
9393 
9394         _mouseMove: function( event ) {
9395 
9396                 // Only check for mouseups outside the document if you've moved inside the document
9397                 // at least once. This prevents the firing of mouseup in the case of IE<9, which will
9398                 // fire a mousemove event if content is placed under the cursor. See #7778
9399                 // Support: IE <9
9400                 if ( this._mouseMoved ) {
9401 
9402                         // IE mouseup check - mouseup happened when mouse was out of window
9403                         if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9404                                         !event.button ) {
9405                                 return this._mouseUp( event );
9406 
9407                         // Iframe mouseup check - mouseup occurred in another document
9408                         } else if ( !event.which ) {
9409 
9410                                 // Support: Safari <=8 - 9
9411                                 // Safari sets which to 0 if you press any of the following keys
9412                                 // during a drag (#14461)
9413                                 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9414                                                 event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9415                                         this.ignoreMissingWhich = true;
9416                                 } else if ( !this.ignoreMissingWhich ) {
9417                                         return this._mouseUp( event );
9418                                 }
9419                         }
9420                 }
9421 
9422                 if ( event.which || event.button ) {
9423                         this._mouseMoved = true;
9424                 }
9425 
9426                 if ( this._mouseStarted ) {
9427                         this._mouseDrag( event );
9428                         return event.preventDefault();
9429                 }
9430 
9431                 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9432                         this._mouseStarted =
9433                                 ( this._mouseStart( this._mouseDownEvent, event ) !== false );
9434                         ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9435                 }
9436 
9437                 return !this._mouseStarted;
9438         },
9439 
9440         _mouseUp: function( event ) {
9441                 this.document
9442                         .off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9443                         .off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9444 
9445                 if ( this._mouseStarted ) {
9446                         this._mouseStarted = false;
9447 
9448                         if ( event.target === this._mouseDownEvent.target ) {
9449                                 $.data( event.target, this.widgetName + ".preventClickEvent", true );
9450                         }
9451 
9452                         this._mouseStop( event );
9453                 }
9454 
9455                 if ( this._mouseDelayTimer ) {
9456                         clearTimeout( this._mouseDelayTimer );
9457                         delete this._mouseDelayTimer;
9458                 }
9459 
9460                 this.ignoreMissingWhich = false;
9461                 mouseHandled = false;
9462                 event.preventDefault();
9463         },
9464 
9465         _mouseDistanceMet: function( event ) {
9466                 return ( Math.max(
9467                                 Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9468                                 Math.abs( this._mouseDownEvent.pageY - event.pageY )
9469                         ) >= this.options.distance
9470                 );
9471         },
9472 
9473         _mouseDelayMet: function( /* event */ ) {
9474                 return this.mouseDelayMet;
9475         },
9476 
9477         // These are placeholder methods, to be overriden by extending plugin
9478         _mouseStart: function( /* event */ ) {},
9479         _mouseDrag: function( /* event */ ) {},
9480         _mouseStop: function( /* event */ ) {},
9481         _mouseCapture: function( /* event */ ) { return true; }
9482 } );
9483 
9484 
9485 
9486 
9487 // $.ui.plugin is deprecated. Use $.widget() extensions instead.
9488 var plugin = $.ui.plugin = {
9489         add: function( module, option, set ) {
9490                 var i,
9491                         proto = $.ui[ module ].prototype;
9492                 for ( i in set ) {
9493                         proto.plugins[ i ] = proto.plugins[ i ] || [];
9494                         proto.plugins[ i ].push( [ option, set[ i ] ] );
9495                 }
9496         },
9497         call: function( instance, name, args, allowDisconnected ) {
9498                 var i,
9499                         set = instance.plugins[ name ];
9500 
9501                 if ( !set ) {
9502                         return;
9503                 }
9504 
9505                 if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9506                                 instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9507                         return;
9508                 }
9509 
9510                 for ( i = 0; i < set.length; i++ ) {
9511                         if ( instance.options[ set[ i ][ 0 ] ] ) {
9512                                 set[ i ][ 1 ].apply( instance.element, args );
9513                         }
9514                 }
9515         }
9516 };
9517 
9518 
9519 
9520 var safeBlur = $.ui.safeBlur = function( element ) {
9521 
9522         // Support: IE9 - 10 only
9523         // If the <body> is blurred, IE will switch windows, see #9420
9524         if ( element && element.nodeName.toLowerCase() !== "body" ) {
9525                 $( element ).trigger( "blur" );
9526         }
9527 };
9528 
9529 
9530 /*!
9531  * jQuery UI Draggable 1.12.1
9532  * http://jqueryui.com
9533  *
9534  * Copyright jQuery Foundation and other contributors
9535  * Released under the MIT license.
9536  * http://jquery.org/license
9537  */
9538 
9539 //>>label: Draggable
9540 //>>group: Interactions
9541 //>>description: Enables dragging functionality for any element.
9542 //>>docs: http://api.jqueryui.com/draggable/
9543 //>>demos: http://jqueryui.com/draggable/
9544 //>>css.structure: ../../themes/base/draggable.css
9545 
9546 
9547 
9548 $.widget( "ui.draggable", $.ui.mouse, {
9549         version: "1.12.1",
9550         widgetEventPrefix: "drag",
9551         options: {
9552                 addClasses: true,
9553                 appendTo: "parent",
9554                 axis: false,
9555                 connectToSortable: false,
9556                 containment: false,
9557                 cursor: "auto",
9558                 cursorAt: false,
9559                 grid: false,
9560                 handle: false,
9561                 helper: "original",
9562                 iframeFix: false,
9563                 opacity: false,
9564                 refreshPositions: false,
9565                 revert: false,
9566                 revertDuration: 500,
9567                 scope: "default",
9568                 scroll: true,
9569                 scrollSensitivity: 20,
9570                 scrollSpeed: 20,
9571                 snap: false,
9572                 snapMode: "both",
9573                 snapTolerance: 20,
9574                 stack: false,
9575                 zIndex: false,
9576 
9577                 // Callbacks
9578                 drag: null,
9579                 start: null,
9580                 stop: null
9581         },
9582         _create: function() {
9583 
9584                 if ( this.options.helper === "original" ) {
9585                         this._setPositionRelative();
9586                 }
9587                 if ( this.options.addClasses ) {
9588                         this._addClass( "ui-draggable" );
9589                 }
9590                 this._setHandleClassName();
9591 
9592                 this._mouseInit();
9593         },
9594 
9595         _setOption: function( key, value ) {
9596                 this._super( key, value );
9597                 if ( key === "handle" ) {
9598                         this._removeHandleClassName();
9599                         this._setHandleClassName();
9600                 }
9601         },
9602 
9603         _destroy: function() {
9604                 if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9605                         this.destroyOnClear = true;
9606                         return;
9607                 }
9608                 this._removeHandleClassName();
9609                 this._mouseDestroy();
9610         },
9611 
9612         _mouseCapture: function( event ) {
9613                 var o = this.options;
9614 
9615                 // Among others, prevent a drag on a resizable-handle
9616                 if ( this.helper || o.disabled ||
9617                                 $( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9618                         return false;
9619                 }
9620 
9621                 //Quit if we're not on a valid handle
9622                 this.handle = this._getHandle( event );
9623                 if ( !this.handle ) {
9624                         return false;
9625                 }
9626 
9627                 this._blurActiveElement( event );
9628 
9629                 this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9630 
9631                 return true;
9632 
9633         },
9634 
9635         _blockFrames: function( selector ) {
9636                 this.iframeBlocks = this.document.find( selector ).map( function() {
9637                         var iframe = $( this );
9638 
9639                         return $( "<div>" )
9640                                 .css( "position", "absolute" )
9641                                 .appendTo( iframe.parent() )
9642                                 .outerWidth( iframe.outerWidth() )
9643                                 .outerHeight( iframe.outerHeight() )
9644                                 .offset( iframe.offset() )[ 0 ];
9645                 } );
9646         },
9647 
9648         _unblockFrames: function() {
9649                 if ( this.iframeBlocks ) {
9650                         this.iframeBlocks.remove();
9651                         delete this.iframeBlocks;
9652                 }
9653         },
9654 
9655         _blurActiveElement: function( event ) {
9656                 var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9657                         target = $( event.target );
9658 
9659                 // Don't blur if the event occurred on an element that is within
9660                 // the currently focused element
9661                 // See #10527, #12472
9662                 if ( target.closest( activeElement ).length ) {
9663                         return;
9664                 }
9665 
9666                 // Blur any element that currently has focus, see #4261
9667                 $.ui.safeBlur( activeElement );
9668         },
9669 
9670         _mouseStart: function( event ) {
9671 
9672                 var o = this.options;
9673 
9674                 //Create and append the visible helper
9675                 this.helper = this._createHelper( event );
9676 
9677                 this._addClass( this.helper, "ui-draggable-dragging" );
9678 
9679                 //Cache the helper size
9680                 this._cacheHelperProportions();
9681 
9682                 //If ddmanager is used for droppables, set the global draggable
9683                 if ( $.ui.ddmanager ) {
9684                         $.ui.ddmanager.current = this;
9685                 }
9686 
9687                 /*
9688                  * - Position generation -
9689                  * This block generates everything position related - it's the core of draggables.
9690                  */
9691 
9692                 //Cache the margins of the original element
9693                 this._cacheMargins();
9694 
9695                 //Store the helper's css position
9696                 this.cssPosition = this.helper.css( "position" );
9697                 this.scrollParent = this.helper.scrollParent( true );
9698                 this.offsetParent = this.helper.offsetParent();
9699                 this.hasFixedAncestor = this.helper.parents().filter( function() {
9700                                 return $( this ).css( "position" ) === "fixed";
9701                         } ).length > 0;
9702 
9703                 //The element's absolute position on the page minus margins
9704                 this.positionAbs = this.element.offset();
9705                 this._refreshOffsets( event );
9706 
9707                 //Generate the original position
9708                 this.originalPosition = this.position = this._generatePosition( event, false );
9709                 this.originalPageX = event.pageX;
9710                 this.originalPageY = event.pageY;
9711 
9712                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9713                 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9714 
9715                 //Set a containment if given in the options
9716                 this._setContainment();
9717 
9718                 //Trigger event + callbacks
9719                 if ( this._trigger( "start", event ) === false ) {
9720                         this._clear();
9721                         return false;
9722                 }
9723 
9724                 //Recache the helper size
9725                 this._cacheHelperProportions();
9726 
9727                 //Prepare the droppable offsets
9728                 if ( $.ui.ddmanager && !o.dropBehaviour ) {
9729                         $.ui.ddmanager.prepareOffsets( this, event );
9730                 }
9731 
9732                 // Execute the drag once - this causes the helper not to be visible before getting its
9733                 // correct position
9734                 this._mouseDrag( event, true );
9735 
9736                 // If the ddmanager is used for droppables, inform the manager that dragging has started
9737                 // (see #5003)
9738                 if ( $.ui.ddmanager ) {
9739                         $.ui.ddmanager.dragStart( this, event );
9740                 }
9741 
9742                 return true;
9743         },
9744 
9745         _refreshOffsets: function( event ) {
9746                 this.offset = {
9747                         top: this.positionAbs.top - this.margins.top,
9748                         left: this.positionAbs.left - this.margins.left,
9749                         scroll: false,
9750                         parent: this._getParentOffset(),
9751                         relative: this._getRelativeOffset()
9752                 };
9753 
9754                 this.offset.click = {
9755                         left: event.pageX - this.offset.left,
9756                         top: event.pageY - this.offset.top
9757                 };
9758         },
9759 
9760         _mouseDrag: function( event, noPropagation ) {
9761 
9762                 // reset any necessary cached properties (see #5009)
9763                 if ( this.hasFixedAncestor ) {
9764                         this.offset.parent = this._getParentOffset();
9765                 }
9766 
9767                 //Compute the helpers position
9768                 this.position = this._generatePosition( event, true );
9769                 this.positionAbs = this._convertPositionTo( "absolute" );
9770 
9771                 //Call plugins and callbacks and use the resulting position if something is returned
9772                 if ( !noPropagation ) {
9773                         var ui = this._uiHash();
9774                         if ( this._trigger( "drag", event, ui ) === false ) {
9775                                 this._mouseUp( new $.Event( "mouseup", event ) );
9776                                 return false;
9777                         }
9778                         this.position = ui.position;
9779                 }
9780 
9781                 this.helper[ 0 ].style.left = this.position.left + "px";
9782                 this.helper[ 0 ].style.top = this.position.top + "px";
9783 
9784                 if ( $.ui.ddmanager ) {
9785                         $.ui.ddmanager.drag( this, event );
9786                 }
9787 
9788                 return false;
9789         },
9790 
9791         _mouseStop: function( event ) {
9792 
9793                 //If we are using droppables, inform the manager about the drop
9794                 var that = this,
9795                         dropped = false;
9796                 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9797                         dropped = $.ui.ddmanager.drop( this, event );
9798                 }
9799 
9800                 //if a drop comes from outside (a sortable)
9801                 if ( this.dropped ) {
9802                         dropped = this.dropped;
9803                         this.dropped = false;
9804                 }
9805 
9806                 if ( ( this.options.revert === "invalid" && !dropped ) ||
9807                                 ( this.options.revert === "valid" && dropped ) ||
9808                                 this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9809                                 this.options.revert.call( this.element, dropped ) )
9810                 ) {
9811                         $( this.helper ).animate(
9812                                 this.originalPosition,
9813                                 parseInt( this.options.revertDuration, 10 ),
9814                                 function() {
9815                                         if ( that._trigger( "stop", event ) !== false ) {
9816                                                 that._clear();
9817                                         }
9818                                 }
9819                         );
9820                 } else {
9821                         if ( this._trigger( "stop", event ) !== false ) {
9822                                 this._clear();
9823                         }
9824                 }
9825 
9826                 return false;
9827         },
9828 
9829         _mouseUp: function( event ) {
9830                 this._unblockFrames();
9831 
9832                 // If the ddmanager is used for droppables, inform the manager that dragging has stopped
9833                 // (see #5003)
9834                 if ( $.ui.ddmanager ) {
9835                         $.ui.ddmanager.dragStop( this, event );
9836                 }
9837 
9838                 // Only need to focus if the event occurred on the draggable itself, see #10527
9839                 if ( this.handleElement.is( event.target ) ) {
9840 
9841                         // The interaction is over; whether or not the click resulted in a drag,
9842                         // focus the element
9843                         this.element.trigger( "focus" );
9844                 }
9845 
9846                 return $.ui.mouse.prototype._mouseUp.call( this, event );
9847         },
9848 
9849         cancel: function() {
9850 
9851                 if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9852                         this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9853                 } else {
9854                         this._clear();
9855                 }
9856 
9857                 return this;
9858 
9859         },
9860 
9861         _getHandle: function( event ) {
9862                 return this.options.handle ?
9863                         !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9864                         true;
9865         },
9866 
9867         _setHandleClassName: function() {
9868                 this.handleElement = this.options.handle ?
9869                         this.element.find( this.options.handle ) : this.element;
9870                 this._addClass( this.handleElement, "ui-draggable-handle" );
9871         },
9872 
9873         _removeHandleClassName: function() {
9874                 this._removeClass( this.handleElement, "ui-draggable-handle" );
9875         },
9876 
9877         _createHelper: function( event ) {
9878 
9879                 var o = this.options,
9880                         helperIsFunction = $.isFunction( o.helper ),
9881                         helper = helperIsFunction ?
9882                                 $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9883                                 ( o.helper === "clone" ?
9884                                         this.element.clone().removeAttr( "id" ) :
9885                                         this.element );
9886 
9887                 if ( !helper.parents( "body" ).length ) {
9888                         helper.appendTo( ( o.appendTo === "parent" ?
9889                                 this.element[ 0 ].parentNode :
9890                                 o.appendTo ) );
9891                 }
9892 
9893                 // Http://bugs.jqueryui.com/ticket/9446
9894                 // a helper function can return the original element
9895                 // which wouldn't have been set to relative in _create
9896                 if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9897                         this._setPositionRelative();
9898                 }
9899 
9900                 if ( helper[ 0 ] !== this.element[ 0 ] &&
9901                                 !( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9902                         helper.css( "position", "absolute" );
9903                 }
9904 
9905                 return helper;
9906 
9907         },
9908 
9909         _setPositionRelative: function() {
9910                 if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9911                         this.element[ 0 ].style.position = "relative";
9912                 }
9913         },
9914 
9915         _adjustOffsetFromHelper: function( obj ) {
9916                 if ( typeof obj === "string" ) {
9917                         obj = obj.split( " " );
9918                 }
9919                 if ( $.isArray( obj ) ) {
9920                         obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9921                 }
9922                 if ( "left" in obj ) {
9923                         this.offset.click.left = obj.left + this.margins.left;
9924                 }
9925                 if ( "right" in obj ) {
9926                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9927                 }
9928                 if ( "top" in obj ) {
9929                         this.offset.click.top = obj.top + this.margins.top;
9930                 }
9931                 if ( "bottom" in obj ) {
9932                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9933                 }
9934         },
9935 
9936         _isRootNode: function( element ) {
9937                 return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9938         },
9939 
9940         _getParentOffset: function() {
9941 
9942                 //Get the offsetParent and cache its position
9943                 var po = this.offsetParent.offset(),
9944                         document = this.document[ 0 ];
9945 
9946                 // This is a special case where we need to modify a offset calculated on start, since the
9947                 // following happened:
9948                 // 1. The position of the helper is absolute, so it's position is calculated based on the
9949                 // next positioned parent
9950                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9951                 // the document, which means that the scroll is included in the initial calculation of the
9952                 // offset of the parent, and never recalculated upon drag
9953                 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9954                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9955                         po.left += this.scrollParent.scrollLeft();
9956                         po.top += this.scrollParent.scrollTop();
9957                 }
9958 
9959                 if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9960                         po = { top: 0, left: 0 };
9961                 }
9962 
9963                 return {
9964                         top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9965                         left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9966                 };
9967 
9968         },
9969 
9970         _getRelativeOffset: function() {
9971                 if ( this.cssPosition !== "relative" ) {
9972                         return { top: 0, left: 0 };
9973                 }
9974 
9975                 var p = this.element.position(),
9976                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9977 
9978                 return {
9979                         top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9980                                 ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9981                         left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9982                                 ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9983                 };
9984 
9985         },
9986 
9987         _cacheMargins: function() {
9988                 this.margins = {
9989                         left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9990                         top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9991                         right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9992                         bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9993                 };
9994         },
9995 
9996         _cacheHelperProportions: function() {
9997                 this.helperProportions = {
9998                         width: this.helper.outerWidth(),
9999                         height: this.helper.outerHeight()
10000                 };
10001         },
10002 
10003         _setContainment: function() {
10004 
10005                 var isUserScrollable, c, ce,
10006                         o = this.options,
10007                         document = this.document[ 0 ];
10008 
10009                 this.relativeContainer = null;
10010 
10011                 if ( !o.containment ) {
10012                         this.containment = null;
10013                         return;
10014                 }
10015 
10016                 if ( o.containment === "window" ) {
10017                         this.containment = [
10018                                 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10019                                 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10020                                 $( window ).scrollLeft() + $( window ).width() -
10021                                         this.helperProportions.width - this.margins.left,
10022                                 $( window ).scrollTop() +
10023                                         ( $( window ).height() || document.body.parentNode.scrollHeight ) -
10024                                         this.helperProportions.height - this.margins.top
10025                         ];
10026                         return;
10027                 }
10028 
10029                 if ( o.containment === "document" ) {
10030                         this.containment = [
10031                                 0,
10032                                 0,
10033                                 $( document ).width() - this.helperProportions.width - this.margins.left,
10034                                 ( $( document ).height() || document.body.parentNode.scrollHeight ) -
10035                                         this.helperProportions.height - this.margins.top
10036                         ];
10037                         return;
10038                 }
10039 
10040                 if ( o.containment.constructor === Array ) {
10041                         this.containment = o.containment;
10042                         return;
10043                 }
10044 
10045                 if ( o.containment === "parent" ) {
10046                         o.containment = this.helper[ 0 ].parentNode;
10047                 }
10048 
10049                 c = $( o.containment );
10050                 ce = c[ 0 ];
10051 
10052                 if ( !ce ) {
10053                         return;
10054                 }
10055 
10056                 isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10057 
10058                 this.containment = [
10059                         ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10060                                 ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10061                         ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10062                                 ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10063                         ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10064                                 ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10065                                 ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10066                                 this.helperProportions.width -
10067                                 this.margins.left -
10068                                 this.margins.right,
10069                         ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10070                                 ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10071                                 ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10072                                 this.helperProportions.height -
10073                                 this.margins.top -
10074                                 this.margins.bottom
10075                 ];
10076                 this.relativeContainer = c;
10077         },
10078 
10079         _convertPositionTo: function( d, pos ) {
10080 
10081                 if ( !pos ) {
10082                         pos = this.position;
10083                 }
10084 
10085                 var mod = d === "absolute" ? 1 : -1,
10086                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10087 
10088                 return {
10089                         top: (
10090 
10091                                 // The absolute mouse position
10092                                 pos.top +
10093 
10094                                 // Only for relative positioned nodes: Relative offset from element to offset parent
10095                                 this.offset.relative.top * mod +
10096 
10097                                 // The offsetParent's offset without borders (offset + border)
10098                                 this.offset.parent.top * mod -
10099                                 ( ( this.cssPosition === "fixed" ?
10100                                         -this.offset.scroll.top :
10101                                         ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10102                         ),
10103                         left: (
10104 
10105                                 // The absolute mouse position
10106                                 pos.left +
10107 
10108                                 // Only for relative positioned nodes: Relative offset from element to offset parent
10109                                 this.offset.relative.left * mod +
10110 
10111                                 // The offsetParent's offset without borders (offset + border)
10112                                 this.offset.parent.left * mod   -
10113                                 ( ( this.cssPosition === "fixed" ?
10114                                         -this.offset.scroll.left :
10115                                         ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10116                         )
10117                 };
10118 
10119         },
10120 
10121         _generatePosition: function( event, constrainPosition ) {
10122 
10123                 var containment, co, top, left,
10124                         o = this.options,
10125                         scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10126                         pageX = event.pageX,
10127                         pageY = event.pageY;
10128 
10129                 // Cache the scroll
10130                 if ( !scrollIsRootNode || !this.offset.scroll ) {
10131                         this.offset.scroll = {
10132                                 top: this.scrollParent.scrollTop(),
10133                                 left: this.scrollParent.scrollLeft()
10134                         };
10135                 }
10136 
10137                 /*
10138                  * - Position constraining -
10139                  * Constrain the position to a mix of grid, containment.
10140                  */
10141 
10142                 // If we are not dragging yet, we won't check for options
10143                 if ( constrainPosition ) {
10144                         if ( this.containment ) {
10145                                 if ( this.relativeContainer ) {
10146                                         co = this.relativeContainer.offset();
10147                                         containment = [
10148                                                 this.containment[ 0 ] + co.left,
10149                                                 this.containment[ 1 ] + co.top,
10150                                                 this.containment[ 2 ] + co.left,
10151                                                 this.containment[ 3 ] + co.top
10152                                         ];
10153                                 } else {
10154                                         containment = this.containment;
10155                                 }
10156 
10157                                 if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10158                                         pageX = containment[ 0 ] + this.offset.click.left;
10159                                 }
10160                                 if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10161                                         pageY = containment[ 1 ] + this.offset.click.top;
10162                                 }
10163                                 if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10164                                         pageX = containment[ 2 ] + this.offset.click.left;
10165                                 }
10166                                 if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10167                                         pageY = containment[ 3 ] + this.offset.click.top;
10168                                 }
10169                         }
10170 
10171                         if ( o.grid ) {
10172 
10173                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10174                                 // argument errors in IE (see ticket #6950)
10175                                 top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10176                                         this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10177                                 pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10178                                         top - this.offset.click.top > containment[ 3 ] ) ?
10179                                                 top :
10180                                                 ( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10181                                                         top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10182 
10183                                 left = o.grid[ 0 ] ? this.originalPageX +
10184                                         Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10185                                         this.originalPageX;
10186                                 pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10187                                         left - this.offset.click.left > containment[ 2 ] ) ?
10188                                                 left :
10189                                                 ( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10190                                                         left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10191                         }
10192 
10193                         if ( o.axis === "y" ) {
10194                                 pageX = this.originalPageX;
10195                         }
10196 
10197                         if ( o.axis === "x" ) {
10198                                 pageY = this.originalPageY;
10199                         }
10200                 }
10201 
10202                 return {
10203                         top: (
10204 
10205                                 // The absolute mouse position
10206                                 pageY -
10207 
10208                                 // Click offset (relative to the element)
10209                                 this.offset.click.top -
10210 
10211                                 // Only for relative positioned nodes: Relative offset from element to offset parent
10212                                 this.offset.relative.top -
10213 
10214                                 // The offsetParent's offset without borders (offset + border)
10215                                 this.offset.parent.top +
10216                                 ( this.cssPosition === "fixed" ?
10217                                         -this.offset.scroll.top :
10218                                         ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10219                         ),
10220                         left: (
10221 
10222                                 // The absolute mouse position
10223                                 pageX -
10224 
10225                                 // Click offset (relative to the element)
10226                                 this.offset.click.left -
10227 
10228                                 // Only for relative positioned nodes: Relative offset from element to offset parent
10229                                 this.offset.relative.left -
10230 
10231                                 // The offsetParent's offset without borders (offset + border)
10232                                 this.offset.parent.left +
10233                                 ( this.cssPosition === "fixed" ?
10234                                         -this.offset.scroll.left :
10235                                         ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10236                         )
10237                 };
10238 
10239         },
10240 
10241         _clear: function() {
10242                 this._removeClass( this.helper, "ui-draggable-dragging" );
10243                 if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10244                         this.helper.remove();
10245                 }
10246                 this.helper = null;
10247                 this.cancelHelperRemoval = false;
10248                 if ( this.destroyOnClear ) {
10249                         this.destroy();
10250                 }
10251         },
10252 
10253         // From now on bulk stuff - mainly helpers
10254 
10255         _trigger: function( type, event, ui ) {
10256                 ui = ui || this._uiHash();
10257                 $.ui.plugin.call( this, type, [ event, ui, this ], true );
10258 
10259                 // Absolute position and offset (see #6884 ) have to be recalculated after plugins
10260                 if ( /^(drag|start|stop)/.test( type ) ) {
10261                         this.positionAbs = this._convertPositionTo( "absolute" );
10262                         ui.offset = this.positionAbs;
10263                 }
10264                 return $.Widget.prototype._trigger.call( this, type, event, ui );
10265         },
10266 
10267         plugins: {},
10268 
10269         _uiHash: function() {
10270                 return {
10271                         helper: this.helper,
10272                         position: this.position,
10273                         originalPosition: this.originalPosition,
10274                         offset: this.positionAbs
10275                 };
10276         }
10277 
10278 } );
10279 
10280 $.ui.plugin.add( "draggable", "connectToSortable", {
10281         start: function( event, ui, draggable ) {
10282                 var uiSortable = $.extend( {}, ui, {
10283                         item: draggable.element
10284                 } );
10285 
10286                 draggable.sortables = [];
10287                 $( draggable.options.connectToSortable ).each( function() {
10288                         var sortable = $( this ).sortable( "instance" );
10289 
10290                         if ( sortable && !sortable.options.disabled ) {
10291                                 draggable.sortables.push( sortable );
10292 
10293                                 // RefreshPositions is called at drag start to refresh the containerCache
10294                                 // which is used in drag. This ensures it's initialized and synchronized
10295                                 // with any changes that might have happened on the page since initialization.
10296                                 sortable.refreshPositions();
10297                                 sortable._trigger( "activate", event, uiSortable );
10298                         }
10299                 } );
10300         },
10301         stop: function( event, ui, draggable ) {
10302                 var uiSortable = $.extend( {}, ui, {
10303                         item: draggable.element
10304                 } );
10305 
10306                 draggable.cancelHelperRemoval = false;
10307 
10308                 $.each( draggable.sortables, function() {
10309                         var sortable = this;
10310 
10311                         if ( sortable.isOver ) {
10312                                 sortable.isOver = 0;
10313 
10314                                 // Allow this sortable to handle removing the helper
10315                                 draggable.cancelHelperRemoval = true;
10316                                 sortable.cancelHelperRemoval = false;
10317 
10318                                 // Use _storedCSS To restore properties in the sortable,
10319                                 // as this also handles revert (#9675) since the draggable
10320                                 // may have modified them in unexpected ways (#8809)
10321                                 sortable._storedCSS = {
10322                                         position: sortable.placeholder.css( "position" ),
10323                                         top: sortable.placeholder.css( "top" ),
10324                                         left: sortable.placeholder.css( "left" )
10325                                 };
10326 
10327                                 sortable._mouseStop( event );
10328 
10329                                 // Once drag has ended, the sortable should return to using
10330                                 // its original helper, not the shared helper from draggable
10331                                 sortable.options.helper = sortable.options._helper;
10332                         } else {
10333 
10334                                 // Prevent this Sortable from removing the helper.
10335                                 // However, don't set the draggable to remove the helper
10336                                 // either as another connected Sortable may yet handle the removal.
10337                                 sortable.cancelHelperRemoval = true;
10338 
10339                                 sortable._trigger( "deactivate", event, uiSortable );
10340                         }
10341                 } );
10342         },
10343         drag: function( event, ui, draggable ) {
10344                 $.each( draggable.sortables, function() {
10345                         var innermostIntersecting = false,
10346                                 sortable = this;
10347 
10348                         // Copy over variables that sortable's _intersectsWith uses
10349                         sortable.positionAbs = draggable.positionAbs;
10350                         sortable.helperProportions = draggable.helperProportions;
10351                         sortable.offset.click = draggable.offset.click;
10352 
10353                         if ( sortable._intersectsWith( sortable.containerCache ) ) {
10354                                 innermostIntersecting = true;
10355 
10356                                 $.each( draggable.sortables, function() {
10357 
10358                                         // Copy over variables that sortable's _intersectsWith uses
10359                                         this.positionAbs = draggable.positionAbs;
10360                                         this.helperProportions = draggable.helperProportions;
10361                                         this.offset.click = draggable.offset.click;
10362 
10363                                         if ( this !== sortable &&
10364                                                         this._intersectsWith( this.containerCache ) &&
10365                                                         $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10366                                                 innermostIntersecting = false;
10367                                         }
10368 
10369                                         return innermostIntersecting;
10370                                 } );
10371                         }
10372 
10373                         if ( innermostIntersecting ) {
10374 
10375                                 // If it intersects, we use a little isOver variable and set it once,
10376                                 // so that the move-in stuff gets fired only once.
10377                                 if ( !sortable.isOver ) {
10378                                         sortable.isOver = 1;
10379 
10380                                         // Store draggable's parent in case we need to reappend to it later.
10381                                         draggable._parent = ui.helper.parent();
10382 
10383                                         sortable.currentItem = ui.helper
10384                                                 .appendTo( sortable.element )
10385                                                 .data( "ui-sortable-item", true );
10386 
10387                                         // Store helper option to later restore it
10388                                         sortable.options._helper = sortable.options.helper;
10389 
10390                                         sortable.options.helper = function() {
10391                                                 return ui.helper[ 0 ];
10392                                         };
10393 
10394                                         // Fire the start events of the sortable with our passed browser event,
10395                                         // and our own helper (so it doesn't create a new one)
10396                                         event.target = sortable.currentItem[ 0 ];
10397                                         sortable._mouseCapture( event, true );
10398                                         sortable._mouseStart( event, true, true );
10399 
10400                                         // Because the browser event is way off the new appended portlet,
10401                                         // modify necessary variables to reflect the changes
10402                                         sortable.offset.click.top = draggable.offset.click.top;
10403                                         sortable.offset.click.left = draggable.offset.click.left;
10404                                         sortable.offset.parent.left -= draggable.offset.parent.left -
10405                                                 sortable.offset.parent.left;
10406                                         sortable.offset.parent.top -= draggable.offset.parent.top -
10407                                                 sortable.offset.parent.top;
10408 
10409                                         draggable._trigger( "toSortable", event );
10410 
10411                                         // Inform draggable that the helper is in a valid drop zone,
10412                                         // used solely in the revert option to handle "valid/invalid".
10413                                         draggable.dropped = sortable.element;
10414 
10415                                         // Need to refreshPositions of all sortables in the case that
10416                                         // adding to one sortable changes the location of the other sortables (#9675)
10417                                         $.each( draggable.sortables, function() {
10418                                                 this.refreshPositions();
10419                                         } );
10420 
10421                                         // Hack so receive/update callbacks work (mostly)
10422                                         draggable.currentItem = draggable.element;
10423                                         sortable.fromOutside = draggable;
10424                                 }
10425 
10426                                 if ( sortable.currentItem ) {
10427                                         sortable._mouseDrag( event );
10428 
10429                                         // Copy the sortable's position because the draggable's can potentially reflect
10430                                         // a relative position, while sortable is always absolute, which the dragged
10431                                         // element has now become. (#8809)
10432                                         ui.position = sortable.position;
10433                                 }
10434                         } else {
10435 
10436                                 // If it doesn't intersect with the sortable, and it intersected before,
10437                                 // we fake the drag stop of the sortable, but make sure it doesn't remove
10438                                 // the helper by using cancelHelperRemoval.
10439                                 if ( sortable.isOver ) {
10440 
10441                                         sortable.isOver = 0;
10442                                         sortable.cancelHelperRemoval = true;
10443 
10444                                         // Calling sortable's mouseStop would trigger a revert,
10445                                         // so revert must be temporarily false until after mouseStop is called.
10446                                         sortable.options._revert = sortable.options.revert;
10447                                         sortable.options.revert = false;
10448 
10449                                         sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10450                                         sortable._mouseStop( event, true );
10451 
10452                                         // Restore sortable behaviors that were modfied
10453                                         // when the draggable entered the sortable area (#9481)
10454                                         sortable.options.revert = sortable.options._revert;
10455                                         sortable.options.helper = sortable.options._helper;
10456 
10457                                         if ( sortable.placeholder ) {
10458                                                 sortable.placeholder.remove();
10459                                         }
10460 
10461                                         // Restore and recalculate the draggable's offset considering the sortable
10462                                         // may have modified them in unexpected ways. (#8809, #10669)
10463                                         ui.helper.appendTo( draggable._parent );
10464                                         draggable._refreshOffsets( event );
10465                                         ui.position = draggable._generatePosition( event, true );
10466 
10467                                         draggable._trigger( "fromSortable", event );
10468 
10469                                         // Inform draggable that the helper is no longer in a valid drop zone
10470                                         draggable.dropped = false;
10471 
10472                                         // Need to refreshPositions of all sortables just in case removing
10473                                         // from one sortable changes the location of other sortables (#9675)
10474                                         $.each( draggable.sortables, function() {
10475                                                 this.refreshPositions();
10476                                         } );
10477                                 }
10478                         }
10479                 } );
10480         }
10481 } );
10482 
10483 $.ui.plugin.add( "draggable", "cursor", {
10484         start: function( event, ui, instance ) {
10485                 var t = $( "body" ),
10486                         o = instance.options;
10487 
10488                 if ( t.css( "cursor" ) ) {
10489                         o._cursor = t.css( "cursor" );
10490                 }
10491                 t.css( "cursor", o.cursor );
10492         },
10493         stop: function( event, ui, instance ) {
10494                 var o = instance.options;
10495                 if ( o._cursor ) {
10496                         $( "body" ).css( "cursor", o._cursor );
10497                 }
10498         }
10499 } );
10500 
10501 $.ui.plugin.add( "draggable", "opacity", {
10502         start: function( event, ui, instance ) {
10503                 var t = $( ui.helper ),
10504                         o = instance.options;
10505                 if ( t.css( "opacity" ) ) {
10506                         o._opacity = t.css( "opacity" );
10507                 }
10508                 t.css( "opacity", o.opacity );
10509         },
10510         stop: function( event, ui, instance ) {
10511                 var o = instance.options;
10512                 if ( o._opacity ) {
10513                         $( ui.helper ).css( "opacity", o._opacity );
10514                 }
10515         }
10516 } );
10517 
10518 $.ui.plugin.add( "draggable", "scroll", {
10519         start: function( event, ui, i ) {
10520                 if ( !i.scrollParentNotHidden ) {
10521                         i.scrollParentNotHidden = i.helper.scrollParent( false );
10522                 }
10523 
10524                 if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10525                                 i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10526                         i.overflowOffset = i.scrollParentNotHidden.offset();
10527                 }
10528         },
10529         drag: function( event, ui, i  ) {
10530 
10531                 var o = i.options,
10532                         scrolled = false,
10533                         scrollParent = i.scrollParentNotHidden[ 0 ],
10534                         document = i.document[ 0 ];
10535 
10536                 if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10537                         if ( !o.axis || o.axis !== "x" ) {
10538                                 if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10539                                                 o.scrollSensitivity ) {
10540                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10541                                 } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10542                                         scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10543                                 }
10544                         }
10545 
10546                         if ( !o.axis || o.axis !== "y" ) {
10547                                 if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10548                                                 o.scrollSensitivity ) {
10549                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10550                                 } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10551                                         scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10552                                 }
10553                         }
10554 
10555                 } else {
10556 
10557                         if ( !o.axis || o.axis !== "x" ) {
10558                                 if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10559                                         scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10560                                 } else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10561                                                 o.scrollSensitivity ) {
10562                                         scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10563                                 }
10564                         }
10565 
10566                         if ( !o.axis || o.axis !== "y" ) {
10567                                 if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10568                                         scrolled = $( document ).scrollLeft(
10569                                                 $( document ).scrollLeft() - o.scrollSpeed
10570                                         );
10571                                 } else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10572                                                 o.scrollSensitivity ) {
10573                                         scrolled = $( document ).scrollLeft(
10574                                                 $( document ).scrollLeft() + o.scrollSpeed
10575                                         );
10576                                 }
10577                         }
10578 
10579                 }
10580 
10581                 if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10582                         $.ui.ddmanager.prepareOffsets( i, event );
10583                 }
10584 
10585         }
10586 } );
10587 
10588 $.ui.plugin.add( "draggable", "snap", {
10589         start: function( event, ui, i ) {
10590 
10591                 var o = i.options;
10592 
10593                 i.snapElements = [];
10594 
10595                 $( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10596                         .each( function() {
10597                                 var $t = $( this ),
10598                                         $o = $t.offset();
10599                                 if ( this !== i.element[ 0 ] ) {
10600                                         i.snapElements.push( {
10601                                                 item: this,
10602                                                 width: $t.outerWidth(), height: $t.outerHeight(),
10603                                                 top: $o.top, left: $o.left
10604                                         } );
10605                                 }
10606                         } );
10607 
10608         },
10609         drag: function( event, ui, inst ) {
10610 
10611                 var ts, bs, ls, rs, l, r, t, b, i, first,
10612                         o = inst.options,
10613                         d = o.snapTolerance,
10614                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10615                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10616 
10617                 for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10618 
10619                         l = inst.snapElements[ i ].left - inst.margins.left;
10620                         r = l + inst.snapElements[ i ].width;
10621                         t = inst.snapElements[ i ].top - inst.margins.top;
10622                         b = t + inst.snapElements[ i ].height;
10623 
10624                         if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10625                                         !$.contains( inst.snapElements[ i ].item.ownerDocument,
10626                                         inst.snapElements[ i ].item ) ) {
10627                                 if ( inst.snapElements[ i ].snapping ) {
10628                                         ( inst.options.snap.release &&
10629                                                 inst.options.snap.release.call(
10630                                                         inst.element,
10631                                                         event,
10632                                                         $.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10633                                                 ) );
10634                                 }
10635                                 inst.snapElements[ i ].snapping = false;
10636                                 continue;
10637                         }
10638 
10639                         if ( o.snapMode !== "inner" ) {
10640                                 ts = Math.abs( t - y2 ) <= d;
10641                                 bs = Math.abs( b - y1 ) <= d;
10642                                 ls = Math.abs( l - x2 ) <= d;
10643                                 rs = Math.abs( r - x1 ) <= d;
10644                                 if ( ts ) {
10645                                         ui.position.top = inst._convertPositionTo( "relative", {
10646                                                 top: t - inst.helperProportions.height,
10647                                                 left: 0
10648                                         } ).top;
10649                                 }
10650                                 if ( bs ) {
10651                                         ui.position.top = inst._convertPositionTo( "relative", {
10652                                                 top: b,
10653                                                 left: 0
10654                                         } ).top;
10655                                 }
10656                                 if ( ls ) {
10657                                         ui.position.left = inst._convertPositionTo( "relative", {
10658                                                 top: 0,
10659                                                 left: l - inst.helperProportions.width
10660                                         } ).left;
10661                                 }
10662                                 if ( rs ) {
10663                                         ui.position.left = inst._convertPositionTo( "relative", {
10664                                                 top: 0,
10665                                                 left: r
10666                                         } ).left;
10667                                 }
10668                         }
10669 
10670                         first = ( ts || bs || ls || rs );
10671 
10672                         if ( o.snapMode !== "outer" ) {
10673                                 ts = Math.abs( t - y1 ) <= d;
10674                                 bs = Math.abs( b - y2 ) <= d;
10675                                 ls = Math.abs( l - x1 ) <= d;
10676                                 rs = Math.abs( r - x2 ) <= d;
10677                                 if ( ts ) {
10678                                         ui.position.top = inst._convertPositionTo( "relative", {
10679                                                 top: t,
10680                                                 left: 0
10681                                         } ).top;
10682                                 }
10683                                 if ( bs ) {
10684                                         ui.position.top = inst._convertPositionTo( "relative", {
10685                                                 top: b - inst.helperProportions.height,
10686                                                 left: 0
10687                                         } ).top;
10688                                 }
10689                                 if ( ls ) {
10690                                         ui.position.left = inst._convertPositionTo( "relative", {
10691                                                 top: 0,
10692                                                 left: l
10693                                         } ).left;
10694                                 }
10695                                 if ( rs ) {
10696                                         ui.position.left = inst._convertPositionTo( "relative", {
10697                                                 top: 0,
10698                                                 left: r - inst.helperProportions.width
10699                                         } ).left;
10700                                 }
10701                         }
10702 
10703                         if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10704                                 ( inst.options.snap.snap &&
10705                                         inst.options.snap.snap.call(
10706                                                 inst.element,
10707                                                 event,
10708                                                 $.extend( inst._uiHash(), {
10709                                                         snapItem: inst.snapElements[ i ].item
10710                                                 } ) ) );
10711                         }
10712                         inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10713 
10714                 }
10715 
10716         }
10717 } );
10718 
10719 $.ui.plugin.add( "draggable", "stack", {
10720         start: function( event, ui, instance ) {
10721                 var min,
10722                         o = instance.options,
10723                         group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10724                                 return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10725                                         ( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10726                         } );
10727 
10728                 if ( !group.length ) { return; }
10729 
10730                 min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10731                 $( group ).each( function( i ) {
10732                         $( this ).css( "zIndex", min + i );
10733                 } );
10734                 this.css( "zIndex", ( min + group.length ) );
10735         }
10736 } );
10737 
10738 $.ui.plugin.add( "draggable", "zIndex", {
10739         start: function( event, ui, instance ) {
10740                 var t = $( ui.helper ),
10741                         o = instance.options;
10742 
10743                 if ( t.css( "zIndex" ) ) {
10744                         o._zIndex = t.css( "zIndex" );
10745                 }
10746                 t.css( "zIndex", o.zIndex );
10747         },
10748         stop: function( event, ui, instance ) {
10749                 var o = instance.options;
10750 
10751                 if ( o._zIndex ) {
10752                         $( ui.helper ).css( "zIndex", o._zIndex );
10753                 }
10754         }
10755 } );
10756 
10757 var widgetsDraggable = $.ui.draggable;
10758 
10759 
10760 /*!
10761  * jQuery UI Resizable 1.12.1
10762  * http://jqueryui.com
10763  *
10764  * Copyright jQuery Foundation and other contributors
10765  * Released under the MIT license.
10766  * http://jquery.org/license
10767  */
10768 
10769 //>>label: Resizable
10770 //>>group: Interactions
10771 //>>description: Enables resize functionality for any element.
10772 //>>docs: http://api.jqueryui.com/resizable/
10773 //>>demos: http://jqueryui.com/resizable/
10774 //>>css.structure: ../../themes/base/core.css
10775 //>>css.structure: ../../themes/base/resizable.css
10776 //>>css.theme: ../../themes/base/theme.css
10777 
10778 
10779 
10780 $.widget( "ui.resizable", $.ui.mouse, {
10781         version: "1.12.1",
10782         widgetEventPrefix: "resize",
10783         options: {
10784                 alsoResize: false,
10785                 animate: false,
10786                 animateDuration: "slow",
10787                 animateEasing: "swing",
10788                 aspectRatio: false,
10789                 autoHide: false,
10790                 classes: {
10791                         "ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10792                 },
10793                 containment: false,
10794                 ghost: false,
10795                 grid: false,
10796                 handles: "e,s,se",
10797                 helper: false,
10798                 maxHeight: null,
10799                 maxWidth: null,
10800                 minHeight: 10,
10801                 minWidth: 10,
10802 
10803                 // See #7960
10804                 zIndex: 90,
10805 
10806                 // Callbacks
10807                 resize: null,
10808                 start: null,
10809                 stop: null
10810         },
10811 
10812         _num: function( value ) {
10813                 return parseFloat( value ) || 0;
10814         },
10815 
10816         _isNumber: function( value ) {
10817                 return !isNaN( parseFloat( value ) );
10818         },
10819 
10820         _hasScroll: function( el, a ) {
10821 
10822                 if ( $( el ).css( "overflow" ) === "hidden" ) {
10823                         return false;
10824                 }
10825 
10826                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10827                         has = false;
10828 
10829                 if ( el[ scroll ] > 0 ) {
10830                         return true;
10831                 }
10832 
10833                 // TODO: determine which cases actually cause this to happen
10834                 // if the element doesn't have the scroll set, see if it's possible to
10835                 // set the scroll
10836                 el[ scroll ] = 1;
10837                 has = ( el[ scroll ] > 0 );
10838                 el[ scroll ] = 0;
10839                 return has;
10840         },
10841 
10842         _create: function() {
10843 
10844                 var margins,
10845                         o = this.options,
10846                         that = this;
10847                 this._addClass( "ui-resizable" );
10848 
10849                 $.extend( this, {
10850                         _aspectRatio: !!( o.aspectRatio ),
10851                         aspectRatio: o.aspectRatio,
10852                         originalElement: this.element,
10853                         _proportionallyResizeElements: [],
10854                         _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10855                 } );
10856 
10857                 // Wrap the element if it cannot hold child nodes
10858                 if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10859 
10860                         this.element.wrap(
10861                                 $( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10862                                         position: this.element.css( "position" ),
10863                                         width: this.element.outerWidth(),
10864                                         height: this.element.outerHeight(),
10865                                         top: this.element.css( "top" ),
10866                                         left: this.element.css( "left" )
10867                                 } )
10868                         );
10869 
10870                         this.element = this.element.parent().data(
10871                                 "ui-resizable", this.element.resizable( "instance" )
10872                         );
10873 
10874                         this.elementIsWrapper = true;
10875 
10876                         margins = {
10877                                 marginTop: this.originalElement.css( "marginTop" ),
10878                                 marginRight: this.originalElement.css( "marginRight" ),
10879                                 marginBottom: this.originalElement.css( "marginBottom" ),
10880                                 marginLeft: this.originalElement.css( "marginLeft" )
10881                         };
10882 
10883                         this.element.css( margins );
10884                         this.originalElement.css( "margin", 0 );
10885 
10886                         // support: Safari
10887                         // Prevent Safari textarea resize
10888                         this.originalResizeStyle = this.originalElement.css( "resize" );
10889                         this.originalElement.css( "resize", "none" );
10890 
10891                         this._proportionallyResizeElements.push( this.originalElement.css( {
10892                                 position: "static",
10893                                 zoom: 1,
10894                                 display: "block"
10895                         } ) );
10896 
10897                         // Support: IE9
10898                         // avoid IE jump (hard set the margin)
10899                         this.originalElement.css( margins );
10900 
10901                         this._proportionallyResize();
10902                 }
10903 
10904                 this._setupHandles();
10905 
10906                 if ( o.autoHide ) {
10907                         $( this.element )
10908                                 .on( "mouseenter", function() {
10909                                         if ( o.disabled ) {
10910                                                 return;
10911                                         }
10912                                         that._removeClass( "ui-resizable-autohide" );
10913                                         that._handles.show();
10914                                 } )
10915                                 .on( "mouseleave", function() {
10916                                         if ( o.disabled ) {
10917                                                 return;
10918                                         }
10919                                         if ( !that.resizing ) {
10920                                                 that._addClass( "ui-resizable-autohide" );
10921                                                 that._handles.hide();
10922                                         }
10923                                 } );
10924                 }
10925 
10926                 this._mouseInit();
10927         },
10928 
10929         _destroy: function() {
10930 
10931                 this._mouseDestroy();
10932 
10933                 var wrapper,
10934                         _destroy = function( exp ) {
10935                                 $( exp )
10936                                         .removeData( "resizable" )
10937                                         .removeData( "ui-resizable" )
10938                                         .off( ".resizable" )
10939                                         .find( ".ui-resizable-handle" )
10940                                                 .remove();
10941                         };
10942 
10943                 // TODO: Unwrap at same DOM position
10944                 if ( this.elementIsWrapper ) {
10945                         _destroy( this.element );
10946                         wrapper = this.element;
10947                         this.originalElement.css( {
10948                                 position: wrapper.css( "position" ),
10949                                 width: wrapper.outerWidth(),
10950                                 height: wrapper.outerHeight(),
10951                                 top: wrapper.css( "top" ),
10952                                 left: wrapper.css( "left" )
10953                         } ).insertAfter( wrapper );
10954                         wrapper.remove();
10955                 }
10956 
10957                 this.originalElement.css( "resize", this.originalResizeStyle );
10958                 _destroy( this.originalElement );
10959 
10960                 return this;
10961         },
10962 
10963         _setOption: function( key, value ) {
10964                 this._super( key, value );
10965 
10966                 switch ( key ) {
10967                 case "handles":
10968                         this._removeHandles();
10969                         this._setupHandles();
10970                         break;
10971                 default:
10972                         break;
10973                 }
10974         },
10975 
10976         _setupHandles: function() {
10977                 var o = this.options, handle, i, n, hname, axis, that = this;
10978                 this.handles = o.handles ||
10979                         ( !$( ".ui-resizable-handle", this.element ).length ?
10980                                 "e,s,se" : {
10981                                         n: ".ui-resizable-n",
10982                                         e: ".ui-resizable-e",
10983                                         s: ".ui-resizable-s",
10984                                         w: ".ui-resizable-w",
10985                                         se: ".ui-resizable-se",
10986                                         sw: ".ui-resizable-sw",
10987                                         ne: ".ui-resizable-ne",
10988                                         nw: ".ui-resizable-nw"
10989                                 } );
10990 
10991                 this._handles = $();
10992                 if ( this.handles.constructor === String ) {
10993 
10994                         if ( this.handles === "all" ) {
10995                                 this.handles = "n,e,s,w,se,sw,ne,nw";
10996                         }
10997 
10998                         n = this.handles.split( "," );
10999                         this.handles = {};
11000 
11001                         for ( i = 0; i < n.length; i++ ) {
11002 
11003                                 handle = $.trim( n[ i ] );
11004                                 hname = "ui-resizable-" + handle;
11005                                 axis = $( "<div>" );
11006                                 this._addClass( axis, "ui-resizable-handle " + hname );
11007 
11008                                 axis.css( { zIndex: o.zIndex } );
11009 
11010                                 this.handles[ handle ] = ".ui-resizable-" + handle;
11011                                 this.element.append( axis );
11012                         }
11013 
11014                 }
11015 
11016                 this._renderAxis = function( target ) {
11017 
11018                         var i, axis, padPos, padWrapper;
11019 
11020                         target = target || this.element;
11021 
11022                         for ( i in this.handles ) {
11023 
11024                                 if ( this.handles[ i ].constructor === String ) {
11025                                         this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11026                                 } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11027                                         this.handles[ i ] = $( this.handles[ i ] );
11028                                         this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11029                                 }
11030 
11031                                 if ( this.elementIsWrapper &&
11032                                                 this.originalElement[ 0 ]
11033                                                         .nodeName
11034                                                         .match( /^(textarea|input|select|button)$/i ) ) {
11035                                         axis = $( this.handles[ i ], this.element );
11036 
11037                                         padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11038                                                 axis.outerHeight() :
11039                                                 axis.outerWidth();
11040 
11041                                         padPos = [ "padding",
11042                                                 /ne|nw|n/.test( i ) ? "Top" :
11043                                                 /se|sw|s/.test( i ) ? "Bottom" :
11044                                                 /^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11045 
11046                                         target.css( padPos, padWrapper );
11047 
11048                                         this._proportionallyResize();
11049                                 }
11050 
11051                                 this._handles = this._handles.add( this.handles[ i ] );
11052                         }
11053                 };
11054 
11055                 // TODO: make renderAxis a prototype function
11056                 this._renderAxis( this.element );
11057 
11058                 this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11059                 this._handles.disableSelection();
11060 
11061                 this._handles.on( "mouseover", function() {
11062                         if ( !that.resizing ) {
11063                                 if ( this.className ) {
11064                                         axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11065                                 }
11066                                 that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11067                         }
11068                 } );
11069 
11070                 if ( o.autoHide ) {
11071                         this._handles.hide();
11072                         this._addClass( "ui-resizable-autohide" );
11073                 }
11074         },
11075 
11076         _removeHandles: function() {
11077                 this._handles.remove();
11078         },
11079 
11080         _mouseCapture: function( event ) {
11081                 var i, handle,
11082                         capture = false;
11083 
11084                 for ( i in this.handles ) {
11085                         handle = $( this.handles[ i ] )[ 0 ];
11086                         if ( handle === event.target || $.contains( handle, event.target ) ) {
11087                                 capture = true;
11088                         }
11089                 }
11090 
11091                 return !this.options.disabled && capture;
11092         },
11093 
11094         _mouseStart: function( event ) {
11095 
11096                 var curleft, curtop, cursor,
11097                         o = this.options,
11098                         el = this.element;
11099 
11100                 this.resizing = true;
11101 
11102                 this._renderProxy();
11103 
11104                 curleft = this._num( this.helper.css( "left" ) );
11105                 curtop = this._num( this.helper.css( "top" ) );
11106 
11107                 if ( o.containment ) {
11108                         curleft += $( o.containment ).scrollLeft() || 0;
11109                         curtop += $( o.containment ).scrollTop() || 0;
11110                 }
11111 
11112                 this.offset = this.helper.offset();
11113                 this.position = { left: curleft, top: curtop };
11114 
11115                 this.size = this._helper ? {
11116                                 width: this.helper.width(),
11117                                 height: this.helper.height()
11118                         } : {
11119                                 width: el.width(),
11120                                 height: el.height()
11121                         };
11122 
11123                 this.originalSize = this._helper ? {
11124                                 width: el.outerWidth(),
11125                                 height: el.outerHeight()
11126                         } : {
11127                                 width: el.width(),
11128                                 height: el.height()
11129                         };
11130 
11131                 this.sizeDiff = {
11132                         width: el.outerWidth() - el.width(),
11133                         height: el.outerHeight() - el.height()
11134                 };
11135 
11136                 this.originalPosition = { left: curleft, top: curtop };
11137                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
11138 
11139                 this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11140                         o.aspectRatio :
11141                         ( ( this.originalSize.width / this.originalSize.height ) || 1 );
11142 
11143                 cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11144                 $( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11145 
11146                 this._addClass( "ui-resizable-resizing" );
11147                 this._propagate( "start", event );
11148                 return true;
11149         },
11150 
11151         _mouseDrag: function( event ) {
11152 
11153                 var data, props,
11154                         smp = this.originalMousePosition,
11155                         a = this.axis,
11156                         dx = ( event.pageX - smp.left ) || 0,
11157                         dy = ( event.pageY - smp.top ) || 0,
11158                         trigger = this._change[ a ];
11159 
11160                 this._updatePrevProperties();
11161 
11162                 if ( !trigger ) {
11163                         return false;
11164                 }
11165 
11166                 data = trigger.apply( this, [ event, dx, dy ] );
11167 
11168                 this._updateVirtualBoundaries( event.shiftKey );
11169                 if ( this._aspectRatio || event.shiftKey ) {
11170                         data = this._updateRatio( data, event );
11171                 }
11172 
11173                 data = this._respectSize( data, event );
11174 
11175                 this._updateCache( data );
11176 
11177                 this._propagate( "resize", event );
11178 
11179                 props = this._applyChanges();
11180 
11181                 if ( !this._helper && this._proportionallyResizeElements.length ) {
11182                         this._proportionallyResize();
11183                 }
11184 
11185                 if ( !$.isEmptyObject( props ) ) {
11186                         this._updatePrevProperties();
11187                         this._trigger( "resize", event, this.ui() );
11188                         this._applyChanges();
11189                 }
11190 
11191                 return false;
11192         },
11193 
11194         _mouseStop: function( event ) {
11195 
11196                 this.resizing = false;
11197                 var pr, ista, soffseth, soffsetw, s, left, top,
11198                         o = this.options, that = this;
11199 
11200                 if ( this._helper ) {
11201 
11202                         pr = this._proportionallyResizeElements;
11203                         ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11204                         soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11205                         soffsetw = ista ? 0 : that.sizeDiff.width;
11206 
11207                         s = {
11208                                 width: ( that.helper.width()  - soffsetw ),
11209                                 height: ( that.helper.height() - soffseth )
11210                         };
11211                         left = ( parseFloat( that.element.css( "left" ) ) +
11212                                 ( that.position.left - that.originalPosition.left ) ) || null;
11213                         top = ( parseFloat( that.element.css( "top" ) ) +
11214                                 ( that.position.top - that.originalPosition.top ) ) || null;
11215 
11216                         if ( !o.animate ) {
11217                                 this.element.css( $.extend( s, { top: top, left: left } ) );
11218                         }
11219 
11220                         that.helper.height( that.size.height );
11221                         that.helper.width( that.size.width );
11222 
11223                         if ( this._helper && !o.animate ) {
11224                                 this._proportionallyResize();
11225                         }
11226                 }
11227 
11228                 $( "body" ).css( "cursor", "auto" );
11229 
11230                 this._removeClass( "ui-resizable-resizing" );
11231 
11232                 this._propagate( "stop", event );
11233 
11234                 if ( this._helper ) {
11235                         this.helper.remove();
11236                 }
11237 
11238                 return false;
11239 
11240         },
11241 
11242         _updatePrevProperties: function() {
11243                 this.prevPosition = {
11244                         top: this.position.top,
11245                         left: this.position.left
11246                 };
11247                 this.prevSize = {
11248                         width: this.size.width,
11249                         height: this.size.height
11250                 };
11251         },
11252 
11253         _applyChanges: function() {
11254                 var props = {};
11255 
11256                 if ( this.position.top !== this.prevPosition.top ) {
11257                         props.top = this.position.top + "px";
11258                 }
11259                 if ( this.position.left !== this.prevPosition.left ) {
11260                         props.left = this.position.left + "px";
11261                 }
11262                 if ( this.size.width !== this.prevSize.width ) {
11263                         props.width = this.size.width + "px";
11264                 }
11265                 if ( this.size.height !== this.prevSize.height ) {
11266                         props.height = this.size.height + "px";
11267                 }
11268 
11269                 this.helper.css( props );
11270 
11271                 return props;
11272         },
11273 
11274         _updateVirtualBoundaries: function( forceAspectRatio ) {
11275                 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11276                         o = this.options;
11277 
11278                 b = {
11279                         minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11280                         maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11281                         minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11282                         maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11283                 };
11284 
11285                 if ( this._aspectRatio || forceAspectRatio ) {
11286                         pMinWidth = b.minHeight * this.aspectRatio;
11287                         pMinHeight = b.minWidth / this.aspectRatio;
11288                         pMaxWidth = b.maxHeight * this.aspectRatio;
11289                         pMaxHeight = b.maxWidth / this.aspectRatio;
11290 
11291                         if ( pMinWidth > b.minWidth ) {
11292                                 b.minWidth = pMinWidth;
11293                         }
11294                         if ( pMinHeight > b.minHeight ) {
11295                                 b.minHeight = pMinHeight;
11296                         }
11297                         if ( pMaxWidth < b.maxWidth ) {
11298                                 b.maxWidth = pMaxWidth;
11299                         }
11300                         if ( pMaxHeight < b.maxHeight ) {
11301                                 b.maxHeight = pMaxHeight;
11302                         }
11303                 }
11304                 this._vBoundaries = b;
11305         },
11306 
11307         _updateCache: function( data ) {
11308                 this.offset = this.helper.offset();
11309                 if ( this._isNumber( data.left ) ) {
11310                         this.position.left = data.left;
11311                 }
11312                 if ( this._isNumber( data.top ) ) {
11313                         this.position.top = data.top;
11314                 }
11315                 if ( this._isNumber( data.height ) ) {
11316                         this.size.height = data.height;
11317                 }
11318                 if ( this._isNumber( data.width ) ) {
11319                         this.size.width = data.width;
11320                 }
11321         },
11322 
11323         _updateRatio: function( data ) {
11324 
11325                 var cpos = this.position,
11326                         csize = this.size,
11327                         a = this.axis;
11328 
11329                 if ( this._isNumber( data.height ) ) {
11330                         data.width = ( data.height * this.aspectRatio );
11331                 } else if ( this._isNumber( data.width ) ) {
11332                         data.height = ( data.width / this.aspectRatio );
11333                 }
11334 
11335                 if ( a === "sw" ) {
11336                         data.left = cpos.left + ( csize.width - data.width );
11337                         data.top = null;
11338                 }
11339                 if ( a === "nw" ) {
11340                         data.top = cpos.top + ( csize.height - data.height );
11341                         data.left = cpos.left + ( csize.width - data.width );
11342                 }
11343 
11344                 return data;
11345         },
11346 
11347         _respectSize: function( data ) {
11348 
11349                 var o = this._vBoundaries,
11350                         a = this.axis,
11351                         ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11352                         ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11353                         isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11354                         isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11355                         dw = this.originalPosition.left + this.originalSize.width,
11356                         dh = this.originalPosition.top + this.originalSize.height,
11357                         cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11358                 if ( isminw ) {
11359                         data.width = o.minWidth;
11360                 }
11361                 if ( isminh ) {
11362                         data.height = o.minHeight;
11363                 }
11364                 if ( ismaxw ) {
11365                         data.width = o.maxWidth;
11366                 }
11367                 if ( ismaxh ) {
11368                         data.height = o.maxHeight;
11369                 }
11370 
11371                 if ( isminw && cw ) {
11372                         data.left = dw - o.minWidth;
11373                 }
11374                 if ( ismaxw && cw ) {
11375                         data.left = dw - o.maxWidth;
11376                 }
11377                 if ( isminh && ch ) {
11378                         data.top = dh - o.minHeight;
11379                 }
11380                 if ( ismaxh && ch ) {
11381                         data.top = dh - o.maxHeight;
11382                 }
11383 
11384                 // Fixing jump error on top/left - bug #2330
11385                 if ( !data.width && !data.height && !data.left && data.top ) {
11386                         data.top = null;
11387                 } else if ( !data.width && !data.height && !data.top && data.left ) {
11388                         data.left = null;
11389                 }
11390 
11391                 return data;
11392         },
11393 
11394         _getPaddingPlusBorderDimensions: function( element ) {
11395                 var i = 0,
11396                         widths = [],
11397                         borders = [
11398                                 element.css( "borderTopWidth" ),
11399                                 element.css( "borderRightWidth" ),
11400                                 element.css( "borderBottomWidth" ),
11401                                 element.css( "borderLeftWidth" )
11402                         ],
11403                         paddings = [
11404                                 element.css( "paddingTop" ),
11405                                 element.css( "paddingRight" ),
11406                                 element.css( "paddingBottom" ),
11407                                 element.css( "paddingLeft" )
11408                         ];
11409 
11410                 for ( ; i < 4; i++ ) {
11411                         widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11412                         widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11413                 }
11414 
11415                 return {
11416                         height: widths[ 0 ] + widths[ 2 ],
11417                         width: widths[ 1 ] + widths[ 3 ]
11418                 };
11419         },
11420 
11421         _proportionallyResize: function() {
11422 
11423                 if ( !this._proportionallyResizeElements.length ) {
11424                         return;
11425                 }
11426 
11427                 var prel,
11428                         i = 0,
11429                         element = this.helper || this.element;
11430 
11431                 for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11432 
11433                         prel = this._proportionallyResizeElements[ i ];
11434 
11435                         // TODO: Seems like a bug to cache this.outerDimensions
11436                         // considering that we are in a loop.
11437                         if ( !this.outerDimensions ) {
11438                                 this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11439                         }
11440 
11441                         prel.css( {
11442                                 height: ( element.height() - this.outerDimensions.height ) || 0,
11443                                 width: ( element.width() - this.outerDimensions.width ) || 0
11444                         } );
11445 
11446                 }
11447 
11448         },
11449 
11450         _renderProxy: function() {
11451 
11452                 var el = this.element, o = this.options;
11453                 this.elementOffset = el.offset();
11454 
11455                 if ( this._helper ) {
11456 
11457                         this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11458 
11459                         this._addClass( this.helper, this._helper );
11460                         this.helper.css( {
11461                                 width: this.element.outerWidth(),
11462                                 height: this.element.outerHeight(),
11463                                 position: "absolute",
11464                                 left: this.elementOffset.left + "px",
11465                                 top: this.elementOffset.top + "px",
11466                                 zIndex: ++o.zIndex //TODO: Don't modify option
11467                         } );
11468 
11469                         this.helper
11470                                 .appendTo( "body" )
11471                                 .disableSelection();
11472 
11473                 } else {
11474                         this.helper = this.element;
11475                 }
11476 
11477         },
11478 
11479         _change: {
11480                 e: function( event, dx ) {
11481                         return { width: this.originalSize.width + dx };
11482                 },
11483                 w: function( event, dx ) {
11484                         var cs = this.originalSize, sp = this.originalPosition;
11485                         return { left: sp.left + dx, width: cs.width - dx };
11486                 },
11487                 n: function( event, dx, dy ) {
11488                         var cs = this.originalSize, sp = this.originalPosition;
11489                         return { top: sp.top + dy, height: cs.height - dy };
11490                 },
11491                 s: function( event, dx, dy ) {
11492                         return { height: this.originalSize.height + dy };
11493                 },
11494                 se: function( event, dx, dy ) {
11495                         return $.extend( this._change.s.apply( this, arguments ),
11496                                 this._change.e.apply( this, [ event, dx, dy ] ) );
11497                 },
11498                 sw: function( event, dx, dy ) {
11499                         return $.extend( this._change.s.apply( this, arguments ),
11500                                 this._change.w.apply( this, [ event, dx, dy ] ) );
11501                 },
11502                 ne: function( event, dx, dy ) {
11503                         return $.extend( this._change.n.apply( this, arguments ),
11504                                 this._change.e.apply( this, [ event, dx, dy ] ) );
11505                 },
11506                 nw: function( event, dx, dy ) {
11507                         return $.extend( this._change.n.apply( this, arguments ),
11508                                 this._change.w.apply( this, [ event, dx, dy ] ) );
11509                 }
11510         },
11511 
11512         _propagate: function( n, event ) {
11513                 $.ui.plugin.call( this, n, [ event, this.ui() ] );
11514                 ( n !== "resize" && this._trigger( n, event, this.ui() ) );
11515         },
11516 
11517         plugins: {},
11518 
11519         ui: function() {
11520                 return {
11521                         originalElement: this.originalElement,
11522                         element: this.element,
11523                         helper: this.helper,
11524                         position: this.position,
11525                         size: this.size,
11526                         originalSize: this.originalSize,
11527                         originalPosition: this.originalPosition
11528                 };
11529         }
11530 
11531 } );
11532 
11533 /*
11534  * Resizable Extensions
11535  */
11536 
11537 $.ui.plugin.add( "resizable", "animate", {
11538 
11539         stop: function( event ) {
11540                 var that = $( this ).resizable( "instance" ),
11541                         o = that.options,
11542                         pr = that._proportionallyResizeElements,
11543                         ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11544                         soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11545                         soffsetw = ista ? 0 : that.sizeDiff.width,
11546                         style = {
11547                                 width: ( that.size.width - soffsetw ),
11548                                 height: ( that.size.height - soffseth )
11549                         },
11550                         left = ( parseFloat( that.element.css( "left" ) ) +
11551                                 ( that.position.left - that.originalPosition.left ) ) || null,
11552                         top = ( parseFloat( that.element.css( "top" ) ) +
11553                                 ( that.position.top - that.originalPosition.top ) ) || null;
11554 
11555                 that.element.animate(
11556                         $.extend( style, top && left ? { top: top, left: left } : {} ), {
11557                                 duration: o.animateDuration,
11558                                 easing: o.animateEasing,
11559                                 step: function() {
11560 
11561                                         var data = {
11562                                                 width: parseFloat( that.element.css( "width" ) ),
11563                                                 height: parseFloat( that.element.css( "height" ) ),
11564                                                 top: parseFloat( that.element.css( "top" ) ),
11565                                                 left: parseFloat( that.element.css( "left" ) )
11566                                         };
11567 
11568                                         if ( pr && pr.length ) {
11569                                                 $( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11570                                         }
11571 
11572                                         // Propagating resize, and updating values for each animation step
11573                                         that._updateCache( data );
11574                                         that._propagate( "resize", event );
11575 
11576                                 }
11577                         }
11578                 );
11579         }
11580 
11581 } );
11582 
11583 $.ui.plugin.add( "resizable", "containment", {
11584 
11585         start: function() {
11586                 var element, p, co, ch, cw, width, height,
11587                         that = $( this ).resizable( "instance" ),
11588                         o = that.options,
11589                         el = that.element,
11590                         oc = o.containment,
11591                         ce = ( oc instanceof $ ) ?
11592                                 oc.get( 0 ) :
11593                                 ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11594 
11595                 if ( !ce ) {
11596                         return;
11597                 }
11598 
11599                 that.containerElement = $( ce );
11600 
11601                 if ( /document/.test( oc ) || oc === document ) {
11602                         that.containerOffset = {
11603                                 left: 0,
11604                                 top: 0
11605                         };
11606                         that.containerPosition = {
11607                                 left: 0,
11608                                 top: 0
11609                         };
11610 
11611                         that.parentData = {
11612                                 element: $( document ),
11613                                 left: 0,
11614                                 top: 0,
11615                                 width: $( document ).width(),
11616                                 height: $( document ).height() || document.body.parentNode.scrollHeight
11617                         };
11618                 } else {
11619                         element = $( ce );
11620                         p = [];
11621                         $( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11622                                 p[ i ] = that._num( element.css( "padding" + name ) );
11623                         } );
11624 
11625                         that.containerOffset = element.offset();
11626                         that.containerPosition = element.position();
11627                         that.containerSize = {
11628                                 height: ( element.innerHeight() - p[ 3 ] ),
11629                                 width: ( element.innerWidth() - p[ 1 ] )
11630                         };
11631 
11632                         co = that.containerOffset;
11633                         ch = that.containerSize.height;
11634                         cw = that.containerSize.width;
11635                         width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11636                         height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11637 
11638                         that.parentData = {
11639                                 element: ce,
11640                                 left: co.left,
11641                                 top: co.top,
11642                                 width: width,
11643                                 height: height
11644                         };
11645                 }
11646         },
11647 
11648         resize: function( event ) {
11649                 var woset, hoset, isParent, isOffsetRelative,
11650                         that = $( this ).resizable( "instance" ),
11651                         o = that.options,
11652                         co = that.containerOffset,
11653                         cp = that.position,
11654                         pRatio = that._aspectRatio || event.shiftKey,
11655                         cop = {
11656                                 top: 0,
11657                                 left: 0
11658                         },
11659                         ce = that.containerElement,
11660                         continueResize = true;
11661 
11662                 if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11663                         cop = co;
11664                 }
11665 
11666                 if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11667                         that.size.width = that.size.width +
11668                                 ( that._helper ?
11669                                         ( that.position.left - co.left ) :
11670                                         ( that.position.left - cop.left ) );
11671 
11672                         if ( pRatio ) {
11673                                 that.size.height = that.size.width / that.aspectRatio;
11674                                 continueResize = false;
11675                         }
11676                         that.position.left = o.helper ? co.left : 0;
11677                 }
11678 
11679                 if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11680                         that.size.height = that.size.height +
11681                                 ( that._helper ?
11682                                         ( that.position.top - co.top ) :
11683                                         that.position.top );
11684 
11685                         if ( pRatio ) {
11686                                 that.size.width = that.size.height * that.aspectRatio;
11687                                 continueResize = false;
11688                         }
11689                         that.position.top = that._helper ? co.top : 0;
11690                 }
11691 
11692                 isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11693                 isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11694 
11695                 if ( isParent && isOffsetRelative ) {
11696                         that.offset.left = that.parentData.left + that.position.left;
11697                         that.offset.top = that.parentData.top + that.position.top;
11698                 } else {
11699                         that.offset.left = that.element.offset().left;
11700                         that.offset.top = that.element.offset().top;
11701                 }
11702 
11703                 woset = Math.abs( that.sizeDiff.width +
11704                         ( that._helper ?
11705                                 that.offset.left - cop.left :
11706                                 ( that.offset.left - co.left ) ) );
11707 
11708                 hoset = Math.abs( that.sizeDiff.height +
11709                         ( that._helper ?
11710                                 that.offset.top - cop.top :
11711                                 ( that.offset.top - co.top ) ) );
11712 
11713                 if ( woset + that.size.width >= that.parentData.width ) {
11714                         that.size.width = that.parentData.width - woset;
11715                         if ( pRatio ) {
11716                                 that.size.height = that.size.width / that.aspectRatio;
11717                                 continueResize = false;
11718                         }
11719                 }
11720 
11721                 if ( hoset + that.size.height >= that.parentData.height ) {
11722                         that.size.height = that.parentData.height - hoset;
11723                         if ( pRatio ) {
11724                                 that.size.width = that.size.height * that.aspectRatio;
11725                                 continueResize = false;
11726                         }
11727                 }
11728 
11729                 if ( !continueResize ) {
11730                         that.position.left = that.prevPosition.left;
11731                         that.position.top = that.prevPosition.top;
11732                         that.size.width = that.prevSize.width;
11733                         that.size.height = that.prevSize.height;
11734                 }
11735         },
11736 
11737         stop: function() {
11738                 var that = $( this ).resizable( "instance" ),
11739                         o = that.options,
11740                         co = that.containerOffset,
11741                         cop = that.containerPosition,
11742                         ce = that.containerElement,
11743                         helper = $( that.helper ),
11744                         ho = helper.offset(),
11745                         w = helper.outerWidth() - that.sizeDiff.width,
11746                         h = helper.outerHeight() - that.sizeDiff.height;
11747 
11748                 if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11749                         $( this ).css( {
11750                                 left: ho.left - cop.left - co.left,
11751                                 width: w,
11752                                 height: h
11753                         } );
11754                 }
11755 
11756                 if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11757                         $( this ).css( {
11758                                 left: ho.left - cop.left - co.left,
11759                                 width: w,
11760                                 height: h
11761                         } );
11762                 }
11763         }
11764 } );
11765 
11766 $.ui.plugin.add( "resizable", "alsoResize", {
11767 
11768         start: function() {
11769                 var that = $( this ).resizable( "instance" ),
11770                         o = that.options;
11771 
11772                 $( o.alsoResize ).each( function() {
11773                         var el = $( this );
11774                         el.data( "ui-resizable-alsoresize", {
11775                                 width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11776                                 left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11777                         } );
11778                 } );
11779         },
11780 
11781         resize: function( event, ui ) {
11782                 var that = $( this ).resizable( "instance" ),
11783                         o = that.options,
11784                         os = that.originalSize,
11785                         op = that.originalPosition,
11786                         delta = {
11787                                 height: ( that.size.height - os.height ) || 0,
11788                                 width: ( that.size.width - os.width ) || 0,
11789                                 top: ( that.position.top - op.top ) || 0,
11790                                 left: ( that.position.left - op.left ) || 0
11791                         };
11792 
11793                         $( o.alsoResize ).each( function() {
11794                                 var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11795                                         css = el.parents( ui.originalElement[ 0 ] ).length ?
11796                                                         [ "width", "height" ] :
11797                                                         [ "width", "height", "top", "left" ];
11798 
11799                                 $.each( css, function( i, prop ) {
11800                                         var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11801                                         if ( sum && sum >= 0 ) {
11802                                                 style[ prop ] = sum || null;
11803                                         }
11804                                 } );
11805 
11806                                 el.css( style );
11807                         } );
11808         },
11809 
11810         stop: function() {
11811                 $( this ).removeData( "ui-resizable-alsoresize" );
11812         }
11813 } );
11814 
11815 $.ui.plugin.add( "resizable", "ghost", {
11816 
11817         start: function() {
11818 
11819                 var that = $( this ).resizable( "instance" ), cs = that.size;
11820 
11821                 that.ghost = that.originalElement.clone();
11822                 that.ghost.css( {
11823                         opacity: 0.25,
11824                         display: "block",
11825                         position: "relative",
11826                         height: cs.height,
11827                         width: cs.width,
11828                         margin: 0,
11829                         left: 0,
11830                         top: 0
11831                 } );
11832 
11833                 that._addClass( that.ghost, "ui-resizable-ghost" );
11834 
11835                 // DEPRECATED
11836                 // TODO: remove after 1.12
11837                 if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11838 
11839                         // Ghost option
11840                         that.ghost.addClass( this.options.ghost );
11841                 }
11842 
11843                 that.ghost.appendTo( that.helper );
11844 
11845         },
11846 
11847         resize: function() {
11848                 var that = $( this ).resizable( "instance" );
11849                 if ( that.ghost ) {
11850                         that.ghost.css( {
11851                                 position: "relative",
11852                                 height: that.size.height,
11853                                 width: that.size.width
11854                         } );
11855                 }
11856         },
11857 
11858         stop: function() {
11859                 var that = $( this ).resizable( "instance" );
11860                 if ( that.ghost && that.helper ) {
11861                         that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11862                 }
11863         }
11864 
11865 } );
11866 
11867 $.ui.plugin.add( "resizable", "grid", {
11868 
11869         resize: function() {
11870                 var outerDimensions,
11871                         that = $( this ).resizable( "instance" ),
11872                         o = that.options,
11873                         cs = that.size,
11874                         os = that.originalSize,
11875                         op = that.originalPosition,
11876                         a = that.axis,
11877                         grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11878                         gridX = ( grid[ 0 ] || 1 ),
11879                         gridY = ( grid[ 1 ] || 1 ),
11880                         ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11881                         oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11882                         newWidth = os.width + ox,
11883                         newHeight = os.height + oy,
11884                         isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11885                         isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11886                         isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11887                         isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11888 
11889                 o.grid = grid;
11890 
11891                 if ( isMinWidth ) {
11892                         newWidth += gridX;
11893                 }
11894                 if ( isMinHeight ) {
11895                         newHeight += gridY;
11896                 }
11897                 if ( isMaxWidth ) {
11898                         newWidth -= gridX;
11899                 }
11900                 if ( isMaxHeight ) {
11901                         newHeight -= gridY;
11902                 }
11903 
11904                 if ( /^(se|s|e)$/.test( a ) ) {
11905                         that.size.width = newWidth;
11906                         that.size.height = newHeight;
11907                 } else if ( /^(ne)$/.test( a ) ) {
11908                         that.size.width = newWidth;
11909                         that.size.height = newHeight;
11910                         that.position.top = op.top - oy;
11911                 } else if ( /^(sw)$/.test( a ) ) {
11912                         that.size.width = newWidth;
11913                         that.size.height = newHeight;
11914                         that.position.left = op.left - ox;
11915                 } else {
11916                         if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11917                                 outerDimensions = that._getPaddingPlusBorderDimensions( this );
11918                         }
11919 
11920                         if ( newHeight - gridY > 0 ) {
11921                                 that.size.height = newHeight;
11922                                 that.position.top = op.top - oy;
11923                         } else {
11924                                 newHeight = gridY - outerDimensions.height;
11925                                 that.size.height = newHeight;
11926                                 that.position.top = op.top + os.height - newHeight;
11927                         }
11928                         if ( newWidth - gridX > 0 ) {
11929                                 that.size.width = newWidth;
11930                                 that.position.left = op.left - ox;
11931                         } else {
11932                                 newWidth = gridX - outerDimensions.width;
11933                                 that.size.width = newWidth;
11934                                 that.position.left = op.left + os.width - newWidth;
11935                         }
11936                 }
11937         }
11938 
11939 } );
11940 
11941 var widgetsResizable = $.ui.resizable;
11942 
11943 
11944 /*!
11945  * jQuery UI Dialog 1.12.1
11946  * http://jqueryui.com
11947  *
11948  * Copyright jQuery Foundation and other contributors
11949  * Released under the MIT license.
11950  * http://jquery.org/license
11951  */
11952 
11953 //>>label: Dialog
11954 //>>group: Widgets
11955 //>>description: Displays customizable dialog windows.
11956 //>>docs: http://api.jqueryui.com/dialog/
11957 //>>demos: http://jqueryui.com/dialog/
11958 //>>css.structure: ../../themes/base/core.css
11959 //>>css.structure: ../../themes/base/dialog.css
11960 //>>css.theme: ../../themes/base/theme.css
11961 
11962 
11963 
11964 $.widget( "ui.dialog", {
11965         version: "1.12.1",
11966         options: {
11967                 appendTo: "body",
11968                 autoOpen: true,
11969                 buttons: [],
11970                 classes: {
11971                         "ui-dialog": "ui-corner-all",
11972                         "ui-dialog-titlebar": "ui-corner-all"
11973                 },
11974                 closeOnEscape: true,
11975                 closeText: "Close",
11976                 draggable: true,
11977                 hide: null,
11978                 height: "auto",
11979                 maxHeight: null,
11980                 maxWidth: null,
11981                 minHeight: 150,
11982                 minWidth: 150,
11983                 modal: false,
11984                 position: {
11985                         my: "center",
11986                         at: "center",
11987                         of: window,
11988                         collision: "fit",
11989 
11990                         // Ensure the titlebar is always visible
11991                         using: function( pos ) {
11992                                 var topOffset = $( this ).css( pos ).offset().top;
11993                                 if ( topOffset < 0 ) {
11994                                         $( this ).css( "top", pos.top - topOffset );
11995                                 }
11996                         }
11997                 },
11998                 resizable: true,
11999                 show: null,
12000                 title: null,
12001                 width: 300,
12002 
12003                 // Callbacks
12004                 beforeClose: null,
12005                 close: null,
12006                 drag: null,
12007                 dragStart: null,
12008                 dragStop: null,
12009                 focus: null,
12010                 open: null,
12011                 resize: null,
12012                 resizeStart: null,
12013                 resizeStop: null
12014         },
12015 
12016         sizeRelatedOptions: {
12017                 buttons: true,
12018                 height: true,
12019                 maxHeight: true,
12020                 maxWidth: true,
12021                 minHeight: true,
12022                 minWidth: true,
12023                 width: true
12024         },
12025 
12026         resizableRelatedOptions: {
12027                 maxHeight: true,
12028                 maxWidth: true,
12029                 minHeight: true,
12030                 minWidth: true
12031         },
12032 
12033         _create: function() {
12034                 this.originalCss = {
12035                         display: this.element[ 0 ].style.display,
12036                         width: this.element[ 0 ].style.width,
12037                         minHeight: this.element[ 0 ].style.minHeight,
12038                         maxHeight: this.element[ 0 ].style.maxHeight,
12039                         height: this.element[ 0 ].style.height
12040                 };
12041                 this.originalPosition = {
12042                         parent: this.element.parent(),
12043                         index: this.element.parent().children().index( this.element )
12044                 };
12045                 this.originalTitle = this.element.attr( "title" );
12046                 if ( this.options.title == null && this.originalTitle != null ) {
12047                         this.options.title = this.originalTitle;
12048                 }
12049 
12050                 // Dialogs can't be disabled
12051                 if ( this.options.disabled ) {
12052                         this.options.disabled = false;
12053                 }
12054 
12055                 this._createWrapper();
12056 
12057                 this.element
12058                         .show()
12059                         .removeAttr( "title" )
12060                         .appendTo( this.uiDialog );
12061 
12062                 this._addClass( "ui-dialog-content", "ui-widget-content" );
12063 
12064                 this._createTitlebar();
12065                 this._createButtonPane();
12066 
12067                 if ( this.options.draggable && $.fn.draggable ) {
12068                         this._makeDraggable();
12069                 }
12070                 if ( this.options.resizable && $.fn.resizable ) {
12071                         this._makeResizable();
12072                 }
12073 
12074                 this._isOpen = false;
12075 
12076                 this._trackFocus();
12077         },
12078 
12079         _init: function() {
12080                 if ( this.options.autoOpen ) {
12081                         this.open();
12082                 }
12083         },
12084 
12085         _appendTo: function() {
12086                 var element = this.options.appendTo;
12087                 if ( element && ( element.jquery || element.nodeType ) ) {
12088                         return $( element );
12089                 }
12090                 return this.document.find( element || "body" ).eq( 0 );
12091         },
12092 
12093         _destroy: function() {
12094                 var next,
12095                         originalPosition = this.originalPosition;
12096 
12097                 this._untrackInstance();
12098                 this._destroyOverlay();
12099 
12100                 this.element
12101                         .removeUniqueId()
12102                         .css( this.originalCss )
12103 
12104                         // Without detaching first, the following becomes really slow
12105                         .detach();
12106 
12107                 this.uiDialog.remove();
12108 
12109                 if ( this.originalTitle ) {
12110                         this.element.attr( "title", this.originalTitle );
12111                 }
12112 
12113                 next = originalPosition.parent.children().eq( originalPosition.index );
12114 
12115                 // Don't try to place the dialog next to itself (#8613)
12116                 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12117                         next.before( this.element );
12118                 } else {
12119                         originalPosition.parent.append( this.element );
12120                 }
12121         },
12122 
12123         widget: function() {
12124                 return this.uiDialog;
12125         },
12126 
12127         disable: $.noop,
12128         enable: $.noop,
12129 
12130         close: function( event ) {
12131                 var that = this;
12132 
12133                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12134                         return;
12135                 }
12136 
12137                 this._isOpen = false;
12138                 this._focusedElement = null;
12139                 this._destroyOverlay();
12140                 this._untrackInstance();
12141 
12142                 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12143 
12144                         // Hiding a focused element doesn't trigger blur in WebKit
12145                         // so in case we have nothing to focus on, explicitly blur the active element
12146                         // https://bugs.webkit.org/show_bug.cgi?id=47182
12147                         $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12148                 }
12149 
12150                 this._hide( this.uiDialog, this.options.hide, function() {
12151                         that._trigger( "close", event );
12152                 } );
12153         },
12154 
12155         isOpen: function() {
12156                 return this._isOpen;
12157         },
12158 
12159         moveToTop: function() {
12160                 this._moveToTop();
12161         },
12162 
12163         _moveToTop: function( event, silent ) {
12164                 var moved = false,
12165                         zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12166                                 return +$( this ).css( "z-index" );
12167                         } ).get(),
12168                         zIndexMax = Math.max.apply( null, zIndices );
12169 
12170                 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12171                         this.uiDialog.css( "z-index", zIndexMax + 1 );
12172                         moved = true;
12173                 }
12174 
12175                 if ( moved && !silent ) {
12176                         this._trigger( "focus", event );
12177                 }
12178                 return moved;
12179         },
12180 
12181         open: function() {
12182                 var that = this;
12183                 if ( this._isOpen ) {
12184                         if ( this._moveToTop() ) {
12185                                 this._focusTabbable();
12186                         }
12187                         return;
12188                 }
12189 
12190                 this._isOpen = true;
12191                 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12192 
12193                 this._size();
12194                 this._position();
12195                 this._createOverlay();
12196                 this._moveToTop( null, true );
12197 
12198                 // Ensure the overlay is moved to the top with the dialog, but only when
12199                 // opening. The overlay shouldn't move after the dialog is open so that
12200                 // modeless dialogs opened after the modal dialog stack properly.
12201                 if ( this.overlay ) {
12202                         this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12203                 }
12204 
12205                 this._show( this.uiDialog, this.options.show, function() {
12206                         that._focusTabbable();
12207                         that._trigger( "focus" );
12208                 } );
12209 
12210                 // Track the dialog immediately upon openening in case a focus event
12211                 // somehow occurs outside of the dialog before an element inside the
12212                 // dialog is focused (#10152)
12213                 this._makeFocusTarget();
12214 
12215                 this._trigger( "open" );
12216         },
12217 
12218         _focusTabbable: function() {
12219 
12220                 // Set focus to the first match:
12221                 // 1. An element that was focused previously
12222                 // 2. First element inside the dialog matching [autofocus]
12223                 // 3. Tabbable element inside the content element
12224                 // 4. Tabbable element inside the buttonpane
12225                 // 5. The close button
12226                 // 6. The dialog itself
12227                 var hasFocus = this._focusedElement;
12228                 if ( !hasFocus ) {
12229                         hasFocus = this.element.find( "[autofocus]" );
12230                 }
12231                 if ( !hasFocus.length ) {
12232                         hasFocus = this.element.find( ":tabbable" );
12233                 }
12234                 if ( !hasFocus.length ) {
12235                         hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12236                 }
12237                 if ( !hasFocus.length ) {
12238                         hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12239                 }
12240                 if ( !hasFocus.length ) {
12241                         hasFocus = this.uiDialog;
12242                 }
12243                 hasFocus.eq( 0 ).trigger( "focus" );
12244         },
12245 
12246         _keepFocus: function( event ) {
12247                 function checkFocus() {
12248                         var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12249                                 isActive = this.uiDialog[ 0 ] === activeElement ||
12250                                         $.contains( this.uiDialog[ 0 ], activeElement );
12251                         if ( !isActive ) {
12252                                 this._focusTabbable();
12253                         }
12254                 }
12255                 event.preventDefault();
12256                 checkFocus.call( this );
12257 
12258                 // support: IE
12259                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12260                 // so we check again later
12261                 this._delay( checkFocus );
12262         },
12263 
12264         _createWrapper: function() {
12265                 this.uiDialog = $( "<div>" )
12266                         .hide()
12267                         .attr( {
12268 
12269                                 // Setting tabIndex makes the div focusable
12270                                 tabIndex: -1,
12271                                 role: "dialog"
12272                         } )
12273                         .appendTo( this._appendTo() );
12274 
12275                 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12276                 this._on( this.uiDialog, {
12277                         keydown: function( event ) {
12278                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12279                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
12280                                         event.preventDefault();
12281                                         this.close( event );
12282                                         return;
12283                                 }
12284 
12285                                 // Prevent tabbing out of dialogs
12286                                 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12287                                         return;
12288                                 }
12289                                 var tabbables = this.uiDialog.find( ":tabbable" ),
12290                                         first = tabbables.filter( ":first" ),
12291                                         last = tabbables.filter( ":last" );
12292 
12293                                 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12294                                                 !event.shiftKey ) {
12295                                         this._delay( function() {
12296                                                 first.trigger( "focus" );
12297                                         } );
12298                                         event.preventDefault();
12299                                 } else if ( ( event.target === first[ 0 ] ||
12300                                                 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12301                                         this._delay( function() {
12302                                                 last.trigger( "focus" );
12303                                         } );
12304                                         event.preventDefault();
12305                                 }
12306                         },
12307                         mousedown: function( event ) {
12308                                 if ( this._moveToTop( event ) ) {
12309                                         this._focusTabbable();
12310                                 }
12311                         }
12312                 } );
12313 
12314                 // We assume that any existing aria-describedby attribute means
12315                 // that the dialog content is marked up properly
12316                 // otherwise we brute force the content as the description
12317                 if ( !this.element.find( "[aria-describedby]" ).length ) {
12318                         this.uiDialog.attr( {
12319                                 "aria-describedby": this.element.uniqueId().attr( "id" )
12320                         } );
12321                 }
12322         },
12323 
12324         _createTitlebar: function() {
12325                 var uiDialogTitle;
12326 
12327                 this.uiDialogTitlebar = $( "<div>" );
12328                 this._addClass( this.uiDialogTitlebar,
12329                         "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12330                 this._on( this.uiDialogTitlebar, {
12331                         mousedown: function( event ) {
12332 
12333                                 // Don't prevent click on close button (#8838)
12334                                 // Focusing a dialog that is partially scrolled out of view
12335                                 // causes the browser to scroll it into view, preventing the click event
12336                                 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12337 
12338                                         // Dialog isn't getting focus when dragging (#8063)
12339                                         this.uiDialog.trigger( "focus" );
12340                                 }
12341                         }
12342                 } );
12343 
12344                 // Support: IE
12345                 // Use type="button" to prevent enter keypresses in textboxes from closing the
12346                 // dialog in IE (#9312)
12347                 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12348                         .button( {
12349                                 label: $( "<a>" ).text( this.options.closeText ).html(),
12350                                 icon: "ui-icon-closethick",
12351                                 showLabel: false
12352                         } )
12353                         .appendTo( this.uiDialogTitlebar );
12354 
12355                 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12356                 this._on( this.uiDialogTitlebarClose, {
12357                         click: function( event ) {
12358                                 event.preventDefault();
12359                                 this.close( event );
12360                         }
12361                 } );
12362 
12363                 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12364                 this._addClass( uiDialogTitle, "ui-dialog-title" );
12365                 this._title( uiDialogTitle );
12366 
12367                 this.uiDialogTitlebar.prependTo( this.uiDialog );
12368 
12369                 this.uiDialog.attr( {
12370                         "aria-labelledby": uiDialogTitle.attr( "id" )
12371                 } );
12372         },
12373 
12374         _title: function( title ) {
12375                 if ( this.options.title ) {
12376                         title.text( this.options.title );
12377                 } else {
12378                         title.html( "&#160;" );
12379                 }
12380         },
12381 
12382         _createButtonPane: function() {
12383                 this.uiDialogButtonPane = $( "<div>" );
12384                 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12385                         "ui-widget-content ui-helper-clearfix" );
12386 
12387                 this.uiButtonSet = $( "<div>" )
12388                         .appendTo( this.uiDialogButtonPane );
12389                 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12390 
12391                 this._createButtons();
12392         },
12393 
12394         _createButtons: function() {
12395                 var that = this,
12396                         buttons = this.options.buttons;
12397 
12398                 // If we already have a button pane, remove it
12399                 this.uiDialogButtonPane.remove();
12400                 this.uiButtonSet.empty();
12401 
12402                 if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12403                         this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12404                         return;
12405                 }
12406 
12407                 $.each( buttons, function( name, props ) {
12408                         var click, buttonOptions;
12409                         props = $.isFunction( props ) ?
12410                                 { click: props, text: name } :
12411                                 props;
12412 
12413                         // Default to a non-submitting button
12414                         props = $.extend( { type: "button" }, props );
12415 
12416                         // Change the context for the click callback to be the main element
12417                         click = props.click;
12418                         buttonOptions = {
12419                                 icon: props.icon,
12420                                 iconPosition: props.iconPosition,
12421                                 showLabel: props.showLabel,
12422 
12423                                 // Deprecated options
12424                                 icons: props.icons,
12425                                 text: props.text
12426                         };
12427 
12428                         delete props.click;
12429                         delete props.icon;
12430                         delete props.iconPosition;
12431                         delete props.showLabel;
12432 
12433                         // Deprecated options
12434                         delete props.icons;
12435                         if ( typeof props.text === "boolean" ) {
12436                                 delete props.text;
12437                         }
12438 
12439                         $( "<button></button>", props )
12440                                 .button( buttonOptions )
12441                                 .appendTo( that.uiButtonSet )
12442                                 .on( "click", function() {
12443                                         click.apply( that.element[ 0 ], arguments );
12444                                 } );
12445                 } );
12446                 this._addClass( this.uiDialog, "ui-dialog-buttons" );
12447                 this.uiDialogButtonPane.appendTo( this.uiDialog );
12448         },
12449 
12450         _makeDraggable: function() {
12451                 var that = this,
12452                         options = this.options;
12453 
12454                 function filteredUi( ui ) {
12455                         return {
12456                                 position: ui.position,
12457                                 offset: ui.offset
12458                         };
12459                 }
12460 
12461                 this.uiDialog.draggable( {
12462                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12463                         handle: ".ui-dialog-titlebar",
12464                         containment: "document",
12465                         start: function( event, ui ) {
12466                                 that._addClass( $( this ), "ui-dialog-dragging" );
12467                                 that._blockFrames();
12468                                 that._trigger( "dragStart", event, filteredUi( ui ) );
12469                         },
12470                         drag: function( event, ui ) {
12471                                 that._trigger( "drag", event, filteredUi( ui ) );
12472                         },
12473                         stop: function( event, ui ) {
12474                                 var left = ui.offset.left - that.document.scrollLeft(),
12475                                         top = ui.offset.top - that.document.scrollTop();
12476 
12477                                 options.position = {
12478                                         my: "left top",
12479                                         at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12480                                                 "top" + ( top >= 0 ? "+" : "" ) + top,
12481                                         of: that.window
12482                                 };
12483                                 that._removeClass( $( this ), "ui-dialog-dragging" );
12484                                 that._unblockFrames();
12485                                 that._trigger( "dragStop", event, filteredUi( ui ) );
12486                         }
12487                 } );
12488         },
12489 
12490         _makeResizable: function() {
12491                 var that = this,
12492                         options = this.options,
12493                         handles = options.resizable,
12494 
12495                         // .ui-resizable has position: relative defined in the stylesheet
12496                         // but dialogs have to use absolute or fixed positioning
12497                         position = this.uiDialog.css( "position" ),
12498                         resizeHandles = typeof handles === "string" ?
12499                                 handles :
12500                                 "n,e,s,w,se,sw,ne,nw";
12501 
12502                 function filteredUi( ui ) {
12503                         return {
12504                                 originalPosition: ui.originalPosition,
12505                                 originalSize: ui.originalSize,
12506                                 position: ui.position,
12507                                 size: ui.size
12508                         };
12509                 }
12510 
12511                 this.uiDialog.resizable( {
12512                         cancel: ".ui-dialog-content",
12513                         containment: "document",
12514                         alsoResize: this.element,
12515                         maxWidth: options.maxWidth,
12516                         maxHeight: options.maxHeight,
12517                         minWidth: options.minWidth,
12518                         minHeight: this._minHeight(),
12519                         handles: resizeHandles,
12520                         start: function( event, ui ) {
12521                                 that._addClass( $( this ), "ui-dialog-resizing" );
12522                                 that._blockFrames();
12523                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
12524                         },
12525                         resize: function( event, ui ) {
12526                                 that._trigger( "resize", event, filteredUi( ui ) );
12527                         },
12528                         stop: function( event, ui ) {
12529                                 var offset = that.uiDialog.offset(),
12530                                         left = offset.left - that.document.scrollLeft(),
12531                                         top = offset.top - that.document.scrollTop();
12532 
12533                                 options.height = that.uiDialog.height();
12534                                 options.width = that.uiDialog.width();
12535                                 options.position = {
12536                                         my: "left top",
12537                                         at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12538                                                 "top" + ( top >= 0 ? "+" : "" ) + top,
12539                                         of: that.window
12540                                 };
12541                                 that._removeClass( $( this ), "ui-dialog-resizing" );
12542                                 that._unblockFrames();
12543                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
12544                         }
12545                 } )
12546                         .css( "position", position );
12547         },
12548 
12549         _trackFocus: function() {
12550                 this._on( this.widget(), {
12551                         focusin: function( event ) {
12552                                 this._makeFocusTarget();
12553                                 this._focusedElement = $( event.target );
12554                         }
12555                 } );
12556         },
12557 
12558         _makeFocusTarget: function() {
12559                 this._untrackInstance();
12560                 this._trackingInstances().unshift( this );
12561         },
12562 
12563         _untrackInstance: function() {
12564                 var instances = this._trackingInstances(),
12565                         exists = $.inArray( this, instances );
12566                 if ( exists !== -1 ) {
12567                         instances.splice( exists, 1 );
12568                 }
12569         },
12570 
12571         _trackingInstances: function() {
12572                 var instances = this.document.data( "ui-dialog-instances" );
12573                 if ( !instances ) {
12574                         instances = [];
12575                         this.document.data( "ui-dialog-instances", instances );
12576                 }
12577                 return instances;
12578         },
12579 
12580         _minHeight: function() {
12581                 var options = this.options;
12582 
12583                 return options.height === "auto" ?
12584                         options.minHeight :
12585                         Math.min( options.minHeight, options.height );
12586         },
12587 
12588         _position: function() {
12589 
12590                 // Need to show the dialog to get the actual offset in the position plugin
12591                 var isVisible = this.uiDialog.is( ":visible" );
12592                 if ( !isVisible ) {
12593                         this.uiDialog.show();
12594                 }
12595                 this.uiDialog.position( this.options.position );
12596                 if ( !isVisible ) {
12597                         this.uiDialog.hide();
12598                 }
12599         },
12600 
12601         _setOptions: function( options ) {
12602                 var that = this,
12603                         resize = false,
12604                         resizableOptions = {};
12605 
12606                 $.each( options, function( key, value ) {
12607                         that._setOption( key, value );
12608 
12609                         if ( key in that.sizeRelatedOptions ) {
12610                                 resize = true;
12611                         }
12612                         if ( key in that.resizableRelatedOptions ) {
12613                                 resizableOptions[ key ] = value;
12614                         }
12615                 } );
12616 
12617                 if ( resize ) {
12618                         this._size();
12619                         this._position();
12620                 }
12621                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12622                         this.uiDialog.resizable( "option", resizableOptions );
12623                 }
12624         },
12625 
12626         _setOption: function( key, value ) {
12627                 var isDraggable, isResizable,
12628                         uiDialog = this.uiDialog;
12629 
12630                 if ( key === "disabled" ) {
12631                         return;
12632                 }
12633 
12634                 this._super( key, value );
12635 
12636                 if ( key === "appendTo" ) {
12637                         this.uiDialog.appendTo( this._appendTo() );
12638                 }
12639 
12640                 if ( key === "buttons" ) {
12641                         this._createButtons();
12642                 }
12643 
12644                 if ( key === "closeText" ) {
12645                         this.uiDialogTitlebarClose.button( {
12646 
12647                                 // Ensure that we always pass a string
12648                                 label: $( "<a>" ).text( "" + this.options.closeText ).html()
12649                         } );
12650                 }
12651 
12652                 if ( key === "draggable" ) {
12653                         isDraggable = uiDialog.is( ":data(ui-draggable)" );
12654                         if ( isDraggable && !value ) {
12655                                 uiDialog.draggable( "destroy" );
12656                         }
12657 
12658                         if ( !isDraggable && value ) {
12659                                 this._makeDraggable();
12660                         }
12661                 }
12662 
12663                 if ( key === "position" ) {
12664                         this._position();
12665                 }
12666 
12667                 if ( key === "resizable" ) {
12668 
12669                         // currently resizable, becoming non-resizable
12670                         isResizable = uiDialog.is( ":data(ui-resizable)" );
12671                         if ( isResizable && !value ) {
12672                                 uiDialog.resizable( "destroy" );
12673                         }
12674 
12675                         // Currently resizable, changing handles
12676                         if ( isResizable && typeof value === "string" ) {
12677                                 uiDialog.resizable( "option", "handles", value );
12678                         }
12679 
12680                         // Currently non-resizable, becoming resizable
12681                         if ( !isResizable && value !== false ) {
12682                                 this._makeResizable();
12683                         }
12684                 }
12685 
12686                 if ( key === "title" ) {
12687                         this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12688                 }
12689         },
12690 
12691         _size: function() {
12692 
12693                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12694                 // divs will both have width and height set, so we need to reset them
12695                 var nonContentHeight, minContentHeight, maxContentHeight,
12696                         options = this.options;
12697 
12698                 // Reset content sizing
12699                 this.element.show().css( {
12700                         width: "auto",
12701                         minHeight: 0,
12702                         maxHeight: "none",
12703                         height: 0
12704                 } );
12705 
12706                 if ( options.minWidth > options.width ) {
12707                         options.width = options.minWidth;
12708                 }
12709 
12710                 // Reset wrapper sizing
12711                 // determine the height of all the non-content elements
12712                 nonContentHeight = this.uiDialog.css( {
12713                         height: "auto",
12714                         width: options.width
12715                 } )
12716                         .outerHeight();
12717                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12718                 maxContentHeight = typeof options.maxHeight === "number" ?
12719                         Math.max( 0, options.maxHeight - nonContentHeight ) :
12720                         "none";
12721 
12722                 if ( options.height === "auto" ) {
12723                         this.element.css( {
12724                                 minHeight: minContentHeight,
12725                                 maxHeight: maxContentHeight,
12726                                 height: "auto"
12727                         } );
12728                 } else {
12729                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12730                 }
12731 
12732                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12733                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12734                 }
12735         },
12736 
12737         _blockFrames: function() {
12738                 this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12739                         var iframe = $( this );
12740 
12741                         return $( "<div>" )
12742                                 .css( {
12743                                         position: "absolute",
12744                                         width: iframe.outerWidth(),
12745                                         height: iframe.outerHeight()
12746                                 } )
12747                                 .appendTo( iframe.parent() )
12748                                 .offset( iframe.offset() )[ 0 ];
12749                 } );
12750         },
12751 
12752         _unblockFrames: function() {
12753                 if ( this.iframeBlocks ) {
12754                         this.iframeBlocks.remove();
12755                         delete this.iframeBlocks;
12756                 }
12757         },
12758 
12759         _allowInteraction: function( event ) {
12760                 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12761                         return true;
12762                 }
12763 
12764                 // TODO: Remove hack when datepicker implements
12765                 // the .ui-front logic (#8989)
12766                 return !!$( event.target ).closest( ".ui-datepicker" ).length;
12767         },
12768 
12769         _createOverlay: function() {
12770                 if ( !this.options.modal ) {
12771                         return;
12772                 }
12773 
12774                 // We use a delay in case the overlay is created from an
12775                 // event that we're going to be cancelling (#2804)
12776                 var isOpening = true;
12777                 this._delay( function() {
12778                         isOpening = false;
12779                 } );
12780 
12781                 if ( !this.document.data( "ui-dialog-overlays" ) ) {
12782 
12783                         // Prevent use of anchors and inputs
12784                         // Using _on() for an event handler shared across many instances is
12785                         // safe because the dialogs stack and must be closed in reverse order
12786                         this._on( this.document, {
12787                                 focusin: function( event ) {
12788                                         if ( isOpening ) {
12789                                                 return;
12790                                         }
12791 
12792                                         if ( !this._allowInteraction( event ) ) {
12793                                                 event.preventDefault();
12794                                                 this._trackingInstances()[ 0 ]._focusTabbable();
12795                                         }
12796                                 }
12797                         } );
12798                 }
12799 
12800                 this.overlay = $( "<div>" )
12801                         .appendTo( this._appendTo() );
12802 
12803                 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12804                 this._on( this.overlay, {
12805                         mousedown: "_keepFocus"
12806                 } );
12807                 this.document.data( "ui-dialog-overlays",
12808                         ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12809         },
12810 
12811         _destroyOverlay: function() {
12812                 if ( !this.options.modal ) {
12813                         return;
12814                 }
12815 
12816                 if ( this.overlay ) {
12817                         var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12818 
12819                         if ( !overlays ) {
12820                                 this._off( this.document, "focusin" );
12821                                 this.document.removeData( "ui-dialog-overlays" );
12822                         } else {
12823                                 this.document.data( "ui-dialog-overlays", overlays );
12824                         }
12825 
12826                         this.overlay.remove();
12827                         this.overlay = null;
12828                 }
12829         }
12830 } );
12831 
12832 // DEPRECATED
12833 // TODO: switch return back to widget declaration at top of file when this is removed
12834 if ( $.uiBackCompat !== false ) {
12835 
12836         // Backcompat for dialogClass option
12837         $.widget( "ui.dialog", $.ui.dialog, {
12838                 options: {
12839                         dialogClass: ""
12840                 },
12841                 _createWrapper: function() {
12842                         this._super();
12843                         this.uiDialog.addClass( this.options.dialogClass );
12844                 },
12845                 _setOption: function( key, value ) {
12846                         if ( key === "dialogClass" ) {
12847                                 this.uiDialog
12848                                         .removeClass( this.options.dialogClass )
12849                                         .addClass( value );
12850                         }
12851                         this._superApply( arguments );
12852                 }
12853         } );
12854 }
12855 
12856 var widgetsDialog = $.ui.dialog;
12857 
12858 
12859 /*!
12860  * jQuery UI Droppable 1.12.1
12861  * http://jqueryui.com
12862  *
12863  * Copyright jQuery Foundation and other contributors
12864  * Released under the MIT license.
12865  * http://jquery.org/license
12866  */
12867 
12868 //>>label: Droppable
12869 //>>group: Interactions
12870 //>>description: Enables drop targets for draggable elements.
12871 //>>docs: http://api.jqueryui.com/droppable/
12872 //>>demos: http://jqueryui.com/droppable/
12873 
12874 
12875 
12876 $.widget( "ui.droppable", {
12877         version: "1.12.1",
12878         widgetEventPrefix: "drop",
12879         options: {
12880                 accept: "*",
12881                 addClasses: true,
12882                 greedy: false,
12883                 scope: "default",
12884                 tolerance: "intersect",
12885 
12886                 // Callbacks
12887                 activate: null,
12888                 deactivate: null,
12889                 drop: null,
12890                 out: null,
12891                 over: null
12892         },
12893         _create: function() {
12894 
12895                 var proportions,
12896                         o = this.options,
12897                         accept = o.accept;
12898 
12899                 this.isover = false;
12900                 this.isout = true;
12901 
12902                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
12903                         return d.is( accept );
12904                 };
12905 
12906                 this.proportions = function( /* valueToWrite */ ) {
12907                         if ( arguments.length ) {
12908 
12909                                 // Store the droppable's proportions
12910                                 proportions = arguments[ 0 ];
12911                         } else {
12912 
12913                                 // Retrieve or derive the droppable's proportions
12914                                 return proportions ?
12915                                         proportions :
12916                                         proportions = {
12917                                                 width: this.element[ 0 ].offsetWidth,
12918                                                 height: this.element[ 0 ].offsetHeight
12919                                         };
12920                         }
12921                 };
12922 
12923                 this._addToManager( o.scope );
12924 
12925                 o.addClasses && this._addClass( "ui-droppable" );
12926 
12927         },
12928 
12929         _addToManager: function( scope ) {
12930 
12931                 // Add the reference and positions to the manager
12932                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12933                 $.ui.ddmanager.droppables[ scope ].push( this );
12934         },
12935 
12936         _splice: function( drop ) {
12937                 var i = 0;
12938                 for ( ; i < drop.length; i++ ) {
12939                         if ( drop[ i ] === this ) {
12940                                 drop.splice( i, 1 );
12941                         }
12942                 }
12943         },
12944 
12945         _destroy: function() {
12946                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12947 
12948                 this._splice( drop );
12949         },
12950 
12951         _setOption: function( key, value ) {
12952 
12953                 if ( key === "accept" ) {
12954                         this.accept = $.isFunction( value ) ? value : function( d ) {
12955                                 return d.is( value );
12956                         };
12957                 } else if ( key === "scope" ) {
12958                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12959 
12960                         this._splice( drop );
12961                         this._addToManager( value );
12962                 }
12963 
12964                 this._super( key, value );
12965         },
12966 
12967         _activate: function( event ) {
12968                 var draggable = $.ui.ddmanager.current;
12969 
12970                 this._addActiveClass();
12971                 if ( draggable ) {
12972                         this._trigger( "activate", event, this.ui( draggable ) );
12973                 }
12974         },
12975 
12976         _deactivate: function( event ) {
12977                 var draggable = $.ui.ddmanager.current;
12978 
12979                 this._removeActiveClass();
12980                 if ( draggable ) {
12981                         this._trigger( "deactivate", event, this.ui( draggable ) );
12982                 }
12983         },
12984 
12985         _over: function( event ) {
12986 
12987                 var draggable = $.ui.ddmanager.current;
12988 
12989                 // Bail if draggable and droppable are same element
12990                 if ( !draggable || ( draggable.currentItem ||
12991                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
12992                         return;
12993                 }
12994 
12995                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12996                                 draggable.element ) ) ) {
12997                         this._addHoverClass();
12998                         this._trigger( "over", event, this.ui( draggable ) );
12999                 }
13000 
13001         },
13002 
13003         _out: function( event ) {
13004 
13005                 var draggable = $.ui.ddmanager.current;
13006 
13007                 // Bail if draggable and droppable are same element
13008                 if ( !draggable || ( draggable.currentItem ||
13009                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
13010                         return;
13011                 }
13012 
13013                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13014                                 draggable.element ) ) ) {
13015                         this._removeHoverClass();
13016                         this._trigger( "out", event, this.ui( draggable ) );
13017                 }
13018 
13019         },
13020 
13021         _drop: function( event, custom ) {
13022 
13023                 var draggable = custom || $.ui.ddmanager.current,
13024                         childrenIntersection = false;
13025 
13026                 // Bail if draggable and droppable are same element
13027                 if ( !draggable || ( draggable.currentItem ||
13028                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
13029                         return false;
13030                 }
13031 
13032                 this.element
13033                         .find( ":data(ui-droppable)" )
13034                         .not( ".ui-draggable-dragging" )
13035                         .each( function() {
13036                                 var inst = $( this ).droppable( "instance" );
13037                                 if (
13038                                         inst.options.greedy &&
13039                                         !inst.options.disabled &&
13040                                         inst.options.scope === draggable.options.scope &&
13041                                         inst.accept.call(
13042                                                 inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13043                                         ) &&
13044                                         intersect(
13045                                                 draggable,
13046                                                 $.extend( inst, { offset: inst.element.offset() } ),
13047                                                 inst.options.tolerance, event
13048                                         )
13049                                 ) {
13050                                         childrenIntersection = true;
13051                                         return false; }
13052                         } );
13053                 if ( childrenIntersection ) {
13054                         return false;
13055                 }
13056 
13057                 if ( this.accept.call( this.element[ 0 ],
13058                                 ( draggable.currentItem || draggable.element ) ) ) {
13059                         this._removeActiveClass();
13060                         this._removeHoverClass();
13061 
13062                         this._trigger( "drop", event, this.ui( draggable ) );
13063                         return this.element;
13064                 }
13065 
13066                 return false;
13067 
13068         },
13069 
13070         ui: function( c ) {
13071                 return {
13072                         draggable: ( c.currentItem || c.element ),
13073                         helper: c.helper,
13074                         position: c.position,
13075                         offset: c.positionAbs
13076                 };
13077         },
13078 
13079         // Extension points just to make backcompat sane and avoid duplicating logic
13080         // TODO: Remove in 1.13 along with call to it below
13081         _addHoverClass: function() {
13082                 this._addClass( "ui-droppable-hover" );
13083         },
13084 
13085         _removeHoverClass: function() {
13086                 this._removeClass( "ui-droppable-hover" );
13087         },
13088 
13089         _addActiveClass: function() {
13090                 this._addClass( "ui-droppable-active" );
13091         },
13092 
13093         _removeActiveClass: function() {
13094                 this._removeClass( "ui-droppable-active" );
13095         }
13096 } );
13097 
13098 var intersect = $.ui.intersect = ( function() {
13099         function isOverAxis( x, reference, size ) {
13100                 return ( x >= reference ) && ( x < ( reference + size ) );
13101         }
13102 
13103         return function( draggable, droppable, toleranceMode, event ) {
13104 
13105                 if ( !droppable.offset ) {
13106                         return false;
13107                 }
13108 
13109                 var x1 = ( draggable.positionAbs ||
13110                                 draggable.position.absolute ).left + draggable.margins.left,
13111                         y1 = ( draggable.positionAbs ||
13112                                 draggable.position.absolute ).top + draggable.margins.top,
13113                         x2 = x1 + draggable.helperProportions.width,
13114                         y2 = y1 + draggable.helperProportions.height,
13115                         l = droppable.offset.left,
13116                         t = droppable.offset.top,
13117                         r = l + droppable.proportions().width,
13118                         b = t + droppable.proportions().height;
13119 
13120                 switch ( toleranceMode ) {
13121                 case "fit":
13122                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13123                 case "intersect":
13124                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13125                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13126                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13127                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13128                 case "pointer":
13129                         return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13130                                 isOverAxis( event.pageX, l, droppable.proportions().width );
13131                 case "touch":
13132                         return (
13133                                 ( y1 >= t && y1 <= b ) || // Top edge touching
13134                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
13135                                 ( y1 < t && y2 > b ) // Surrounded vertically
13136                         ) && (
13137                                 ( x1 >= l && x1 <= r ) || // Left edge touching
13138                                 ( x2 >= l && x2 <= r ) || // Right edge touching
13139                                 ( x1 < l && x2 > r ) // Surrounded horizontally
13140                         );
13141                 default:
13142                         return false;
13143                 }
13144         };
13145 } )();
13146 
13147 /*
13148         This manager tracks offsets of draggables and droppables
13149 */
13150 $.ui.ddmanager = {
13151         current: null,
13152         droppables: { "default": [] },
13153         prepareOffsets: function( t, event ) {
13154 
13155                 var i, j,
13156                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13157                         type = event ? event.type : null, // workaround for #2317
13158                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13159 
13160                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13161 
13162                         // No disabled and non-accepted
13163                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13164                                         ( t.currentItem || t.element ) ) ) ) {
13165                                 continue;
13166                         }
13167 
13168                         // Filter out elements in the current dragged item
13169                         for ( j = 0; j < list.length; j++ ) {
13170                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
13171                                         m[ i ].proportions().height = 0;
13172                                         continue droppablesLoop;
13173                                 }
13174                         }
13175 
13176                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13177                         if ( !m[ i ].visible ) {
13178                                 continue;
13179                         }
13180 
13181                         // Activate the droppable if used directly from draggables
13182                         if ( type === "mousedown" ) {
13183                                 m[ i ]._activate.call( m[ i ], event );
13184                         }
13185 
13186                         m[ i ].offset = m[ i ].element.offset();
13187                         m[ i ].proportions( {
13188                                 width: m[ i ].element[ 0 ].offsetWidth,
13189                                 height: m[ i ].element[ 0 ].offsetHeight
13190                         } );
13191 
13192                 }
13193 
13194         },
13195         drop: function( draggable, event ) {
13196 
13197                 var dropped = false;
13198 
13199                 // Create a copy of the droppables in case the list changes during the drop (#9116)
13200                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13201 
13202                         if ( !this.options ) {
13203                                 return;
13204                         }
13205                         if ( !this.options.disabled && this.visible &&
13206                                         intersect( draggable, this, this.options.tolerance, event ) ) {
13207                                 dropped = this._drop.call( this, event ) || dropped;
13208                         }
13209 
13210                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13211                                         ( draggable.currentItem || draggable.element ) ) ) {
13212                                 this.isout = true;
13213                                 this.isover = false;
13214                                 this._deactivate.call( this, event );
13215                         }
13216 
13217                 } );
13218                 return dropped;
13219 
13220         },
13221         dragStart: function( draggable, event ) {
13222 
13223                 // Listen for scrolling so that if the dragging causes scrolling the position of the
13224                 // droppables can be recalculated (see #5003)
13225                 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13226                         if ( !draggable.options.refreshPositions ) {
13227                                 $.ui.ddmanager.prepareOffsets( draggable, event );
13228                         }
13229                 } );
13230         },
13231         drag: function( draggable, event ) {
13232 
13233                 // If you have a highly dynamic page, you might try this option. It renders positions
13234                 // every time you move the mouse.
13235                 if ( draggable.options.refreshPositions ) {
13236                         $.ui.ddmanager.prepareOffsets( draggable, event );
13237                 }
13238 
13239                 // Run through all droppables and check their positions based on specific tolerance options
13240                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13241 
13242                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
13243                                 return;
13244                         }
13245 
13246                         var parentInstance, scope, parent,
13247                                 intersects = intersect( draggable, this, this.options.tolerance, event ),
13248                                 c = !intersects && this.isover ?
13249                                         "isout" :
13250                                         ( intersects && !this.isover ? "isover" : null );
13251                         if ( !c ) {
13252                                 return;
13253                         }
13254 
13255                         if ( this.options.greedy ) {
13256 
13257                                 // find droppable parents with same scope
13258                                 scope = this.options.scope;
13259                                 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13260                                         return $( this ).droppable( "instance" ).options.scope === scope;
13261                                 } );
13262 
13263                                 if ( parent.length ) {
13264                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13265                                         parentInstance.greedyChild = ( c === "isover" );
13266                                 }
13267                         }
13268 
13269                         // We just moved into a greedy child
13270                         if ( parentInstance && c === "isover" ) {
13271                                 parentInstance.isover = false;
13272                                 parentInstance.isout = true;
13273                                 parentInstance._out.call( parentInstance, event );
13274                         }
13275 
13276                         this[ c ] = true;
13277                         this[ c === "isout" ? "isover" : "isout" ] = false;
13278                         this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13279 
13280                         // We just moved out of a greedy child
13281                         if ( parentInstance && c === "isout" ) {
13282                                 parentInstance.isout = false;
13283                                 parentInstance.isover = true;
13284                                 parentInstance._over.call( parentInstance, event );
13285                         }
13286                 } );
13287 
13288         },
13289         dragStop: function( draggable, event ) {
13290                 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13291 
13292                 // Call prepareOffsets one final time since IE does not fire return scroll events when
13293                 // overflow was caused by drag (see #5003)
13294                 if ( !draggable.options.refreshPositions ) {
13295                         $.ui.ddmanager.prepareOffsets( draggable, event );
13296                 }
13297         }
13298 };
13299 
13300 // DEPRECATED
13301 // TODO: switch return back to widget declaration at top of file when this is removed
13302 if ( $.uiBackCompat !== false ) {
13303 
13304         // Backcompat for activeClass and hoverClass options
13305         $.widget( "ui.droppable", $.ui.droppable, {
13306                 options: {
13307                         hoverClass: false,
13308                         activeClass: false
13309                 },
13310                 _addActiveClass: function() {
13311                         this._super();
13312                         if ( this.options.activeClass ) {
13313                                 this.element.addClass( this.options.activeClass );
13314                         }
13315                 },
13316                 _removeActiveClass: function() {
13317                         this._super();
13318                         if ( this.options.activeClass ) {
13319                                 this.element.removeClass( this.options.activeClass );
13320                         }
13321                 },
13322                 _addHoverClass: function() {
13323                         this._super();
13324                         if ( this.options.hoverClass ) {
13325                                 this.element.addClass( this.options.hoverClass );
13326                         }
13327                 },
13328                 _removeHoverClass: function() {
13329                         this._super();
13330                         if ( this.options.hoverClass ) {
13331                                 this.element.removeClass( this.options.hoverClass );
13332                         }
13333                 }
13334         } );
13335 }
13336 
13337 var widgetsDroppable = $.ui.droppable;
13338 
13339 
13340 /*!
13341  * jQuery UI Progressbar 1.12.1
13342  * http://jqueryui.com
13343  *
13344  * Copyright jQuery Foundation and other contributors
13345  * Released under the MIT license.
13346  * http://jquery.org/license
13347  */
13348 
13349 //>>label: Progressbar
13350 //>>group: Widgets
13351 // jscs:disable maximumLineLength
13352 //>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13353 // jscs:enable maximumLineLength
13354 //>>docs: http://api.jqueryui.com/progressbar/
13355 //>>demos: http://jqueryui.com/progressbar/
13356 //>>css.structure: ../../themes/base/core.css
13357 //>>css.structure: ../../themes/base/progressbar.css
13358 //>>css.theme: ../../themes/base/theme.css
13359 
13360 
13361 
13362 var widgetsProgressbar = $.widget( "ui.progressbar", {
13363         version: "1.12.1",
13364         options: {
13365                 classes: {
13366                         "ui-progressbar": "ui-corner-all",
13367                         "ui-progressbar-value": "ui-corner-left",
13368                         "ui-progressbar-complete": "ui-corner-right"
13369                 },
13370                 max: 100,
13371                 value: 0,
13372 
13373                 change: null,
13374                 complete: null
13375         },
13376 
13377         min: 0,
13378 
13379         _create: function() {
13380 
13381                 // Constrain initial value
13382                 this.oldValue = this.options.value = this._constrainedValue();
13383 
13384                 this.element.attr( {
13385 
13386                         // Only set static values; aria-valuenow and aria-valuemax are
13387                         // set inside _refreshValue()
13388                         role: "progressbar",
13389                         "aria-valuemin": this.min
13390                 } );
13391                 this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13392 
13393                 this.valueDiv = $( "<div>" ).appendTo( this.element );
13394                 this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13395                 this._refreshValue();
13396         },
13397 
13398         _destroy: function() {
13399                 this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13400 
13401                 this.valueDiv.remove();
13402         },
13403 
13404         value: function( newValue ) {
13405                 if ( newValue === undefined ) {
13406                         return this.options.value;
13407                 }
13408 
13409                 this.options.value = this._constrainedValue( newValue );
13410                 this._refreshValue();
13411         },
13412 
13413         _constrainedValue: function( newValue ) {
13414                 if ( newValue === undefined ) {
13415                         newValue = this.options.value;
13416                 }
13417 
13418                 this.indeterminate = newValue === false;
13419 
13420                 // Sanitize value
13421                 if ( typeof newValue !== "number" ) {
13422                         newValue = 0;
13423                 }
13424 
13425                 return this.indeterminate ? false :
13426                         Math.min( this.options.max, Math.max( this.min, newValue ) );
13427         },
13428 
13429         _setOptions: function( options ) {
13430 
13431                 // Ensure "value" option is set after other values (like max)
13432                 var value = options.value;
13433                 delete options.value;
13434 
13435                 this._super( options );
13436 
13437                 this.options.value = this._constrainedValue( value );
13438                 this._refreshValue();
13439         },
13440 
13441         _setOption: function( key, value ) {
13442                 if ( key === "max" ) {
13443 
13444                         // Don't allow a max less than min
13445                         value = Math.max( this.min, value );
13446                 }
13447                 this._super( key, value );
13448         },
13449 
13450         _setOptionDisabled: function( value ) {
13451                 this._super( value );
13452 
13453                 this.element.attr( "aria-disabled", value );
13454                 this._toggleClass( null, "ui-state-disabled", !!value );
13455         },
13456 
13457         _percentage: function() {
13458                 return this.indeterminate ?
13459                         100 :
13460                         100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13461         },
13462 
13463         _refreshValue: function() {
13464                 var value = this.options.value,
13465                         percentage = this._percentage();
13466 
13467                 this.valueDiv
13468                         .toggle( this.indeterminate || value > this.min )
13469                         .width( percentage.toFixed( 0 ) + "%" );
13470 
13471                 this
13472                         ._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13473                                 value === this.options.max )
13474                         ._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13475 
13476                 if ( this.indeterminate ) {
13477                         this.element.removeAttr( "aria-valuenow" );
13478                         if ( !this.overlayDiv ) {
13479                                 this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13480                                 this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13481                         }
13482                 } else {
13483                         this.element.attr( {
13484                                 "aria-valuemax": this.options.max,
13485                                 "aria-valuenow": value
13486                         } );
13487                         if ( this.overlayDiv ) {
13488                                 this.overlayDiv.remove();
13489                                 this.overlayDiv = null;
13490                         }
13491                 }
13492 
13493                 if ( this.oldValue !== value ) {
13494                         this.oldValue = value;
13495                         this._trigger( "change" );
13496                 }
13497                 if ( value === this.options.max ) {
13498                         this._trigger( "complete" );
13499                 }
13500         }
13501 } );
13502 
13503 
13504 /*!
13505  * jQuery UI Selectable 1.12.1
13506  * http://jqueryui.com
13507  *
13508  * Copyright jQuery Foundation and other contributors
13509  * Released under the MIT license.
13510  * http://jquery.org/license
13511  */
13512 
13513 //>>label: Selectable
13514 //>>group: Interactions
13515 //>>description: Allows groups of elements to be selected with the mouse.
13516 //>>docs: http://api.jqueryui.com/selectable/
13517 //>>demos: http://jqueryui.com/selectable/
13518 //>>css.structure: ../../themes/base/selectable.css
13519 
13520 
13521 
13522 var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13523         version: "1.12.1",
13524         options: {
13525                 appendTo: "body",
13526                 autoRefresh: true,
13527                 distance: 0,
13528                 filter: "*",
13529                 tolerance: "touch",
13530 
13531                 // Callbacks
13532                 selected: null,
13533                 selecting: null,
13534                 start: null,
13535                 stop: null,
13536                 unselected: null,
13537                 unselecting: null
13538         },
13539         _create: function() {
13540                 var that = this;
13541 
13542                 this._addClass( "ui-selectable" );
13543 
13544                 this.dragged = false;
13545 
13546                 // Cache selectee children based on filter
13547                 this.refresh = function() {
13548                         that.elementPos = $( that.element[ 0 ] ).offset();
13549                         that.selectees = $( that.options.filter, that.element[ 0 ] );
13550                         that._addClass( that.selectees, "ui-selectee" );
13551                         that.selectees.each( function() {
13552                                 var $this = $( this ),
13553                                         selecteeOffset = $this.offset(),
13554                                         pos = {
13555                                                 left: selecteeOffset.left - that.elementPos.left,
13556                                                 top: selecteeOffset.top - that.elementPos.top
13557                                         };
13558                                 $.data( this, "selectable-item", {
13559                                         element: this,
13560                                         $element: $this,
13561                                         left: pos.left,
13562                                         top: pos.top,
13563                                         right: pos.left + $this.outerWidth(),
13564                                         bottom: pos.top + $this.outerHeight(),
13565                                         startselected: false,
13566                                         selected: $this.hasClass( "ui-selected" ),
13567                                         selecting: $this.hasClass( "ui-selecting" ),
13568                                         unselecting: $this.hasClass( "ui-unselecting" )
13569                                 } );
13570                         } );
13571                 };
13572                 this.refresh();
13573 
13574                 this._mouseInit();
13575 
13576                 this.helper = $( "<div>" );
13577                 this._addClass( this.helper, "ui-selectable-helper" );
13578         },
13579 
13580         _destroy: function() {
13581                 this.selectees.removeData( "selectable-item" );
13582                 this._mouseDestroy();
13583         },
13584 
13585         _mouseStart: function( event ) {
13586                 var that = this,
13587                         options = this.options;
13588 
13589                 this.opos = [ event.pageX, event.pageY ];
13590                 this.elementPos = $( this.element[ 0 ] ).offset();
13591 
13592                 if ( this.options.disabled ) {
13593                         return;
13594                 }
13595 
13596                 this.selectees = $( options.filter, this.element[ 0 ] );
13597 
13598                 this._trigger( "start", event );
13599 
13600                 $( options.appendTo ).append( this.helper );
13601 
13602                 // position helper (lasso)
13603                 this.helper.css( {
13604                         "left": event.pageX,
13605                         "top": event.pageY,
13606                         "width": 0,
13607                         "height": 0
13608                 } );
13609 
13610                 if ( options.autoRefresh ) {
13611                         this.refresh();
13612                 }
13613 
13614                 this.selectees.filter( ".ui-selected" ).each( function() {
13615                         var selectee = $.data( this, "selectable-item" );
13616                         selectee.startselected = true;
13617                         if ( !event.metaKey && !event.ctrlKey ) {
13618                                 that._removeClass( selectee.$element, "ui-selected" );
13619                                 selectee.selected = false;
13620                                 that._addClass( selectee.$element, "ui-unselecting" );
13621                                 selectee.unselecting = true;
13622 
13623                                 // selectable UNSELECTING callback
13624                                 that._trigger( "unselecting", event, {
13625                                         unselecting: selectee.element
13626                                 } );
13627                         }
13628                 } );
13629 
13630                 $( event.target ).parents().addBack().each( function() {
13631                         var doSelect,
13632                                 selectee = $.data( this, "selectable-item" );
13633                         if ( selectee ) {
13634                                 doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13635                                         !selectee.$element.hasClass( "ui-selected" );
13636                                 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13637                                         ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13638                                 selectee.unselecting = !doSelect;
13639                                 selectee.selecting = doSelect;
13640                                 selectee.selected = doSelect;
13641 
13642                                 // selectable (UN)SELECTING callback
13643                                 if ( doSelect ) {
13644                                         that._trigger( "selecting", event, {
13645                                                 selecting: selectee.element
13646                                         } );
13647                                 } else {
13648                                         that._trigger( "unselecting", event, {
13649                                                 unselecting: selectee.element
13650                                         } );
13651                                 }
13652                                 return false;
13653                         }
13654                 } );
13655 
13656         },
13657 
13658         _mouseDrag: function( event ) {
13659 
13660                 this.dragged = true;
13661 
13662                 if ( this.options.disabled ) {
13663                         return;
13664                 }
13665 
13666                 var tmp,
13667                         that = this,
13668                         options = this.options,
13669                         x1 = this.opos[ 0 ],
13670                         y1 = this.opos[ 1 ],
13671                         x2 = event.pageX,
13672                         y2 = event.pageY;
13673 
13674                 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13675                 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13676                 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13677 
13678                 this.selectees.each( function() {
13679                         var selectee = $.data( this, "selectable-item" ),
13680                                 hit = false,
13681                                 offset = {};
13682 
13683                         //prevent helper from being selected if appendTo: selectable
13684                         if ( !selectee || selectee.element === that.element[ 0 ] ) {
13685                                 return;
13686                         }
13687 
13688                         offset.left   = selectee.left   + that.elementPos.left;
13689                         offset.right  = selectee.right  + that.elementPos.left;
13690                         offset.top    = selectee.top    + that.elementPos.top;
13691                         offset.bottom = selectee.bottom + that.elementPos.top;
13692 
13693                         if ( options.tolerance === "touch" ) {
13694                                 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13695                     offset.bottom < y1 ) );
13696                         } else if ( options.tolerance === "fit" ) {
13697                                 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13698                     offset.bottom < y2 );
13699                         }
13700 
13701                         if ( hit ) {
13702 
13703                                 // SELECT
13704                                 if ( selectee.selected ) {
13705                                         that._removeClass( selectee.$element, "ui-selected" );
13706                                         selectee.selected = false;
13707                                 }
13708                                 if ( selectee.unselecting ) {
13709                                         that._removeClass( selectee.$element, "ui-unselecting" );
13710                                         selectee.unselecting = false;
13711                                 }
13712                                 if ( !selectee.selecting ) {
13713                                         that._addClass( selectee.$element, "ui-selecting" );
13714                                         selectee.selecting = true;
13715 
13716                                         // selectable SELECTING callback
13717                                         that._trigger( "selecting", event, {
13718                                                 selecting: selectee.element
13719                                         } );
13720                                 }
13721                         } else {
13722 
13723                                 // UNSELECT
13724                                 if ( selectee.selecting ) {
13725                                         if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13726                                                 that._removeClass( selectee.$element, "ui-selecting" );
13727                                                 selectee.selecting = false;
13728                                                 that._addClass( selectee.$element, "ui-selected" );
13729                                                 selectee.selected = true;
13730                                         } else {
13731                                                 that._removeClass( selectee.$element, "ui-selecting" );
13732                                                 selectee.selecting = false;
13733                                                 if ( selectee.startselected ) {
13734                                                         that._addClass( selectee.$element, "ui-unselecting" );
13735                                                         selectee.unselecting = true;
13736                                                 }
13737 
13738                                                 // selectable UNSELECTING callback
13739                                                 that._trigger( "unselecting", event, {
13740                                                         unselecting: selectee.element
13741                                                 } );
13742                                         }
13743                                 }
13744                                 if ( selectee.selected ) {
13745                                         if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13746                                                 that._removeClass( selectee.$element, "ui-selected" );
13747                                                 selectee.selected = false;
13748 
13749                                                 that._addClass( selectee.$element, "ui-unselecting" );
13750                                                 selectee.unselecting = true;
13751 
13752                                                 // selectable UNSELECTING callback
13753                                                 that._trigger( "unselecting", event, {
13754                                                         unselecting: selectee.element
13755                                                 } );
13756                                         }
13757                                 }
13758                         }
13759                 } );
13760 
13761                 return false;
13762         },
13763 
13764         _mouseStop: function( event ) {
13765                 var that = this;
13766 
13767                 this.dragged = false;
13768 
13769                 $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13770                         var selectee = $.data( this, "selectable-item" );
13771                         that._removeClass( selectee.$element, "ui-unselecting" );
13772                         selectee.unselecting = false;
13773                         selectee.startselected = false;
13774                         that._trigger( "unselected", event, {
13775                                 unselected: selectee.element
13776                         } );
13777                 } );
13778                 $( ".ui-selecting", this.element[ 0 ] ).each( function() {
13779                         var selectee = $.data( this, "selectable-item" );
13780                         that._removeClass( selectee.$element, "ui-selecting" )
13781                                 ._addClass( selectee.$element, "ui-selected" );
13782                         selectee.selecting = false;
13783                         selectee.selected = true;
13784                         selectee.startselected = true;
13785                         that._trigger( "selected", event, {
13786                                 selected: selectee.element
13787                         } );
13788                 } );
13789                 this._trigger( "stop", event );
13790 
13791                 this.helper.remove();
13792 
13793                 return false;
13794         }
13795 
13796 } );
13797 
13798 
13799 /*!
13800  * jQuery UI Selectmenu 1.12.1
13801  * http://jqueryui.com
13802  *
13803  * Copyright jQuery Foundation and other contributors
13804  * Released under the MIT license.
13805  * http://jquery.org/license
13806  */
13807 
13808 //>>label: Selectmenu
13809 //>>group: Widgets
13810 // jscs:disable maximumLineLength
13811 //>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
13812 // jscs:enable maximumLineLength
13813 //>>docs: http://api.jqueryui.com/selectmenu/
13814 //>>demos: http://jqueryui.com/selectmenu/
13815 //>>css.structure: ../../themes/base/core.css
13816 //>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13817 //>>css.theme: ../../themes/base/theme.css
13818 
13819 
13820 
13821 var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13822         version: "1.12.1",
13823         defaultElement: "<select>",
13824         options: {
13825                 appendTo: null,
13826                 classes: {
13827                         "ui-selectmenu-button-open": "ui-corner-top",
13828                         "ui-selectmenu-button-closed": "ui-corner-all"
13829                 },
13830                 disabled: null,
13831                 icons: {
13832                         button: "ui-icon-triangle-1-s"
13833                 },
13834                 position: {
13835                         my: "left top",
13836                         at: "left bottom",
13837                         collision: "none"
13838                 },
13839                 width: false,
13840 
13841                 // Callbacks
13842                 change: null,
13843                 close: null,
13844                 focus: null,
13845                 open: null,
13846                 select: null
13847         },
13848 
13849         _create: function() {
13850                 var selectmenuId = this.element.uniqueId().attr( "id" );
13851                 this.ids = {
13852                         element: selectmenuId,
13853                         button: selectmenuId + "-button",
13854                         menu: selectmenuId + "-menu"
13855                 };
13856 
13857                 this._drawButton();
13858                 this._drawMenu();
13859                 this._bindFormResetHandler();
13860 
13861                 this._rendered = false;
13862                 this.menuItems = $();
13863         },
13864 
13865         _drawButton: function() {
13866                 var icon,
13867                         that = this,
13868                         item = this._parseOption(
13869                                 this.element.find( "option:selected" ),
13870                                 this.element[ 0 ].selectedIndex
13871                         );
13872 
13873                 // Associate existing label with the new button
13874                 this.labels = this.element.labels().attr( "for", this.ids.button );
13875                 this._on( this.labels, {
13876                         click: function( event ) {
13877                                 this.button.focus();
13878                                 event.preventDefault();
13879                         }
13880                 } );
13881 
13882                 // Hide original select element
13883                 this.element.hide();
13884 
13885                 // Create button
13886                 this.button = $( "<span>", {
13887                         tabindex: this.options.disabled ? -1 : 0,
13888                         id: this.ids.button,
13889                         role: "combobox",
13890                         "aria-expanded": "false",
13891                         "aria-autocomplete": "list",
13892                         "aria-owns": this.ids.menu,
13893                         "aria-haspopup": "true",
13894                         title: this.element.attr( "title" )
13895                 } )
13896                         .insertAfter( this.element );
13897 
13898                 this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13899                         "ui-button ui-widget" );
13900 
13901                 icon = $( "<span>" ).appendTo( this.button );
13902                 this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13903                 this.buttonItem = this._renderButtonItem( item )
13904                         .appendTo( this.button );
13905 
13906                 if ( this.options.width !== false ) {
13907                         this._resizeButton();
13908                 }
13909 
13910                 this._on( this.button, this._buttonEvents );
13911                 this.button.one( "focusin", function() {
13912 
13913                         // Delay rendering the menu items until the button receives focus.
13914                         // The menu may have already been rendered via a programmatic open.
13915                         if ( !that._rendered ) {
13916                                 that._refreshMenu();
13917                         }
13918                 } );
13919         },
13920 
13921         _drawMenu: function() {
13922                 var that = this;
13923 
13924                 // Create menu
13925                 this.menu = $( "<ul>", {
13926                         "aria-hidden": "true",
13927                         "aria-labelledby": this.ids.button,
13928                         id: this.ids.menu
13929                 } );
13930 
13931                 // Wrap menu
13932                 this.menuWrap = $( "<div>" ).append( this.menu );
13933                 this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13934                 this.menuWrap.appendTo( this._appendTo() );
13935 
13936                 // Initialize menu widget
13937                 this.menuInstance = this.menu
13938                         .menu( {
13939                                 classes: {
13940                                         "ui-menu": "ui-corner-bottom"
13941                                 },
13942                                 role: "listbox",
13943                                 select: function( event, ui ) {
13944                                         event.preventDefault();
13945 
13946                                         // Support: IE8
13947                                         // If the item was selected via a click, the text selection
13948                                         // will be destroyed in IE
13949                                         that._setSelection();
13950 
13951                                         that._select( ui.item.data( "ui-selectmenu-item" ), event );
13952                                 },
13953                                 focus: function( event, ui ) {
13954                                         var item = ui.item.data( "ui-selectmenu-item" );
13955 
13956                                         // Prevent inital focus from firing and check if its a newly focused item
13957                                         if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13958                                                 that._trigger( "focus", event, { item: item } );
13959                                                 if ( !that.isOpen ) {
13960                                                         that._select( item, event );
13961                                                 }
13962                                         }
13963                                         that.focusIndex = item.index;
13964 
13965                                         that.button.attr( "aria-activedescendant",
13966                                                 that.menuItems.eq( item.index ).attr( "id" ) );
13967                                 }
13968                         } )
13969                         .menu( "instance" );
13970 
13971                 // Don't close the menu on mouseleave
13972                 this.menuInstance._off( this.menu, "mouseleave" );
13973 
13974                 // Cancel the menu's collapseAll on document click
13975                 this.menuInstance._closeOnDocumentClick = function() {
13976                         return false;
13977                 };
13978 
13979                 // Selects often contain empty items, but never contain dividers
13980                 this.menuInstance._isDivider = function() {
13981                         return false;
13982                 };
13983         },
13984 
13985         refresh: function() {
13986                 this._refreshMenu();
13987                 this.buttonItem.replaceWith(
13988                         this.buttonItem = this._renderButtonItem(
13989 
13990                                 // Fall back to an empty object in case there are no options
13991                                 this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13992                         )
13993                 );
13994                 if ( this.options.width === null ) {
13995                         this._resizeButton();
13996                 }
13997         },
13998 
13999         _refreshMenu: function() {
14000                 var item,
14001                         options = this.element.find( "option" );
14002 
14003                 this.menu.empty();
14004 
14005                 this._parseOptions( options );
14006                 this._renderMenu( this.menu, this.items );
14007 
14008                 this.menuInstance.refresh();
14009                 this.menuItems = this.menu.find( "li" )
14010                         .not( ".ui-selectmenu-optgroup" )
14011                                 .find( ".ui-menu-item-wrapper" );
14012 
14013                 this._rendered = true;
14014 
14015                 if ( !options.length ) {
14016                         return;
14017                 }
14018 
14019                 item = this._getSelectedItem();
14020 
14021                 // Update the menu to have the correct item focused
14022                 this.menuInstance.focus( null, item );
14023                 this._setAria( item.data( "ui-selectmenu-item" ) );
14024 
14025                 // Set disabled state
14026                 this._setOption( "disabled", this.element.prop( "disabled" ) );
14027         },
14028 
14029         open: function( event ) {
14030                 if ( this.options.disabled ) {
14031                         return;
14032                 }
14033 
14034                 // If this is the first time the menu is being opened, render the items
14035                 if ( !this._rendered ) {
14036                         this._refreshMenu();
14037                 } else {
14038 
14039                         // Menu clears focus on close, reset focus to selected item
14040                         this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14041                         this.menuInstance.focus( null, this._getSelectedItem() );
14042                 }
14043 
14044                 // If there are no options, don't open the menu
14045                 if ( !this.menuItems.length ) {
14046                         return;
14047                 }
14048 
14049                 this.isOpen = true;
14050                 this._toggleAttr();
14051                 this._resizeMenu();
14052                 this._position();
14053 
14054                 this._on( this.document, this._documentClick );
14055 
14056                 this._trigger( "open", event );
14057         },
14058 
14059         _position: function() {
14060                 this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14061         },
14062 
14063         close: function( event ) {
14064                 if ( !this.isOpen ) {
14065                         return;
14066                 }
14067 
14068                 this.isOpen = false;
14069                 this._toggleAttr();
14070 
14071                 this.range = null;
14072                 this._off( this.document );
14073 
14074                 this._trigger( "close", event );
14075         },
14076 
14077         widget: function() {
14078                 return this.button;
14079         },
14080 
14081         menuWidget: function() {
14082                 return this.menu;
14083         },
14084 
14085         _renderButtonItem: function( item ) {
14086                 var buttonItem = $( "<span>" );
14087 
14088                 this._setText( buttonItem, item.label );
14089                 this._addClass( buttonItem, "ui-selectmenu-text" );
14090 
14091                 return buttonItem;
14092         },
14093 
14094         _renderMenu: function( ul, items ) {
14095                 var that = this,
14096                         currentOptgroup = "";
14097 
14098                 $.each( items, function( index, item ) {
14099                         var li;
14100 
14101                         if ( item.optgroup !== currentOptgroup ) {
14102                                 li = $( "<li>", {
14103                                         text: item.optgroup
14104                                 } );
14105                                 that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14106                                         ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14107                                                 " ui-state-disabled" :
14108                                                 "" ) );
14109 
14110                                 li.appendTo( ul );
14111 
14112                                 currentOptgroup = item.optgroup;
14113                         }
14114 
14115                         that._renderItemData( ul, item );
14116                 } );
14117         },
14118 
14119         _renderItemData: function( ul, item ) {
14120                 return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14121         },
14122 
14123         _renderItem: function( ul, item ) {
14124                 var li = $( "<li>" ),
14125                         wrapper = $( "<div>", {
14126                                 title: item.element.attr( "title" )
14127                         } );
14128 
14129                 if ( item.disabled ) {
14130                         this._addClass( li, null, "ui-state-disabled" );
14131                 }
14132                 this._setText( wrapper, item.label );
14133 
14134                 return li.append( wrapper ).appendTo( ul );
14135         },
14136 
14137         _setText: function( element, value ) {
14138                 if ( value ) {
14139                         element.text( value );
14140                 } else {
14141                         element.html( "&#160;" );
14142                 }
14143         },
14144 
14145         _move: function( direction, event ) {
14146                 var item, next,
14147                         filter = ".ui-menu-item";
14148 
14149                 if ( this.isOpen ) {
14150                         item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14151                 } else {
14152                         item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14153                         filter += ":not(.ui-state-disabled)";
14154                 }
14155 
14156                 if ( direction === "first" || direction === "last" ) {
14157                         next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14158                 } else {
14159                         next = item[ direction + "All" ]( filter ).eq( 0 );
14160                 }
14161 
14162                 if ( next.length ) {
14163                         this.menuInstance.focus( event, next );
14164                 }
14165         },
14166 
14167         _getSelectedItem: function() {
14168                 return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14169         },
14170 
14171         _toggle: function( event ) {
14172                 this[ this.isOpen ? "close" : "open" ]( event );
14173         },
14174 
14175         _setSelection: function() {
14176                 var selection;
14177 
14178                 if ( !this.range ) {
14179                         return;
14180                 }
14181 
14182                 if ( window.getSelection ) {
14183                         selection = window.getSelection();
14184                         selection.removeAllRanges();
14185                         selection.addRange( this.range );
14186 
14187                 // Support: IE8
14188                 } else {
14189                         this.range.select();
14190                 }
14191 
14192                 // Support: IE
14193                 // Setting the text selection kills the button focus in IE, but
14194                 // restoring the focus doesn't kill the selection.
14195                 this.button.focus();
14196         },
14197 
14198         _documentClick: {
14199                 mousedown: function( event ) {
14200                         if ( !this.isOpen ) {
14201                                 return;
14202                         }
14203 
14204                         if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14205                                         $.ui.escapeSelector( this.ids.button ) ).length ) {
14206                                 this.close( event );
14207                         }
14208                 }
14209         },
14210 
14211         _buttonEvents: {
14212 
14213                 // Prevent text selection from being reset when interacting with the selectmenu (#10144)
14214                 mousedown: function() {
14215                         var selection;
14216 
14217                         if ( window.getSelection ) {
14218                                 selection = window.getSelection();
14219                                 if ( selection.rangeCount ) {
14220                                         this.range = selection.getRangeAt( 0 );
14221                                 }
14222 
14223                         // Support: IE8
14224                         } else {
14225                                 this.range = document.selection.createRange();
14226                         }
14227                 },
14228 
14229                 click: function( event ) {
14230                         this._setSelection();
14231                         this._toggle( event );
14232                 },
14233 
14234                 keydown: function( event ) {
14235                         var preventDefault = true;
14236                         switch ( event.keyCode ) {
14237                         case $.ui.keyCode.TAB:
14238                         case $.ui.keyCode.ESCAPE:
14239                                 this.close( event );
14240                                 preventDefault = false;
14241                                 break;
14242                         case $.ui.keyCode.ENTER:
14243                                 if ( this.isOpen ) {
14244                                         this._selectFocusedItem( event );
14245                                 }
14246                                 break;
14247                         case $.ui.keyCode.UP:
14248                                 if ( event.altKey ) {
14249                                         this._toggle( event );
14250                                 } else {
14251                                         this._move( "prev", event );
14252                                 }
14253                                 break;
14254                         case $.ui.keyCode.DOWN:
14255                                 if ( event.altKey ) {
14256                                         this._toggle( event );
14257                                 } else {
14258                                         this._move( "next", event );
14259                                 }
14260                                 break;
14261                         case $.ui.keyCode.SPACE:
14262                                 if ( this.isOpen ) {
14263                                         this._selectFocusedItem( event );
14264                                 } else {
14265                                         this._toggle( event );
14266                                 }
14267                                 break;
14268                         case $.ui.keyCode.LEFT:
14269                                 this._move( "prev", event );
14270                                 break;
14271                         case $.ui.keyCode.RIGHT:
14272                                 this._move( "next", event );
14273                                 break;
14274                         case $.ui.keyCode.HOME:
14275                         case $.ui.keyCode.PAGE_UP:
14276                                 this._move( "first", event );
14277                                 break;
14278                         case $.ui.keyCode.END:
14279                         case $.ui.keyCode.PAGE_DOWN:
14280                                 this._move( "last", event );
14281                                 break;
14282                         default:
14283                                 this.menu.trigger( event );
14284                                 preventDefault = false;
14285                         }
14286 
14287                         if ( preventDefault ) {
14288                                 event.preventDefault();
14289                         }
14290                 }
14291         },
14292 
14293         _selectFocusedItem: function( event ) {
14294                 var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14295                 if ( !item.hasClass( "ui-state-disabled" ) ) {
14296                         this._select( item.data( "ui-selectmenu-item" ), event );
14297                 }
14298         },
14299 
14300         _select: function( item, event ) {
14301                 var oldIndex = this.element[ 0 ].selectedIndex;
14302 
14303                 // Change native select element
14304                 this.element[ 0 ].selectedIndex = item.index;
14305                 this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14306                 this._setAria( item );
14307                 this._trigger( "select", event, { item: item } );
14308 
14309                 if ( item.index !== oldIndex ) {
14310                         this._trigger( "change", event, { item: item } );
14311                 }
14312 
14313                 this.close( event );
14314         },
14315 
14316         _setAria: function( item ) {
14317                 var id = this.menuItems.eq( item.index ).attr( "id" );
14318 
14319                 this.button.attr( {
14320                         "aria-labelledby": id,
14321                         "aria-activedescendant": id
14322                 } );
14323                 this.menu.attr( "aria-activedescendant", id );
14324         },
14325 
14326         _setOption: function( key, value ) {
14327                 if ( key === "icons" ) {
14328                         var icon = this.button.find( "span.ui-icon" );
14329                         this._removeClass( icon, null, this.options.icons.button )
14330                                 ._addClass( icon, null, value.button );
14331                 }
14332 
14333                 this._super( key, value );
14334 
14335                 if ( key === "appendTo" ) {
14336                         this.menuWrap.appendTo( this._appendTo() );
14337                 }
14338 
14339                 if ( key === "width" ) {
14340                         this._resizeButton();
14341                 }
14342         },
14343 
14344         _setOptionDisabled: function( value ) {
14345                 this._super( value );
14346 
14347                 this.menuInstance.option( "disabled", value );
14348                 this.button.attr( "aria-disabled", value );
14349                 this._toggleClass( this.button, null, "ui-state-disabled", value );
14350 
14351                 this.element.prop( "disabled", value );
14352                 if ( value ) {
14353                         this.button.attr( "tabindex", -1 );
14354                         this.close();
14355                 } else {
14356                         this.button.attr( "tabindex", 0 );
14357                 }
14358         },
14359 
14360         _appendTo: function() {
14361                 var element = this.options.appendTo;
14362 
14363                 if ( element ) {
14364                         element = element.jquery || element.nodeType ?
14365                                 $( element ) :
14366                                 this.document.find( element ).eq( 0 );
14367                 }
14368 
14369                 if ( !element || !element[ 0 ] ) {
14370                         element = this.element.closest( ".ui-front, dialog" );
14371                 }
14372 
14373                 if ( !element.length ) {
14374                         element = this.document[ 0 ].body;
14375                 }
14376 
14377                 return element;
14378         },
14379 
14380         _toggleAttr: function() {
14381                 this.button.attr( "aria-expanded", this.isOpen );
14382 
14383                 // We can't use two _toggleClass() calls here, because we need to make sure
14384                 // we always remove classes first and add them second, otherwise if both classes have the
14385                 // same theme class, it will be removed after we add it.
14386                 this._removeClass( this.button, "ui-selectmenu-button-" +
14387                         ( this.isOpen ? "closed" : "open" ) )
14388                         ._addClass( this.button, "ui-selectmenu-button-" +
14389                                 ( this.isOpen ? "open" : "closed" ) )
14390                         ._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14391 
14392                 this.menu.attr( "aria-hidden", !this.isOpen );
14393         },
14394 
14395         _resizeButton: function() {
14396                 var width = this.options.width;
14397 
14398                 // For `width: false`, just remove inline style and stop
14399                 if ( width === false ) {
14400                         this.button.css( "width", "" );
14401                         return;
14402                 }
14403 
14404                 // For `width: null`, match the width of the original element
14405                 if ( width === null ) {
14406                         width = this.element.show().outerWidth();
14407                         this.element.hide();
14408                 }
14409 
14410                 this.button.outerWidth( width );
14411         },
14412 
14413         _resizeMenu: function() {
14414                 this.menu.outerWidth( Math.max(
14415                         this.button.outerWidth(),
14416 
14417                         // Support: IE10
14418                         // IE10 wraps long text (possibly a rounding bug)
14419                         // so we add 1px to avoid the wrapping
14420                         this.menu.width( "" ).outerWidth() + 1
14421                 ) );
14422         },
14423 
14424         _getCreateOptions: function() {
14425                 var options = this._super();
14426 
14427                 options.disabled = this.element.prop( "disabled" );
14428 
14429                 return options;
14430         },
14431 
14432         _parseOptions: function( options ) {
14433                 var that = this,
14434                         data = [];
14435                 options.each( function( index, item ) {
14436                         data.push( that._parseOption( $( item ), index ) );
14437                 } );
14438                 this.items = data;
14439         },
14440 
14441         _parseOption: function( option, index ) {
14442                 var optgroup = option.parent( "optgroup" );
14443 
14444                 return {
14445                         element: option,
14446                         index: index,
14447                         value: option.val(),
14448                         label: option.text(),
14449                         optgroup: optgroup.attr( "label" ) || "",
14450                         disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14451                 };
14452         },
14453 
14454         _destroy: function() {
14455                 this._unbindFormResetHandler();
14456                 this.menuWrap.remove();
14457                 this.button.remove();
14458                 this.element.show();
14459                 this.element.removeUniqueId();
14460                 this.labels.attr( "for", this.ids.element );
14461         }
14462 } ] );
14463 
14464 
14465 /*!
14466  * jQuery UI Slider 1.12.1
14467  * http://jqueryui.com
14468  *
14469  * Copyright jQuery Foundation and other contributors
14470  * Released under the MIT license.
14471  * http://jquery.org/license
14472  */
14473 
14474 //>>label: Slider
14475 //>>group: Widgets
14476 //>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14477 //>>docs: http://api.jqueryui.com/slider/
14478 //>>demos: http://jqueryui.com/slider/
14479 //>>css.structure: ../../themes/base/core.css
14480 //>>css.structure: ../../themes/base/slider.css
14481 //>>css.theme: ../../themes/base/theme.css
14482 
14483 
14484 
14485 var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14486         version: "1.12.1",
14487         widgetEventPrefix: "slide",
14488 
14489         options: {
14490                 animate: false,
14491                 classes: {
14492                         "ui-slider": "ui-corner-all",
14493                         "ui-slider-handle": "ui-corner-all",
14494 
14495                         // Note: ui-widget-header isn't the most fittingly semantic framework class for this
14496                         // element, but worked best visually with a variety of themes
14497                         "ui-slider-range": "ui-corner-all ui-widget-header"
14498                 },
14499                 distance: 0,
14500                 max: 100,
14501                 min: 0,
14502                 orientation: "horizontal",
14503                 range: false,
14504                 step: 1,
14505                 value: 0,
14506                 values: null,
14507 
14508                 // Callbacks
14509                 change: null,
14510                 slide: null,
14511                 start: null,
14512                 stop: null
14513         },
14514 
14515         // Number of pages in a slider
14516         // (how many times can you page up/down to go through the whole range)
14517         numPages: 5,
14518 
14519         _create: function() {
14520                 this._keySliding = false;
14521                 this._mouseSliding = false;
14522                 this._animateOff = true;
14523                 this._handleIndex = null;
14524                 this._detectOrientation();
14525                 this._mouseInit();
14526                 this._calculateNewMax();
14527 
14528                 this._addClass( "ui-slider ui-slider-" + this.orientation,
14529                         "ui-widget ui-widget-content" );
14530 
14531                 this._refresh();
14532 
14533                 this._animateOff = false;
14534         },
14535 
14536         _refresh: function() {
14537                 this._createRange();
14538                 this._createHandles();
14539                 this._setupEvents();
14540                 this._refreshValue();
14541         },
14542 
14543         _createHandles: function() {
14544                 var i, handleCount,
14545                         options = this.options,
14546                         existingHandles = this.element.find( ".ui-slider-handle" ),
14547                         handle = "<span tabindex='0'></span>",
14548                         handles = [];
14549 
14550                 handleCount = ( options.values && options.values.length ) || 1;
14551 
14552                 if ( existingHandles.length > handleCount ) {
14553                         existingHandles.slice( handleCount ).remove();
14554                         existingHandles = existingHandles.slice( 0, handleCount );
14555                 }
14556 
14557                 for ( i = existingHandles.length; i < handleCount; i++ ) {
14558                         handles.push( handle );
14559                 }
14560 
14561                 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14562 
14563                 this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14564 
14565                 this.handle = this.handles.eq( 0 );
14566 
14567                 this.handles.each( function( i ) {
14568                         $( this )
14569                                 .data( "ui-slider-handle-index", i )
14570                                 .attr( "tabIndex", 0 );
14571                 } );
14572         },
14573 
14574         _createRange: function() {
14575                 var options = this.options;
14576 
14577                 if ( options.range ) {
14578                         if ( options.range === true ) {
14579                                 if ( !options.values ) {
14580                                         options.values = [ this._valueMin(), this._valueMin() ];
14581                                 } else if ( options.values.length && options.values.length !== 2 ) {
14582                                         options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14583                                 } else if ( $.isArray( options.values ) ) {
14584                                         options.values = options.values.slice( 0 );
14585                                 }
14586                         }
14587 
14588                         if ( !this.range || !this.range.length ) {
14589                                 this.range = $( "<div>" )
14590                                         .appendTo( this.element );
14591 
14592                                 this._addClass( this.range, "ui-slider-range" );
14593                         } else {
14594                                 this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14595 
14596                                 // Handle range switching from true to min/max
14597                                 this.range.css( {
14598                                         "left": "",
14599                                         "bottom": ""
14600                                 } );
14601                         }
14602                         if ( options.range === "min" || options.range === "max" ) {
14603                                 this._addClass( this.range, "ui-slider-range-" + options.range );
14604                         }
14605                 } else {
14606                         if ( this.range ) {
14607                                 this.range.remove();
14608                         }
14609                         this.range = null;
14610                 }
14611         },
14612 
14613         _setupEvents: function() {
14614                 this._off( this.handles );
14615                 this._on( this.handles, this._handleEvents );
14616                 this._hoverable( this.handles );
14617                 this._focusable( this.handles );
14618         },
14619 
14620         _destroy: function() {
14621                 this.handles.remove();
14622                 if ( this.range ) {
14623                         this.range.remove();
14624                 }
14625 
14626                 this._mouseDestroy();
14627         },
14628 
14629         _mouseCapture: function( event ) {
14630                 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14631                         that = this,
14632                         o = this.options;
14633 
14634                 if ( o.disabled ) {
14635                         return false;
14636                 }
14637 
14638                 this.elementSize = {
14639                         width: this.element.outerWidth(),
14640                         height: this.element.outerHeight()
14641                 };
14642                 this.elementOffset = this.element.offset();
14643 
14644                 position = { x: event.pageX, y: event.pageY };
14645                 normValue = this._normValueFromMouse( position );
14646                 distance = this._valueMax() - this._valueMin() + 1;
14647                 this.handles.each( function( i ) {
14648                         var thisDistance = Math.abs( normValue - that.values( i ) );
14649                         if ( ( distance > thisDistance ) ||
14650                                 ( distance === thisDistance &&
14651                                         ( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14652                                 distance = thisDistance;
14653                                 closestHandle = $( this );
14654                                 index = i;
14655                         }
14656                 } );
14657 
14658                 allowed = this._start( event, index );
14659                 if ( allowed === false ) {
14660                         return false;
14661                 }
14662                 this._mouseSliding = true;
14663 
14664                 this._handleIndex = index;
14665 
14666                 this._addClass( closestHandle, null, "ui-state-active" );
14667                 closestHandle.trigger( "focus" );
14668 
14669                 offset = closestHandle.offset();
14670                 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14671                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14672                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14673                         top: event.pageY - offset.top -
14674                                 ( closestHandle.height() / 2 ) -
14675                                 ( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14676                                 ( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14677                                 ( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14678                 };
14679 
14680                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14681                         this._slide( event, index, normValue );
14682                 }
14683                 this._animateOff = true;
14684                 return true;
14685         },
14686 
14687         _mouseStart: function() {
14688                 return true;
14689         },
14690 
14691         _mouseDrag: function( event ) {
14692                 var position = { x: event.pageX, y: event.pageY },
14693                         normValue = this._normValueFromMouse( position );
14694 
14695                 this._slide( event, this._handleIndex, normValue );
14696 
14697                 return false;
14698         },
14699 
14700         _mouseStop: function( event ) {
14701                 this._removeClass( this.handles, null, "ui-state-active" );
14702                 this._mouseSliding = false;
14703 
14704                 this._stop( event, this._handleIndex );
14705                 this._change( event, this._handleIndex );
14706 
14707                 this._handleIndex = null;
14708                 this._clickOffset = null;
14709                 this._animateOff = false;
14710 
14711                 return false;
14712         },
14713 
14714         _detectOrientation: function() {
14715                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14716         },
14717 
14718         _normValueFromMouse: function( position ) {
14719                 var pixelTotal,
14720                         pixelMouse,
14721                         percentMouse,
14722                         valueTotal,
14723                         valueMouse;
14724 
14725                 if ( this.orientation === "horizontal" ) {
14726                         pixelTotal = this.elementSize.width;
14727                         pixelMouse = position.x - this.elementOffset.left -
14728                                 ( this._clickOffset ? this._clickOffset.left : 0 );
14729                 } else {
14730                         pixelTotal = this.elementSize.height;
14731                         pixelMouse = position.y - this.elementOffset.top -
14732                                 ( this._clickOffset ? this._clickOffset.top : 0 );
14733                 }
14734 
14735                 percentMouse = ( pixelMouse / pixelTotal );
14736                 if ( percentMouse > 1 ) {
14737                         percentMouse = 1;
14738                 }
14739                 if ( percentMouse < 0 ) {
14740                         percentMouse = 0;
14741                 }
14742                 if ( this.orientation === "vertical" ) {
14743                         percentMouse = 1 - percentMouse;
14744                 }
14745 
14746                 valueTotal = this._valueMax() - this._valueMin();
14747                 valueMouse = this._valueMin() + percentMouse * valueTotal;
14748 
14749                 return this._trimAlignValue( valueMouse );
14750         },
14751 
14752         _uiHash: function( index, value, values ) {
14753                 var uiHash = {
14754                         handle: this.handles[ index ],
14755                         handleIndex: index,
14756                         value: value !== undefined ? value : this.value()
14757                 };
14758 
14759                 if ( this._hasMultipleValues() ) {
14760                         uiHash.value = value !== undefined ? value : this.values( index );
14761                         uiHash.values = values || this.values();
14762                 }
14763 
14764                 return uiHash;
14765         },
14766 
14767         _hasMultipleValues: function() {
14768                 return this.options.values && this.options.values.length;
14769         },
14770 
14771         _start: function( event, index ) {
14772                 return this._trigger( "start", event, this._uiHash( index ) );
14773         },
14774 
14775         _slide: function( event, index, newVal ) {
14776                 var allowed, otherVal,
14777                         currentValue = this.value(),
14778                         newValues = this.values();
14779 
14780                 if ( this._hasMultipleValues() ) {
14781                         otherVal = this.values( index ? 0 : 1 );
14782                         currentValue = this.values( index );
14783 
14784                         if ( this.options.values.length === 2 && this.options.range === true ) {
14785                                 newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14786                         }
14787 
14788                         newValues[ index ] = newVal;
14789                 }
14790 
14791                 if ( newVal === currentValue ) {
14792                         return;
14793                 }
14794 
14795                 allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14796 
14797                 // A slide can be canceled by returning false from the slide callback
14798                 if ( allowed === false ) {
14799                         return;
14800                 }
14801 
14802                 if ( this._hasMultipleValues() ) {
14803                         this.values( index, newVal );
14804                 } else {
14805                         this.value( newVal );
14806                 }
14807         },
14808 
14809         _stop: function( event, index ) {
14810                 this._trigger( "stop", event, this._uiHash( index ) );
14811         },
14812 
14813         _change: function( event, index ) {
14814                 if ( !this._keySliding && !this._mouseSliding ) {
14815 
14816                         //store the last changed value index for reference when handles overlap
14817                         this._lastChangedValue = index;
14818                         this._trigger( "change", event, this._uiHash( index ) );
14819                 }
14820         },
14821 
14822         value: function( newValue ) {
14823                 if ( arguments.length ) {
14824                         this.options.value = this._trimAlignValue( newValue );
14825                         this._refreshValue();
14826                         this._change( null, 0 );
14827                         return;
14828                 }
14829 
14830                 return this._value();
14831         },
14832 
14833         values: function( index, newValue ) {
14834                 var vals,
14835                         newValues,
14836                         i;
14837 
14838                 if ( arguments.length > 1 ) {
14839                         this.options.values[ index ] = this._trimAlignValue( newValue );
14840                         this._refreshValue();
14841                         this._change( null, index );
14842                         return;
14843                 }
14844 
14845                 if ( arguments.length ) {
14846                         if ( $.isArray( arguments[ 0 ] ) ) {
14847                                 vals = this.options.values;
14848                                 newValues = arguments[ 0 ];
14849                                 for ( i = 0; i < vals.length; i += 1 ) {
14850                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
14851                                         this._change( null, i );
14852                                 }
14853                                 this._refreshValue();
14854                         } else {
14855                                 if ( this._hasMultipleValues() ) {
14856                                         return this._values( index );
14857                                 } else {
14858                                         return this.value();
14859                                 }
14860                         }
14861                 } else {
14862                         return this._values();
14863                 }
14864         },
14865 
14866         _setOption: function( key, value ) {
14867                 var i,
14868                         valsLength = 0;
14869 
14870                 if ( key === "range" && this.options.range === true ) {
14871                         if ( value === "min" ) {
14872                                 this.options.value = this._values( 0 );
14873                                 this.options.values = null;
14874                         } else if ( value === "max" ) {
14875                                 this.options.value = this._values( this.options.values.length - 1 );
14876                                 this.options.values = null;
14877                         }
14878                 }
14879 
14880                 if ( $.isArray( this.options.values ) ) {
14881                         valsLength = this.options.values.length;
14882                 }
14883 
14884                 this._super( key, value );
14885 
14886                 switch ( key ) {
14887                         case "orientation":
14888                                 this._detectOrientation();
14889                                 this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14890                                         ._addClass( "ui-slider-" + this.orientation );
14891                                 this._refreshValue();
14892                                 if ( this.options.range ) {
14893                                         this._refreshRange( value );
14894                                 }
14895 
14896                                 // Reset positioning from previous orientation
14897                                 this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14898                                 break;
14899                         case "value":
14900                                 this._animateOff = true;
14901                                 this._refreshValue();
14902                                 this._change( null, 0 );
14903                                 this._animateOff = false;
14904                                 break;
14905                         case "values":
14906                                 this._animateOff = true;
14907                                 this._refreshValue();
14908 
14909                                 // Start from the last handle to prevent unreachable handles (#9046)
14910                                 for ( i = valsLength - 1; i >= 0; i-- ) {
14911                                         this._change( null, i );
14912                                 }
14913                                 this._animateOff = false;
14914                                 break;
14915                         case "step":
14916                         case "min":
14917                         case "max":
14918                                 this._animateOff = true;
14919                                 this._calculateNewMax();
14920                                 this._refreshValue();
14921                                 this._animateOff = false;
14922                                 break;
14923                         case "range":
14924                                 this._animateOff = true;
14925                                 this._refresh();
14926                                 this._animateOff = false;
14927                                 break;
14928                 }
14929         },
14930 
14931         _setOptionDisabled: function( value ) {
14932                 this._super( value );
14933 
14934                 this._toggleClass( null, "ui-state-disabled", !!value );
14935         },
14936 
14937         //internal value getter
14938         // _value() returns value trimmed by min and max, aligned by step
14939         _value: function() {
14940                 var val = this.options.value;
14941                 val = this._trimAlignValue( val );
14942 
14943                 return val;
14944         },
14945 
14946         //internal values getter
14947         // _values() returns array of values trimmed by min and max, aligned by step
14948         // _values( index ) returns single value trimmed by min and max, aligned by step
14949         _values: function( index ) {
14950                 var val,
14951                         vals,
14952                         i;
14953 
14954                 if ( arguments.length ) {
14955                         val = this.options.values[ index ];
14956                         val = this._trimAlignValue( val );
14957 
14958                         return val;
14959                 } else if ( this._hasMultipleValues() ) {
14960 
14961                         // .slice() creates a copy of the array
14962                         // this copy gets trimmed by min and max and then returned
14963                         vals = this.options.values.slice();
14964                         for ( i = 0; i < vals.length; i += 1 ) {
14965                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
14966                         }
14967 
14968                         return vals;
14969                 } else {
14970                         return [];
14971                 }
14972         },
14973 
14974         // Returns the step-aligned value that val is closest to, between (inclusive) min and max
14975         _trimAlignValue: function( val ) {
14976                 if ( val <= this._valueMin() ) {
14977                         return this._valueMin();
14978                 }
14979                 if ( val >= this._valueMax() ) {
14980                         return this._valueMax();
14981                 }
14982                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
14983                         valModStep = ( val - this._valueMin() ) % step,
14984                         alignValue = val - valModStep;
14985 
14986                 if ( Math.abs( valModStep ) * 2 >= step ) {
14987                         alignValue += ( valModStep > 0 ) ? step : ( -step );
14988                 }
14989 
14990                 // Since JavaScript has problems with large floats, round
14991                 // the final value to 5 digits after the decimal point (see #4124)
14992                 return parseFloat( alignValue.toFixed( 5 ) );
14993         },
14994 
14995         _calculateNewMax: function() {
14996                 var max = this.options.max,
14997                         min = this._valueMin(),
14998                         step = this.options.step,
14999                         aboveMin = Math.round( ( max - min ) / step ) * step;
15000                 max = aboveMin + min;
15001                 if ( max > this.options.max ) {
15002 
15003                         //If max is not divisible by step, rounding off may increase its value
15004                         max -= step;
15005                 }
15006                 this.max = parseFloat( max.toFixed( this._precision() ) );
15007         },
15008 
15009         _precision: function() {
15010                 var precision = this._precisionOf( this.options.step );
15011                 if ( this.options.min !== null ) {
15012                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
15013                 }
15014                 return precision;
15015         },
15016 
15017         _precisionOf: function( num ) {
15018                 var str = num.toString(),
15019                         decimal = str.indexOf( "." );
15020                 return decimal === -1 ? 0 : str.length - decimal - 1;
15021         },
15022 
15023         _valueMin: function() {
15024                 return this.options.min;
15025         },
15026 
15027         _valueMax: function() {
15028                 return this.max;
15029         },
15030 
15031         _refreshRange: function( orientation ) {
15032                 if ( orientation === "vertical" ) {
15033                         this.range.css( { "width": "", "left": "" } );
15034                 }
15035                 if ( orientation === "horizontal" ) {
15036                         this.range.css( { "height": "", "bottom": "" } );
15037                 }
15038         },
15039 
15040         _refreshValue: function() {
15041                 var lastValPercent, valPercent, value, valueMin, valueMax,
15042                         oRange = this.options.range,
15043                         o = this.options,
15044                         that = this,
15045                         animate = ( !this._animateOff ) ? o.animate : false,
15046                         _set = {};
15047 
15048                 if ( this._hasMultipleValues() ) {
15049                         this.handles.each( function( i ) {
15050                                 valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15051                                         that._valueMin() ) * 100;
15052                                 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15053                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15054                                 if ( that.options.range === true ) {
15055                                         if ( that.orientation === "horizontal" ) {
15056                                                 if ( i === 0 ) {
15057                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15058                                                                 left: valPercent + "%"
15059                                                         }, o.animate );
15060                                                 }
15061                                                 if ( i === 1 ) {
15062                                                         that.range[ animate ? "animate" : "css" ]( {
15063                                                                 width: ( valPercent - lastValPercent ) + "%"
15064                                                         }, {
15065                                                                 queue: false,
15066                                                                 duration: o.animate
15067                                                         } );
15068                                                 }
15069                                         } else {
15070                                                 if ( i === 0 ) {
15071                                                         that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15072                                                                 bottom: ( valPercent ) + "%"
15073                                                         }, o.animate );
15074                                                 }
15075                                                 if ( i === 1 ) {
15076                                                         that.range[ animate ? "animate" : "css" ]( {
15077                                                                 height: ( valPercent - lastValPercent ) + "%"
15078                                                         }, {
15079                                                                 queue: false,
15080                                                                 duration: o.animate
15081                                                         } );
15082                                                 }
15083                                         }
15084                                 }
15085                                 lastValPercent = valPercent;
15086                         } );
15087                 } else {
15088                         value = this.value();
15089                         valueMin = this._valueMin();
15090                         valueMax = this._valueMax();
15091                         valPercent = ( valueMax !== valueMin ) ?
15092                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15093                                         0;
15094                         _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15095                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15096 
15097                         if ( oRange === "min" && this.orientation === "horizontal" ) {
15098                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15099                                         width: valPercent + "%"
15100                                 }, o.animate );
15101                         }
15102                         if ( oRange === "max" && this.orientation === "horizontal" ) {
15103                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15104                                         width: ( 100 - valPercent ) + "%"
15105                                 }, o.animate );
15106                         }
15107                         if ( oRange === "min" && this.orientation === "vertical" ) {
15108                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15109                                         height: valPercent + "%"
15110                                 }, o.animate );
15111                         }
15112                         if ( oRange === "max" && this.orientation === "vertical" ) {
15113                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15114                                         height: ( 100 - valPercent ) + "%"
15115                                 }, o.animate );
15116                         }
15117                 }
15118         },
15119 
15120         _handleEvents: {
15121                 keydown: function( event ) {
15122                         var allowed, curVal, newVal, step,
15123                                 index = $( event.target ).data( "ui-slider-handle-index" );
15124 
15125                         switch ( event.keyCode ) {
15126                                 case $.ui.keyCode.HOME:
15127                                 case $.ui.keyCode.END:
15128                                 case $.ui.keyCode.PAGE_UP:
15129                                 case $.ui.keyCode.PAGE_DOWN:
15130                                 case $.ui.keyCode.UP:
15131                                 case $.ui.keyCode.RIGHT:
15132                                 case $.ui.keyCode.DOWN:
15133                                 case $.ui.keyCode.LEFT:
15134                                         event.preventDefault();
15135                                         if ( !this._keySliding ) {
15136                                                 this._keySliding = true;
15137                                                 this._addClass( $( event.target ), null, "ui-state-active" );
15138                                                 allowed = this._start( event, index );
15139                                                 if ( allowed === false ) {
15140                                                         return;
15141                                                 }
15142                                         }
15143                                         break;
15144                         }
15145 
15146                         step = this.options.step;
15147                         if ( this._hasMultipleValues() ) {
15148                                 curVal = newVal = this.values( index );
15149                         } else {
15150                                 curVal = newVal = this.value();
15151                         }
15152 
15153                         switch ( event.keyCode ) {
15154                                 case $.ui.keyCode.HOME:
15155                                         newVal = this._valueMin();
15156                                         break;
15157                                 case $.ui.keyCode.END:
15158                                         newVal = this._valueMax();
15159                                         break;
15160                                 case $.ui.keyCode.PAGE_UP:
15161                                         newVal = this._trimAlignValue(
15162                                                 curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15163                                         );
15164                                         break;
15165                                 case $.ui.keyCode.PAGE_DOWN:
15166                                         newVal = this._trimAlignValue(
15167                                                 curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15168                                         break;
15169                                 case $.ui.keyCode.UP:
15170                                 case $.ui.keyCode.RIGHT:
15171                                         if ( curVal === this._valueMax() ) {
15172                                                 return;
15173                                         }
15174                                         newVal = this._trimAlignValue( curVal + step );
15175                                         break;
15176                                 case $.ui.keyCode.DOWN:
15177                                 case $.ui.keyCode.LEFT:
15178                                         if ( curVal === this._valueMin() ) {
15179                                                 return;
15180                                         }
15181                                         newVal = this._trimAlignValue( curVal - step );
15182                                         break;
15183                         }
15184 
15185                         this._slide( event, index, newVal );
15186                 },
15187                 keyup: function( event ) {
15188                         var index = $( event.target ).data( "ui-slider-handle-index" );
15189 
15190                         if ( this._keySliding ) {
15191                                 this._keySliding = false;
15192                                 this._stop( event, index );
15193                                 this._change( event, index );
15194                                 this._removeClass( $( event.target ), null, "ui-state-active" );
15195                         }
15196                 }
15197         }
15198 } );
15199 
15200 
15201 /*!
15202  * jQuery UI Sortable 1.12.1
15203  * http://jqueryui.com
15204  *
15205  * Copyright jQuery Foundation and other contributors
15206  * Released under the MIT license.
15207  * http://jquery.org/license
15208  */
15209 
15210 //>>label: Sortable
15211 //>>group: Interactions
15212 //>>description: Enables items in a list to be sorted using the mouse.
15213 //>>docs: http://api.jqueryui.com/sortable/
15214 //>>demos: http://jqueryui.com/sortable/
15215 //>>css.structure: ../../themes/base/sortable.css
15216 
15217 
15218 
15219 var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15220         version: "1.12.1",
15221         widgetEventPrefix: "sort",
15222         ready: false,
15223         options: {
15224                 appendTo: "parent",
15225                 axis: false,
15226                 connectWith: false,
15227                 containment: false,
15228                 cursor: "auto",
15229                 cursorAt: false,
15230                 dropOnEmpty: true,
15231                 forcePlaceholderSize: false,
15232                 forceHelperSize: false,
15233                 grid: false,
15234                 handle: false,
15235                 helper: "original",
15236                 items: "> *",
15237                 opacity: false,
15238                 placeholder: false,
15239                 revert: false,
15240                 scroll: true,
15241                 scrollSensitivity: 20,
15242                 scrollSpeed: 20,
15243                 scope: "default",
15244                 tolerance: "intersect",
15245                 zIndex: 1000,
15246 
15247                 // Callbacks
15248                 activate: null,
15249                 beforeStop: null,
15250                 change: null,
15251                 deactivate: null,
15252                 out: null,
15253                 over: null,
15254                 receive: null,
15255                 remove: null,
15256                 sort: null,
15257                 start: null,
15258                 stop: null,
15259                 update: null
15260         },
15261 
15262         _isOverAxis: function( x, reference, size ) {
15263                 return ( x >= reference ) && ( x < ( reference + size ) );
15264         },
15265 
15266         _isFloating: function( item ) {
15267                 return ( /left|right/ ).test( item.css( "float" ) ) ||
15268                         ( /inline|table-cell/ ).test( item.css( "display" ) );
15269         },
15270 
15271         _create: function() {
15272                 this.containerCache = {};
15273                 this._addClass( "ui-sortable" );
15274 
15275                 //Get the items
15276                 this.refresh();
15277 
15278                 //Let's determine the parent's offset
15279                 this.offset = this.element.offset();
15280 
15281                 //Initialize mouse events for interaction
15282                 this._mouseInit();
15283 
15284                 this._setHandleClassName();
15285 
15286                 //We're ready to go
15287                 this.ready = true;
15288 
15289         },
15290 
15291         _setOption: function( key, value ) {
15292                 this._super( key, value );
15293 
15294                 if ( key === "handle" ) {
15295                         this._setHandleClassName();
15296                 }
15297         },
15298 
15299         _setHandleClassName: function() {
15300                 var that = this;
15301                 this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15302                 $.each( this.items, function() {
15303                         that._addClass(
15304                                 this.instance.options.handle ?
15305                                         this.item.find( this.instance.options.handle ) :
15306                                         this.item,
15307                                 "ui-sortable-handle"
15308                         );
15309                 } );
15310         },
15311 
15312         _destroy: function() {
15313                 this._mouseDestroy();
15314 
15315                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
15316                         this.items[ i ].item.removeData( this.widgetName + "-item" );
15317                 }
15318 
15319                 return this;
15320         },
15321 
15322         _mouseCapture: function( event, overrideHandle ) {
15323                 var currentItem = null,
15324                         validHandle = false,
15325                         that = this;
15326 
15327                 if ( this.reverting ) {
15328                         return false;
15329                 }
15330 
15331                 if ( this.options.disabled || this.options.type === "static" ) {
15332                         return false;
15333                 }
15334 
15335                 //We have to refresh the items data once first
15336                 this._refreshItems( event );
15337 
15338                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
15339                 $( event.target ).parents().each( function() {
15340                         if ( $.data( this, that.widgetName + "-item" ) === that ) {
15341                                 currentItem = $( this );
15342                                 return false;
15343                         }
15344                 } );
15345                 if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15346                         currentItem = $( event.target );
15347                 }
15348 
15349                 if ( !currentItem ) {
15350                         return false;
15351                 }
15352                 if ( this.options.handle && !overrideHandle ) {
15353                         $( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15354                                 if ( this === event.target ) {
15355                                         validHandle = true;
15356                                 }
15357                         } );
15358                         if ( !validHandle ) {
15359                                 return false;
15360                         }
15361                 }
15362 
15363                 this.currentItem = currentItem;
15364                 this._removeCurrentsFromItems();
15365                 return true;
15366 
15367         },
15368 
15369         _mouseStart: function( event, overrideHandle, noActivation ) {
15370 
15371                 var i, body,
15372                         o = this.options;
15373 
15374                 this.currentContainer = this;
15375 
15376                 //We only need to call refreshPositions, because the refreshItems call has been moved to
15377                 // mouseCapture
15378                 this.refreshPositions();
15379 
15380                 //Create and append the visible helper
15381                 this.helper = this._createHelper( event );
15382 
15383                 //Cache the helper size
15384                 this._cacheHelperProportions();
15385 
15386                 /*
15387                  * - Position generation -
15388                  * This block generates everything position related - it's the core of draggables.
15389                  */
15390 
15391                 //Cache the margins of the original element
15392                 this._cacheMargins();
15393 
15394                 //Get the next scrolling parent
15395                 this.scrollParent = this.helper.scrollParent();
15396 
15397                 //The element's absolute position on the page minus margins
15398                 this.offset = this.currentItem.offset();
15399                 this.offset = {
15400                         top: this.offset.top - this.margins.top,
15401                         left: this.offset.left - this.margins.left
15402                 };
15403 
15404                 $.extend( this.offset, {
15405                         click: { //Where the click happened, relative to the element
15406                                 left: event.pageX - this.offset.left,
15407                                 top: event.pageY - this.offset.top
15408                         },
15409                         parent: this._getParentOffset(),
15410 
15411                         // This is a relative to absolute position minus the actual position calculation -
15412                         // only used for relative positioned helper
15413                         relative: this._getRelativeOffset()
15414                 } );
15415 
15416                 // Only after we got the offset, we can change the helper's position to absolute
15417                 // TODO: Still need to figure out a way to make relative sorting possible
15418                 this.helper.css( "position", "absolute" );
15419                 this.cssPosition = this.helper.css( "position" );
15420 
15421                 //Generate the original position
15422                 this.originalPosition = this._generatePosition( event );
15423                 this.originalPageX = event.pageX;
15424                 this.originalPageY = event.pageY;
15425 
15426                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15427                 ( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15428 
15429                 //Cache the former DOM position
15430                 this.domPosition = {
15431                         prev: this.currentItem.prev()[ 0 ],
15432                         parent: this.currentItem.parent()[ 0 ]
15433                 };
15434 
15435                 // If the helper is not the original, hide the original so it's not playing any role during
15436                 // the drag, won't cause anything bad this way
15437                 if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15438                         this.currentItem.hide();
15439                 }
15440 
15441                 //Create the placeholder
15442                 this._createPlaceholder();
15443 
15444                 //Set a containment if given in the options
15445                 if ( o.containment ) {
15446                         this._setContainment();
15447                 }
15448 
15449                 if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15450                         body = this.document.find( "body" );
15451 
15452                         // Support: IE
15453                         this.storedCursor = body.css( "cursor" );
15454                         body.css( "cursor", o.cursor );
15455 
15456                         this.storedStylesheet =
15457                                 $( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15458                 }
15459 
15460                 if ( o.opacity ) { // opacity option
15461                         if ( this.helper.css( "opacity" ) ) {
15462                                 this._storedOpacity = this.helper.css( "opacity" );
15463                         }
15464                         this.helper.css( "opacity", o.opacity );
15465                 }
15466 
15467                 if ( o.zIndex ) { // zIndex option
15468                         if ( this.helper.css( "zIndex" ) ) {
15469                                 this._storedZIndex = this.helper.css( "zIndex" );
15470                         }
15471                         this.helper.css( "zIndex", o.zIndex );
15472                 }
15473 
15474                 //Prepare scrolling
15475                 if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15476                                 this.scrollParent[ 0 ].tagName !== "HTML" ) {
15477                         this.overflowOffset = this.scrollParent.offset();
15478                 }
15479 
15480                 //Call callbacks
15481                 this._trigger( "start", event, this._uiHash() );
15482 
15483                 //Recache the helper size
15484                 if ( !this._preserveHelperProportions ) {
15485                         this._cacheHelperProportions();
15486                 }
15487 
15488                 //Post "activate" events to possible containers
15489                 if ( !noActivation ) {
15490                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
15491                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15492                         }
15493                 }
15494 
15495                 //Prepare possible droppables
15496                 if ( $.ui.ddmanager ) {
15497                         $.ui.ddmanager.current = this;
15498                 }
15499 
15500                 if ( $.ui.ddmanager && !o.dropBehaviour ) {
15501                         $.ui.ddmanager.prepareOffsets( this, event );
15502                 }
15503 
15504                 this.dragging = true;
15505 
15506                 this._addClass( this.helper, "ui-sortable-helper" );
15507 
15508                 // Execute the drag once - this causes the helper not to be visiblebefore getting its
15509                 // correct position
15510                 this._mouseDrag( event );
15511                 return true;
15512 
15513         },
15514 
15515         _mouseDrag: function( event ) {
15516                 var i, item, itemElement, intersection,
15517                         o = this.options,
15518                         scrolled = false;
15519 
15520                 //Compute the helpers position
15521                 this.position = this._generatePosition( event );
15522                 this.positionAbs = this._convertPositionTo( "absolute" );
15523 
15524                 if ( !this.lastPositionAbs ) {
15525                         this.lastPositionAbs = this.positionAbs;
15526                 }
15527 
15528                 //Do scrolling
15529                 if ( this.options.scroll ) {
15530                         if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15531                                         this.scrollParent[ 0 ].tagName !== "HTML" ) {
15532 
15533                                 if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15534                                                 event.pageY < o.scrollSensitivity ) {
15535                                         this.scrollParent[ 0 ].scrollTop =
15536                                                 scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15537                                 } else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15538                                         this.scrollParent[ 0 ].scrollTop =
15539                                                 scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15540                                 }
15541 
15542                                 if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15543                                                 event.pageX < o.scrollSensitivity ) {
15544                                         this.scrollParent[ 0 ].scrollLeft = scrolled =
15545                                                 this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15546                                 } else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15547                                         this.scrollParent[ 0 ].scrollLeft = scrolled =
15548                                                 this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15549                                 }
15550 
15551                         } else {
15552 
15553                                 if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15554                                         scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15555                                 } else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15556                                                 o.scrollSensitivity ) {
15557                                         scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15558                                 }
15559 
15560                                 if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15561                                         scrolled = this.document.scrollLeft(
15562                                                 this.document.scrollLeft() - o.scrollSpeed
15563                                         );
15564                                 } else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15565                                                 o.scrollSensitivity ) {
15566                                         scrolled = this.document.scrollLeft(
15567                                                 this.document.scrollLeft() + o.scrollSpeed
15568                                         );
15569                                 }
15570 
15571                         }
15572 
15573                         if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15574                                 $.ui.ddmanager.prepareOffsets( this, event );
15575                         }
15576                 }
15577 
15578                 //Regenerate the absolute position used for position checks
15579                 this.positionAbs = this._convertPositionTo( "absolute" );
15580 
15581                 //Set the helper position
15582                 if ( !this.options.axis || this.options.axis !== "y" ) {
15583                         this.helper[ 0 ].style.left = this.position.left + "px";
15584                 }
15585                 if ( !this.options.axis || this.options.axis !== "x" ) {
15586                         this.helper[ 0 ].style.top = this.position.top + "px";
15587                 }
15588 
15589                 //Rearrange
15590                 for ( i = this.items.length - 1; i >= 0; i-- ) {
15591 
15592                         //Cache variables and intersection, continue if no intersection
15593                         item = this.items[ i ];
15594                         itemElement = item.item[ 0 ];
15595                         intersection = this._intersectsWithPointer( item );
15596                         if ( !intersection ) {
15597                                 continue;
15598                         }
15599 
15600                         // Only put the placeholder inside the current Container, skip all
15601                         // items from other containers. This works because when moving
15602                         // an item from one container to another the
15603                         // currentContainer is switched before the placeholder is moved.
15604                         //
15605                         // Without this, moving items in "sub-sortables" can cause
15606                         // the placeholder to jitter between the outer and inner container.
15607                         if ( item.instance !== this.currentContainer ) {
15608                                 continue;
15609                         }
15610 
15611                         // Cannot intersect with itself
15612                         // no useless actions that have been done before
15613                         // no action if the item moved is the parent of the item checked
15614                         if ( itemElement !== this.currentItem[ 0 ] &&
15615                                 this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15616                                 !$.contains( this.placeholder[ 0 ], itemElement ) &&
15617                                 ( this.options.type === "semi-dynamic" ?
15618                                         !$.contains( this.element[ 0 ], itemElement ) :
15619                                         true
15620                                 )
15621                         ) {
15622 
15623                                 this.direction = intersection === 1 ? "down" : "up";
15624 
15625                                 if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15626                                         this._rearrange( event, item );
15627                                 } else {
15628                                         break;
15629                                 }
15630 
15631                                 this._trigger( "change", event, this._uiHash() );
15632                                 break;
15633                         }
15634                 }
15635 
15636                 //Post events to containers
15637                 this._contactContainers( event );
15638 
15639                 //Interconnect with droppables
15640                 if ( $.ui.ddmanager ) {
15641                         $.ui.ddmanager.drag( this, event );
15642                 }
15643 
15644                 //Call callbacks
15645                 this._trigger( "sort", event, this._uiHash() );
15646 
15647                 this.lastPositionAbs = this.positionAbs;
15648                 return false;
15649 
15650         },
15651 
15652         _mouseStop: function( event, noPropagation ) {
15653 
15654                 if ( !event ) {
15655                         return;
15656                 }
15657 
15658                 //If we are using droppables, inform the manager about the drop
15659                 if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15660                         $.ui.ddmanager.drop( this, event );
15661                 }
15662 
15663                 if ( this.options.revert ) {
15664                         var that = this,
15665                                 cur = this.placeholder.offset(),
15666                                 axis = this.options.axis,
15667                                 animation = {};
15668 
15669                         if ( !axis || axis === "x" ) {
15670                                 animation.left = cur.left - this.offset.parent.left - this.margins.left +
15671                                         ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15672                                                 0 :
15673                                                 this.offsetParent[ 0 ].scrollLeft
15674                                         );
15675                         }
15676                         if ( !axis || axis === "y" ) {
15677                                 animation.top = cur.top - this.offset.parent.top - this.margins.top +
15678                                         ( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15679                                                 0 :
15680                                                 this.offsetParent[ 0 ].scrollTop
15681                                         );
15682                         }
15683                         this.reverting = true;
15684                         $( this.helper ).animate(
15685                                 animation,
15686                                 parseInt( this.options.revert, 10 ) || 500,
15687                                 function() {
15688                                         that._clear( event );
15689                                 }
15690                         );
15691                 } else {
15692                         this._clear( event, noPropagation );
15693                 }
15694 
15695                 return false;
15696 
15697         },
15698 
15699         cancel: function() {
15700 
15701                 if ( this.dragging ) {
15702 
15703                         this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15704 
15705                         if ( this.options.helper === "original" ) {
15706                                 this.currentItem.css( this._storedCSS );
15707                                 this._removeClass( this.currentItem, "ui-sortable-helper" );
15708                         } else {
15709                                 this.currentItem.show();
15710                         }
15711 
15712                         //Post deactivating events to containers
15713                         for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15714                                 this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15715                                 if ( this.containers[ i ].containerCache.over ) {
15716                                         this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15717                                         this.containers[ i ].containerCache.over = 0;
15718                                 }
15719                         }
15720 
15721                 }
15722 
15723                 if ( this.placeholder ) {
15724 
15725                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15726                         // it unbinds ALL events from the original node!
15727                         if ( this.placeholder[ 0 ].parentNode ) {
15728                                 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15729                         }
15730                         if ( this.options.helper !== "original" && this.helper &&
15731                                         this.helper[ 0 ].parentNode ) {
15732                                 this.helper.remove();
15733                         }
15734 
15735                         $.extend( this, {
15736                                 helper: null,
15737                                 dragging: false,
15738                                 reverting: false,
15739                                 _noFinalSort: null
15740                         } );
15741 
15742                         if ( this.domPosition.prev ) {
15743                                 $( this.domPosition.prev ).after( this.currentItem );
15744                         } else {
15745                                 $( this.domPosition.parent ).prepend( this.currentItem );
15746                         }
15747                 }
15748 
15749                 return this;
15750 
15751         },
15752 
15753         serialize: function( o ) {
15754 
15755                 var items = this._getItemsAsjQuery( o && o.connected ),
15756                         str = [];
15757                 o = o || {};
15758 
15759                 $( items ).each( function() {
15760                         var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15761                                 .match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15762                         if ( res ) {
15763                                 str.push(
15764                                         ( o.key || res[ 1 ] + "[]" ) +
15765                                         "=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15766                         }
15767                 } );
15768 
15769                 if ( !str.length && o.key ) {
15770                         str.push( o.key + "=" );
15771                 }
15772 
15773                 return str.join( "&" );
15774 
15775         },
15776 
15777         toArray: function( o ) {
15778 
15779                 var items = this._getItemsAsjQuery( o && o.connected ),
15780                         ret = [];
15781 
15782                 o = o || {};
15783 
15784                 items.each( function() {
15785                         ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15786                 } );
15787                 return ret;
15788 
15789         },
15790 
15791         /* Be careful with the following core functions */
15792         _intersectsWith: function( item ) {
15793 
15794                 var x1 = this.positionAbs.left,
15795                         x2 = x1 + this.helperProportions.width,
15796                         y1 = this.positionAbs.top,
15797                         y2 = y1 + this.helperProportions.height,
15798                         l = item.left,
15799                         r = l + item.width,
15800                         t = item.top,
15801                         b = t + item.height,
15802                         dyClick = this.offset.click.top,
15803                         dxClick = this.offset.click.left,
15804                         isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15805                                 ( y1 + dyClick ) < b ),
15806                         isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15807                                 ( x1 + dxClick ) < r ),
15808                         isOverElement = isOverElementHeight && isOverElementWidth;
15809 
15810                 if ( this.options.tolerance === "pointer" ||
15811                         this.options.forcePointerForContainers ||
15812                         ( this.options.tolerance !== "pointer" &&
15813                                 this.helperProportions[ this.floating ? "width" : "height" ] >
15814                                 item[ this.floating ? "width" : "height" ] )
15815                 ) {
15816                         return isOverElement;
15817                 } else {
15818 
15819                         return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15820                                 x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15821                                 t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15822                                 y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15823 
15824                 }
15825         },
15826 
15827         _intersectsWithPointer: function( item ) {
15828                 var verticalDirection, horizontalDirection,
15829                         isOverElementHeight = ( this.options.axis === "x" ) ||
15830                                 this._isOverAxis(
15831                                         this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15832                         isOverElementWidth = ( this.options.axis === "y" ) ||
15833                                 this._isOverAxis(
15834                                         this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15835                         isOverElement = isOverElementHeight && isOverElementWidth;
15836 
15837                 if ( !isOverElement ) {
15838                         return false;
15839                 }
15840 
15841                 verticalDirection = this._getDragVerticalDirection();
15842                 horizontalDirection = this._getDragHorizontalDirection();
15843 
15844                 return this.floating ?
15845                         ( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15846                         : ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15847 
15848         },
15849 
15850         _intersectsWithSides: function( item ) {
15851 
15852                 var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15853                                 this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15854                         isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15855                                 this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15856                         verticalDirection = this._getDragVerticalDirection(),
15857                         horizontalDirection = this._getDragHorizontalDirection();
15858 
15859                 if ( this.floating && horizontalDirection ) {
15860                         return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15861                                 ( horizontalDirection === "left" && !isOverRightHalf ) );
15862                 } else {
15863                         return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15864                                 ( verticalDirection === "up" && !isOverBottomHalf ) );
15865                 }
15866 
15867         },
15868 
15869         _getDragVerticalDirection: function() {
15870                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
15871                 return delta !== 0 && ( delta > 0 ? "down" : "up" );
15872         },
15873 
15874         _getDragHorizontalDirection: function() {
15875                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
15876                 return delta !== 0 && ( delta > 0 ? "right" : "left" );
15877         },
15878 
15879         refresh: function( event ) {
15880                 this._refreshItems( event );
15881                 this._setHandleClassName();
15882                 this.refreshPositions();
15883                 return this;
15884         },
15885 
15886         _connectWith: function() {
15887                 var options = this.options;
15888                 return options.connectWith.constructor === String ?
15889                         [ options.connectWith ] :
15890                         options.connectWith;
15891         },
15892 
15893         _getItemsAsjQuery: function( connected ) {
15894 
15895                 var i, j, cur, inst,
15896                         items = [],
15897                         queries = [],
15898                         connectWith = this._connectWith();
15899 
15900                 if ( connectWith && connected ) {
15901                         for ( i = connectWith.length - 1; i >= 0; i-- ) {
15902                                 cur = $( connectWith[ i ], this.document[ 0 ] );
15903                                 for ( j = cur.length - 1; j >= 0; j-- ) {
15904                                         inst = $.data( cur[ j ], this.widgetFullName );
15905                                         if ( inst && inst !== this && !inst.options.disabled ) {
15906                                                 queries.push( [ $.isFunction( inst.options.items ) ?
15907                                                         inst.options.items.call( inst.element ) :
15908                                                         $( inst.options.items, inst.element )
15909                                                                 .not( ".ui-sortable-helper" )
15910                                                                 .not( ".ui-sortable-placeholder" ), inst ] );
15911                                         }
15912                                 }
15913                         }
15914                 }
15915 
15916                 queries.push( [ $.isFunction( this.options.items ) ?
15917                         this.options.items
15918                                 .call( this.element, null, { options: this.options, item: this.currentItem } ) :
15919                         $( this.options.items, this.element )
15920                                 .not( ".ui-sortable-helper" )
15921                                 .not( ".ui-sortable-placeholder" ), this ] );
15922 
15923                 function addItems() {
15924                         items.push( this );
15925                 }
15926                 for ( i = queries.length - 1; i >= 0; i-- ) {
15927                         queries[ i ][ 0 ].each( addItems );
15928                 }
15929 
15930                 return $( items );
15931 
15932         },
15933 
15934         _removeCurrentsFromItems: function() {
15935 
15936                 var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15937 
15938                 this.items = $.grep( this.items, function( item ) {
15939                         for ( var j = 0; j < list.length; j++ ) {
15940                                 if ( list[ j ] === item.item[ 0 ] ) {
15941                                         return false;
15942                                 }
15943                         }
15944                         return true;
15945                 } );
15946 
15947         },
15948 
15949         _refreshItems: function( event ) {
15950 
15951                 this.items = [];
15952                 this.containers = [ this ];
15953 
15954                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
15955                         items = this.items,
15956                         queries = [ [ $.isFunction( this.options.items ) ?
15957                                 this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15958                                 $( this.options.items, this.element ), this ] ],
15959                         connectWith = this._connectWith();
15960 
15961                 //Shouldn't be run the first time through due to massive slow-down
15962                 if ( connectWith && this.ready ) {
15963                         for ( i = connectWith.length - 1; i >= 0; i-- ) {
15964                                 cur = $( connectWith[ i ], this.document[ 0 ] );
15965                                 for ( j = cur.length - 1; j >= 0; j-- ) {
15966                                         inst = $.data( cur[ j ], this.widgetFullName );
15967                                         if ( inst && inst !== this && !inst.options.disabled ) {
15968                                                 queries.push( [ $.isFunction( inst.options.items ) ?
15969                                                         inst.options.items
15970                                                                 .call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15971                                                         $( inst.options.items, inst.element ), inst ] );
15972                                                 this.containers.push( inst );
15973                                         }
15974                                 }
15975                         }
15976                 }
15977 
15978                 for ( i = queries.length - 1; i >= 0; i-- ) {
15979                         targetData = queries[ i ][ 1 ];
15980                         _queries = queries[ i ][ 0 ];
15981 
15982                         for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15983                                 item = $( _queries[ j ] );
15984 
15985                                 // Data for target checking (mouse manager)
15986                                 item.data( this.widgetName + "-item", targetData );
15987 
15988                                 items.push( {
15989                                         item: item,
15990                                         instance: targetData,
15991                                         width: 0, height: 0,
15992                                         left: 0, top: 0
15993                                 } );
15994                         }
15995                 }
15996 
15997         },
15998 
15999         refreshPositions: function( fast ) {
16000 
16001                 // Determine whether items are being displayed horizontally
16002                 this.floating = this.items.length ?
16003                         this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16004                         false;
16005 
16006                 //This has to be redone because due to the item being moved out/into the offsetParent,
16007                 // the offsetParent's position will change
16008                 if ( this.offsetParent && this.helper ) {
16009                         this.offset.parent = this._getParentOffset();
16010                 }
16011 
16012                 var i, item, t, p;
16013 
16014                 for ( i = this.items.length - 1; i >= 0; i-- ) {
16015                         item = this.items[ i ];
16016 
16017                         //We ignore calculating positions of all connected containers when we're not over them
16018                         if ( item.instance !== this.currentContainer && this.currentContainer &&
16019                                         item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16020                                 continue;
16021                         }
16022 
16023                         t = this.options.toleranceElement ?
16024                                 $( this.options.toleranceElement, item.item ) :
16025                                 item.item;
16026 
16027                         if ( !fast ) {
16028                                 item.width = t.outerWidth();
16029                                 item.height = t.outerHeight();
16030                         }
16031 
16032                         p = t.offset();
16033                         item.left = p.left;
16034                         item.top = p.top;
16035                 }
16036 
16037                 if ( this.options.custom && this.options.custom.refreshContainers ) {
16038                         this.options.custom.refreshContainers.call( this );
16039                 } else {
16040                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
16041                                 p = this.containers[ i ].element.offset();
16042                                 this.containers[ i ].containerCache.left = p.left;
16043                                 this.containers[ i ].containerCache.top = p.top;
16044                                 this.containers[ i ].containerCache.width =
16045                                         this.containers[ i ].element.outerWidth();
16046                                 this.containers[ i ].containerCache.height =
16047                                         this.containers[ i ].element.outerHeight();
16048                         }
16049                 }
16050 
16051                 return this;
16052         },
16053 
16054         _createPlaceholder: function( that ) {
16055                 that = that || this;
16056                 var className,
16057                         o = that.options;
16058 
16059                 if ( !o.placeholder || o.placeholder.constructor === String ) {
16060                         className = o.placeholder;
16061                         o.placeholder = {
16062                                 element: function() {
16063 
16064                                         var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16065                                                 element = $( "<" + nodeName + ">", that.document[ 0 ] );
16066 
16067                                                 that._addClass( element, "ui-sortable-placeholder",
16068                                                                 className || that.currentItem[ 0 ].className )
16069                                                         ._removeClass( element, "ui-sortable-helper" );
16070 
16071                                         if ( nodeName === "tbody" ) {
16072                                                 that._createTrPlaceholder(
16073                                                         that.currentItem.find( "tr" ).eq( 0 ),
16074                                                         $( "<tr>", that.document[ 0 ] ).appendTo( element )
16075                                                 );
16076                                         } else if ( nodeName === "tr" ) {
16077                                                 that._createTrPlaceholder( that.currentItem, element );
16078                                         } else if ( nodeName === "img" ) {
16079                                                 element.attr( "src", that.currentItem.attr( "src" ) );
16080                                         }
16081 
16082                                         if ( !className ) {
16083                                                 element.css( "visibility", "hidden" );
16084                                         }
16085 
16086                                         return element;
16087                                 },
16088                                 update: function( container, p ) {
16089 
16090                                         // 1. If a className is set as 'placeholder option, we don't force sizes -
16091                                         // the class is responsible for that
16092                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16093                                         // class name is specified
16094                                         if ( className && !o.forcePlaceholderSize ) {
16095                                                 return;
16096                                         }
16097 
16098                                         //If the element doesn't have a actual height by itself (without styles coming
16099                                         // from a stylesheet), it receives the inline height from the dragged item
16100                                         if ( !p.height() ) {
16101                                                 p.height(
16102                                                         that.currentItem.innerHeight() -
16103                                                         parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16104                                                         parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16105                                         }
16106                                         if ( !p.width() ) {
16107                                                 p.width(
16108                                                         that.currentItem.innerWidth() -
16109                                                         parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16110                                                         parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16111                                         }
16112                                 }
16113                         };
16114                 }
16115 
16116                 //Create the placeholder
16117                 that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16118 
16119                 //Append it after the actual current item
16120                 that.currentItem.after( that.placeholder );
16121 
16122                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16123                 o.placeholder.update( that, that.placeholder );
16124 
16125         },
16126 
16127         _createTrPlaceholder: function( sourceTr, targetTr ) {
16128                 var that = this;
16129 
16130                 sourceTr.children().each( function() {
16131                         $( "<td>&#160;</td>", that.document[ 0 ] )
16132                                 .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16133                                 .appendTo( targetTr );
16134                 } );
16135         },
16136 
16137         _contactContainers: function( event ) {
16138                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16139                         floating, axis,
16140                         innermostContainer = null,
16141                         innermostIndex = null;
16142 
16143                 // Get innermost container that intersects with item
16144                 for ( i = this.containers.length - 1; i >= 0; i-- ) {
16145 
16146                         // Never consider a container that's located within the item itself
16147                         if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16148                                 continue;
16149                         }
16150 
16151                         if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16152 
16153                                 // If we've already found a container and it's more "inner" than this, then continue
16154                                 if ( innermostContainer &&
16155                                                 $.contains(
16156                                                         this.containers[ i ].element[ 0 ],
16157                                                         innermostContainer.element[ 0 ] ) ) {
16158                                         continue;
16159                                 }
16160 
16161                                 innermostContainer = this.containers[ i ];
16162                                 innermostIndex = i;
16163 
16164                         } else {
16165 
16166                                 // container doesn't intersect. trigger "out" event if necessary
16167                                 if ( this.containers[ i ].containerCache.over ) {
16168                                         this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16169                                         this.containers[ i ].containerCache.over = 0;
16170                                 }
16171                         }
16172 
16173                 }
16174 
16175                 // If no intersecting containers found, return
16176                 if ( !innermostContainer ) {
16177                         return;
16178                 }
16179 
16180                 // Move the item into the container if it's not there already
16181                 if ( this.containers.length === 1 ) {
16182                         if ( !this.containers[ innermostIndex ].containerCache.over ) {
16183                                 this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16184                                 this.containers[ innermostIndex ].containerCache.over = 1;
16185                         }
16186                 } else {
16187 
16188                         // When entering a new container, we will find the item with the least distance and
16189                         // append our item near it
16190                         dist = 10000;
16191                         itemWithLeastDistance = null;
16192                         floating = innermostContainer.floating || this._isFloating( this.currentItem );
16193                         posProperty = floating ? "left" : "top";
16194                         sizeProperty = floating ? "width" : "height";
16195                         axis = floating ? "pageX" : "pageY";
16196 
16197                         for ( j = this.items.length - 1; j >= 0; j-- ) {
16198                                 if ( !$.contains(
16199                                                 this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16200                                 ) {
16201                                         continue;
16202                                 }
16203                                 if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16204                                         continue;
16205                                 }
16206 
16207                                 cur = this.items[ j ].item.offset()[ posProperty ];
16208                                 nearBottom = false;
16209                                 if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16210                                         nearBottom = true;
16211                                 }
16212 
16213                                 if ( Math.abs( event[ axis ] - cur ) < dist ) {
16214                                         dist = Math.abs( event[ axis ] - cur );
16215                                         itemWithLeastDistance = this.items[ j ];
16216                                         this.direction = nearBottom ? "up" : "down";
16217                                 }
16218                         }
16219 
16220                         //Check if dropOnEmpty is enabled
16221                         if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16222                                 return;
16223                         }
16224 
16225                         if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16226                                 if ( !this.currentContainer.containerCache.over ) {
16227                                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16228                                         this.currentContainer.containerCache.over = 1;
16229                                 }
16230                                 return;
16231                         }
16232 
16233                         itemWithLeastDistance ?
16234                                 this._rearrange( event, itemWithLeastDistance, null, true ) :
16235                                 this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16236                         this._trigger( "change", event, this._uiHash() );
16237                         this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16238                         this.currentContainer = this.containers[ innermostIndex ];
16239 
16240                         //Update the placeholder
16241                         this.options.placeholder.update( this.currentContainer, this.placeholder );
16242 
16243                         this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16244                         this.containers[ innermostIndex ].containerCache.over = 1;
16245                 }
16246 
16247         },
16248 
16249         _createHelper: function( event ) {
16250 
16251                 var o = this.options,
16252                         helper = $.isFunction( o.helper ) ?
16253                                 $( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16254                                 ( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16255 
16256                 //Add the helper to the DOM if that didn't happen already
16257                 if ( !helper.parents( "body" ).length ) {
16258                         $( o.appendTo !== "parent" ?
16259                                 o.appendTo :
16260                                 this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16261                 }
16262 
16263                 if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16264                         this._storedCSS = {
16265                                 width: this.currentItem[ 0 ].style.width,
16266                                 height: this.currentItem[ 0 ].style.height,
16267                                 position: this.currentItem.css( "position" ),
16268                                 top: this.currentItem.css( "top" ),
16269                                 left: this.currentItem.css( "left" )
16270                         };
16271                 }
16272 
16273                 if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16274                         helper.width( this.currentItem.width() );
16275                 }
16276                 if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16277                         helper.height( this.currentItem.height() );
16278                 }
16279 
16280                 return helper;
16281 
16282         },
16283 
16284         _adjustOffsetFromHelper: function( obj ) {
16285                 if ( typeof obj === "string" ) {
16286                         obj = obj.split( " " );
16287                 }
16288                 if ( $.isArray( obj ) ) {
16289                         obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16290                 }
16291                 if ( "left" in obj ) {
16292                         this.offset.click.left = obj.left + this.margins.left;
16293                 }
16294                 if ( "right" in obj ) {
16295                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16296                 }
16297                 if ( "top" in obj ) {
16298                         this.offset.click.top = obj.top + this.margins.top;
16299                 }
16300                 if ( "bottom" in obj ) {
16301                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16302                 }
16303         },
16304 
16305         _getParentOffset: function() {
16306 
16307                 //Get the offsetParent and cache its position
16308                 this.offsetParent = this.helper.offsetParent();
16309                 var po = this.offsetParent.offset();
16310 
16311                 // This is a special case where we need to modify a offset calculated on start, since the
16312                 // following happened:
16313                 // 1. The position of the helper is absolute, so it's position is calculated based on the
16314                 // next positioned parent
16315                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16316                 // the document, which means that the scroll is included in the initial calculation of the
16317                 // offset of the parent, and never recalculated upon drag
16318                 if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16319                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16320                         po.left += this.scrollParent.scrollLeft();
16321                         po.top += this.scrollParent.scrollTop();
16322                 }
16323 
16324                 // This needs to be actually done for all browsers, since pageX/pageY includes this
16325                 // information with an ugly IE fix
16326                 if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16327                                 ( this.offsetParent[ 0 ].tagName &&
16328                                 this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16329                         po = { top: 0, left: 0 };
16330                 }
16331 
16332                 return {
16333                         top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16334                         left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16335                 };
16336 
16337         },
16338 
16339         _getRelativeOffset: function() {
16340 
16341                 if ( this.cssPosition === "relative" ) {
16342                         var p = this.currentItem.position();
16343                         return {
16344                                 top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16345                                         this.scrollParent.scrollTop(),
16346                                 left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16347                                         this.scrollParent.scrollLeft()
16348                         };
16349                 } else {
16350                         return { top: 0, left: 0 };
16351                 }
16352 
16353         },
16354 
16355         _cacheMargins: function() {
16356                 this.margins = {
16357                         left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16358                         top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16359                 };
16360         },
16361 
16362         _cacheHelperProportions: function() {
16363                 this.helperProportions = {
16364                         width: this.helper.outerWidth(),
16365                         height: this.helper.outerHeight()
16366                 };
16367         },
16368 
16369         _setContainment: function() {
16370 
16371                 var ce, co, over,
16372                         o = this.options;
16373                 if ( o.containment === "parent" ) {
16374                         o.containment = this.helper[ 0 ].parentNode;
16375                 }
16376                 if ( o.containment === "document" || o.containment === "window" ) {
16377                         this.containment = [
16378                                 0 - this.offset.relative.left - this.offset.parent.left,
16379                                 0 - this.offset.relative.top - this.offset.parent.top,
16380                                 o.containment === "document" ?
16381                                         this.document.width() :
16382                                         this.window.width() - this.helperProportions.width - this.margins.left,
16383                                 ( o.containment === "document" ?
16384                                         ( this.document.height() || document.body.parentNode.scrollHeight ) :
16385                                         this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16386                                 ) - this.helperProportions.height - this.margins.top
16387                         ];
16388                 }
16389 
16390                 if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16391                         ce = $( o.containment )[ 0 ];
16392                         co = $( o.containment ).offset();
16393                         over = ( $( ce ).css( "overflow" ) !== "hidden" );
16394 
16395                         this.containment = [
16396                                 co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16397                                         ( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16398                                 co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16399                                         ( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16400                                 co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16401                                         ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16402                                         ( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16403                                         this.helperProportions.width - this.margins.left,
16404                                 co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16405                                         ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16406                                         ( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16407                                         this.helperProportions.height - this.margins.top
16408                         ];
16409                 }
16410 
16411         },
16412 
16413         _convertPositionTo: function( d, pos ) {
16414 
16415                 if ( !pos ) {
16416                         pos = this.position;
16417                 }
16418                 var mod = d === "absolute" ? 1 : -1,
16419                         scroll = this.cssPosition === "absolute" &&
16420                                 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16421                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16422                                         this.offsetParent :
16423                                         this.scrollParent,
16424                         scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16425 
16426                 return {
16427                         top: (
16428 
16429                                 // The absolute mouse position
16430                                 pos.top +
16431 
16432                                 // Only for relative positioned nodes: Relative offset from element to offset parent
16433                                 this.offset.relative.top * mod +
16434 
16435                                 // The offsetParent's offset without borders (offset + border)
16436                                 this.offset.parent.top * mod -
16437                                 ( ( this.cssPosition === "fixed" ?
16438                                         -this.scrollParent.scrollTop() :
16439                                         ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16440                         ),
16441                         left: (
16442 
16443                                 // The absolute mouse position
16444                                 pos.left +
16445 
16446                                 // Only for relative positioned nodes: Relative offset from element to offset parent
16447                                 this.offset.relative.left * mod +
16448 
16449                                 // The offsetParent's offset without borders (offset + border)
16450                                 this.offset.parent.left * mod   -
16451                                 ( ( this.cssPosition === "fixed" ?
16452                                         -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16453                                         scroll.scrollLeft() ) * mod )
16454                         )
16455                 };
16456 
16457         },
16458 
16459         _generatePosition: function( event ) {
16460 
16461                 var top, left,
16462                         o = this.options,
16463                         pageX = event.pageX,
16464                         pageY = event.pageY,
16465                         scroll = this.cssPosition === "absolute" &&
16466                                 !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16467                                 $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16468                                         this.offsetParent :
16469                                         this.scrollParent,
16470                                 scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16471 
16472                 // This is another very weird special case that only happens for relative elements:
16473                 // 1. If the css position is relative
16474                 // 2. and the scroll parent is the document or similar to the offset parent
16475                 // we have to refresh the relative offset during the scroll so there are no jumps
16476                 if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16477                                 this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16478                         this.offset.relative = this._getRelativeOffset();
16479                 }
16480 
16481                 /*
16482                  * - Position constraining -
16483                  * Constrain the position to a mix of grid, containment.
16484                  */
16485 
16486                 if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16487 
16488                         if ( this.containment ) {
16489                                 if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16490                                         pageX = this.containment[ 0 ] + this.offset.click.left;
16491                                 }
16492                                 if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16493                                         pageY = this.containment[ 1 ] + this.offset.click.top;
16494                                 }
16495                                 if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16496                                         pageX = this.containment[ 2 ] + this.offset.click.left;
16497                                 }
16498                                 if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16499                                         pageY = this.containment[ 3 ] + this.offset.click.top;
16500                                 }
16501                         }
16502 
16503                         if ( o.grid ) {
16504                                 top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16505                                         o.grid[ 1 ] ) * o.grid[ 1 ];
16506                                 pageY = this.containment ?
16507                                         ( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16508                                                 top - this.offset.click.top <= this.containment[ 3 ] ) ?
16509                                                         top :
16510                                                         ( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16511                                                                 top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16512                                                                 top;
16513 
16514                                 left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16515                                         o.grid[ 0 ] ) * o.grid[ 0 ];
16516                                 pageX = this.containment ?
16517                                         ( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16518                                                 left - this.offset.click.left <= this.containment[ 2 ] ) ?
16519                                                         left :
16520                                                         ( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16521                                                                 left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16522                                                                 left;
16523                         }
16524 
16525                 }
16526 
16527                 return {
16528                         top: (
16529 
16530                                 // The absolute mouse position
16531                                 pageY -
16532 
16533                                 // Click offset (relative to the element)
16534                                 this.offset.click.top -
16535 
16536                                 // Only for relative positioned nodes: Relative offset from element to offset parent
16537                                 this.offset.relative.top -
16538 
16539                                 // The offsetParent's offset without borders (offset + border)
16540                                 this.offset.parent.top +
16541                                 ( ( this.cssPosition === "fixed" ?
16542                                         -this.scrollParent.scrollTop() :
16543                                         ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16544                         ),
16545                         left: (
16546 
16547                                 // The absolute mouse position
16548                                 pageX -
16549 
16550                                 // Click offset (relative to the element)
16551                                 this.offset.click.left -
16552 
16553                                 // Only for relative positioned nodes: Relative offset from element to offset parent
16554                                 this.offset.relative.left -
16555 
16556                                 // The offsetParent's offset without borders (offset + border)
16557                                 this.offset.parent.left +
16558                                 ( ( this.cssPosition === "fixed" ?
16559                                         -this.scrollParent.scrollLeft() :
16560                                         scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16561                         )
16562                 };
16563 
16564         },
16565 
16566         _rearrange: function( event, i, a, hardRefresh ) {
16567 
16568                 a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16569                         i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16570                                 ( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16571 
16572                 //Various things done here to improve the performance:
16573                 // 1. we create a setTimeout, that calls refreshPositions
16574                 // 2. on the instance, we have a counter variable, that get's higher after every append
16575                 // 3. on the local scope, we copy the counter variable, and check in the timeout,
16576                 // if it's still the same
16577                 // 4. this lets only the last addition to the timeout stack through
16578                 this.counter = this.counter ? ++this.counter : 1;
16579                 var counter = this.counter;
16580 
16581                 this._delay( function() {
16582                         if ( counter === this.counter ) {
16583 
16584                                 //Precompute after each DOM insertion, NOT on mousemove
16585                                 this.refreshPositions( !hardRefresh );
16586                         }
16587                 } );
16588 
16589         },
16590 
16591         _clear: function( event, noPropagation ) {
16592 
16593                 this.reverting = false;
16594 
16595                 // We delay all events that have to be triggered to after the point where the placeholder
16596                 // has been removed and everything else normalized again
16597                 var i,
16598                         delayedTriggers = [];
16599 
16600                 // We first have to update the dom position of the actual currentItem
16601                 // Note: don't do it if the current item is already removed (by a user), or it gets
16602                 // reappended (see #4088)
16603                 if ( !this._noFinalSort && this.currentItem.parent().length ) {
16604                         this.placeholder.before( this.currentItem );
16605                 }
16606                 this._noFinalSort = null;
16607 
16608                 if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16609                         for ( i in this._storedCSS ) {
16610                                 if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16611                                         this._storedCSS[ i ] = "";
16612                                 }
16613                         }
16614                         this.currentItem.css( this._storedCSS );
16615                         this._removeClass( this.currentItem, "ui-sortable-helper" );
16616                 } else {
16617                         this.currentItem.show();
16618                 }
16619 
16620                 if ( this.fromOutside && !noPropagation ) {
16621                         delayedTriggers.push( function( event ) {
16622                                 this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16623                         } );
16624                 }
16625                 if ( ( this.fromOutside ||
16626                                 this.domPosition.prev !==
16627                                 this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16628                                 this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16629 
16630                         // Trigger update callback if the DOM position has changed
16631                         delayedTriggers.push( function( event ) {
16632                                 this._trigger( "update", event, this._uiHash() );
16633                         } );
16634                 }
16635 
16636                 // Check if the items Container has Changed and trigger appropriate
16637                 // events.
16638                 if ( this !== this.currentContainer ) {
16639                         if ( !noPropagation ) {
16640                                 delayedTriggers.push( function( event ) {
16641                                         this._trigger( "remove", event, this._uiHash() );
16642                                 } );
16643                                 delayedTriggers.push( ( function( c ) {
16644                                         return function( event ) {
16645                                                 c._trigger( "receive", event, this._uiHash( this ) );
16646                                         };
16647                                 } ).call( this, this.currentContainer ) );
16648                                 delayedTriggers.push( ( function( c ) {
16649                                         return function( event ) {
16650                                                 c._trigger( "update", event, this._uiHash( this ) );
16651                                         };
16652                                 } ).call( this, this.currentContainer ) );
16653                         }
16654                 }
16655 
16656                 //Post events to containers
16657                 function delayEvent( type, instance, container ) {
16658                         return function( event ) {
16659                                 container._trigger( type, event, instance._uiHash( instance ) );
16660                         };
16661                 }
16662                 for ( i = this.containers.length - 1; i >= 0; i-- ) {
16663                         if ( !noPropagation ) {
16664                                 delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16665                         }
16666                         if ( this.containers[ i ].containerCache.over ) {
16667                                 delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16668                                 this.containers[ i ].containerCache.over = 0;
16669                         }
16670                 }
16671 
16672                 //Do what was originally in plugins
16673                 if ( this.storedCursor ) {
16674                         this.document.find( "body" ).css( "cursor", this.storedCursor );
16675                         this.storedStylesheet.remove();
16676                 }
16677                 if ( this._storedOpacity ) {
16678                         this.helper.css( "opacity", this._storedOpacity );
16679                 }
16680                 if ( this._storedZIndex ) {
16681                         this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16682                 }
16683 
16684                 this.dragging = false;
16685 
16686                 if ( !noPropagation ) {
16687                         this._trigger( "beforeStop", event, this._uiHash() );
16688                 }
16689 
16690                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16691                 // it unbinds ALL events from the original node!
16692                 this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16693 
16694                 if ( !this.cancelHelperRemoval ) {
16695                         if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16696                                 this.helper.remove();
16697                         }
16698                         this.helper = null;
16699                 }
16700 
16701                 if ( !noPropagation ) {
16702                         for ( i = 0; i < delayedTriggers.length; i++ ) {
16703 
16704                                 // Trigger all delayed events
16705                                 delayedTriggers[ i ].call( this, event );
16706                         }
16707                         this._trigger( "stop", event, this._uiHash() );
16708                 }
16709 
16710                 this.fromOutside = false;
16711                 return !this.cancelHelperRemoval;
16712 
16713         },
16714 
16715         _trigger: function() {
16716                 if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16717                         this.cancel();
16718                 }
16719         },
16720 
16721         _uiHash: function( _inst ) {
16722                 var inst = _inst || this;
16723                 return {
16724                         helper: inst.helper,
16725                         placeholder: inst.placeholder || $( [] ),
16726                         position: inst.position,
16727                         originalPosition: inst.originalPosition,
16728                         offset: inst.positionAbs,
16729                         item: inst.currentItem,
16730                         sender: _inst ? _inst.element : null
16731                 };
16732         }
16733 
16734 } );
16735 
16736 
16737 /*!
16738  * jQuery UI Spinner 1.12.1
16739  * http://jqueryui.com
16740  *
16741  * Copyright jQuery Foundation and other contributors
16742  * Released under the MIT license.
16743  * http://jquery.org/license
16744  */
16745 
16746 //>>label: Spinner
16747 //>>group: Widgets
16748 //>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16749 //>>docs: http://api.jqueryui.com/spinner/
16750 //>>demos: http://jqueryui.com/spinner/
16751 //>>css.structure: ../../themes/base/core.css
16752 //>>css.structure: ../../themes/base/spinner.css
16753 //>>css.theme: ../../themes/base/theme.css
16754 
16755 
16756 
16757 function spinnerModifer( fn ) {
16758         return function() {
16759                 var previous = this.element.val();
16760                 fn.apply( this, arguments );
16761                 this._refresh();
16762                 if ( previous !== this.element.val() ) {
16763                         this._trigger( "change" );
16764                 }
16765         };
16766 }
16767 
16768 $.widget( "ui.spinner", {
16769         version: "1.12.1",
16770         defaultElement: "<input>",
16771         widgetEventPrefix: "spin",
16772         options: {
16773                 classes: {
16774                         "ui-spinner": "ui-corner-all",
16775                         "ui-spinner-down": "ui-corner-br",
16776                         "ui-spinner-up": "ui-corner-tr"
16777                 },
16778                 culture: null,
16779                 icons: {
16780                         down: "ui-icon-triangle-1-s",
16781                         up: "ui-icon-triangle-1-n"
16782                 },
16783                 incremental: true,
16784                 max: null,
16785                 min: null,
16786                 numberFormat: null,
16787                 page: 10,
16788                 step: 1,
16789 
16790                 change: null,
16791                 spin: null,
16792                 start: null,
16793                 stop: null
16794         },
16795 
16796         _create: function() {
16797 
16798                 // handle string values that need to be parsed
16799                 this._setOption( "max", this.options.max );
16800                 this._setOption( "min", this.options.min );
16801                 this._setOption( "step", this.options.step );
16802 
16803                 // Only format if there is a value, prevents the field from being marked
16804                 // as invalid in Firefox, see #9573.
16805                 if ( this.value() !== "" ) {
16806 
16807                         // Format the value, but don't constrain.
16808                         this._value( this.element.val(), true );
16809                 }
16810 
16811                 this._draw();
16812                 this._on( this._events );
16813                 this._refresh();
16814 
16815                 // Turning off autocomplete prevents the browser from remembering the
16816                 // value when navigating through history, so we re-enable autocomplete
16817                 // if the page is unloaded before the widget is destroyed. #7790
16818                 this._on( this.window, {
16819                         beforeunload: function() {
16820                                 this.element.removeAttr( "autocomplete" );
16821                         }
16822                 } );
16823         },
16824 
16825         _getCreateOptions: function() {
16826                 var options = this._super();
16827                 var element = this.element;
16828 
16829                 $.each( [ "min", "max", "step" ], function( i, option ) {
16830                         var value = element.attr( option );
16831                         if ( value != null && value.length ) {
16832                                 options[ option ] = value;
16833                         }
16834                 } );
16835 
16836                 return options;
16837         },
16838 
16839         _events: {
16840                 keydown: function( event ) {
16841                         if ( this._start( event ) && this._keydown( event ) ) {
16842                                 event.preventDefault();
16843                         }
16844                 },
16845                 keyup: "_stop",
16846                 focus: function() {
16847                         this.previous = this.element.val();
16848                 },
16849                 blur: function( event ) {
16850                         if ( this.cancelBlur ) {
16851                                 delete this.cancelBlur;
16852                                 return;
16853                         }
16854 
16855                         this._stop();
16856                         this._refresh();
16857                         if ( this.previous !== this.element.val() ) {
16858                                 this._trigger( "change", event );
16859                         }
16860                 },
16861                 mousewheel: function( event, delta ) {
16862                         if ( !delta ) {
16863                                 return;
16864                         }
16865                         if ( !this.spinning && !this._start( event ) ) {
16866                                 return false;
16867                         }
16868 
16869                         this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16870                         clearTimeout( this.mousewheelTimer );
16871                         this.mousewheelTimer = this._delay( function() {
16872                                 if ( this.spinning ) {
16873                                         this._stop( event );
16874                                 }
16875                         }, 100 );
16876                         event.preventDefault();
16877                 },
16878                 "mousedown .ui-spinner-button": function( event ) {
16879                         var previous;
16880 
16881                         // We never want the buttons to have focus; whenever the user is
16882                         // interacting with the spinner, the focus should be on the input.
16883                         // If the input is focused then this.previous is properly set from
16884                         // when the input first received focus. If the input is not focused
16885                         // then we need to set this.previous based on the value before spinning.
16886                         previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16887                                 this.previous : this.element.val();
16888                         function checkFocus() {
16889                                 var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16890                                 if ( !isActive ) {
16891                                         this.element.trigger( "focus" );
16892                                         this.previous = previous;
16893 
16894                                         // support: IE
16895                                         // IE sets focus asynchronously, so we need to check if focus
16896                                         // moved off of the input because the user clicked on the button.
16897                                         this._delay( function() {
16898                                                 this.previous = previous;
16899                                         } );
16900                                 }
16901                         }
16902 
16903                         // Ensure focus is on (or stays on) the text field
16904                         event.preventDefault();
16905                         checkFocus.call( this );
16906 
16907                         // Support: IE
16908                         // IE doesn't prevent moving focus even with event.preventDefault()
16909                         // so we set a flag to know when we should ignore the blur event
16910                         // and check (again) if focus moved off of the input.
16911                         this.cancelBlur = true;
16912                         this._delay( function() {
16913                                 delete this.cancelBlur;
16914                                 checkFocus.call( this );
16915                         } );
16916 
16917                         if ( this._start( event ) === false ) {
16918                                 return;
16919                         }
16920 
16921                         this._repeat( null, $( event.currentTarget )
16922                                 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16923                 },
16924                 "mouseup .ui-spinner-button": "_stop",
16925                 "mouseenter .ui-spinner-button": function( event ) {
16926 
16927                         // button will add ui-state-active if mouse was down while mouseleave and kept down
16928                         if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16929                                 return;
16930                         }
16931 
16932                         if ( this._start( event ) === false ) {
16933                                 return false;
16934                         }
16935                         this._repeat( null, $( event.currentTarget )
16936                                 .hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16937                 },
16938 
16939                 // TODO: do we really want to consider this a stop?
16940                 // shouldn't we just stop the repeater and wait until mouseup before
16941                 // we trigger the stop event?
16942                 "mouseleave .ui-spinner-button": "_stop"
16943         },
16944 
16945         // Support mobile enhanced option and make backcompat more sane
16946         _enhance: function() {
16947                 this.uiSpinner = this.element
16948                         .attr( "autocomplete", "off" )
16949                         .wrap( "<span>" )
16950                         .parent()
16951 
16952                                 // Add buttons
16953                                 .append(
16954                                         "<a></a><a></a>"
16955                                 );
16956         },
16957 
16958         _draw: function() {
16959                 this._enhance();
16960 
16961                 this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16962                 this._addClass( "ui-spinner-input" );
16963 
16964                 this.element.attr( "role", "spinbutton" );
16965 
16966                 // Button bindings
16967                 this.buttons = this.uiSpinner.children( "a" )
16968                         .attr( "tabIndex", -1 )
16969                         .attr( "aria-hidden", true )
16970                         .button( {
16971                                 classes: {
16972                                         "ui-button": ""
16973                                 }
16974                         } );
16975 
16976                 // TODO: Right now button does not support classes this is already updated in button PR
16977                 this._removeClass( this.buttons, "ui-corner-all" );
16978 
16979                 this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16980                 this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16981                 this.buttons.first().button( {
16982                         "icon": this.options.icons.up,
16983                         "showLabel": false
16984                 } );
16985                 this.buttons.last().button( {
16986                         "icon": this.options.icons.down,
16987                         "showLabel": false
16988                 } );
16989 
16990                 // IE 6 doesn't understand height: 50% for the buttons
16991                 // unless the wrapper has an explicit height
16992                 if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16993                                 this.uiSpinner.height() > 0 ) {
16994                         this.uiSpinner.height( this.uiSpinner.height() );
16995                 }
16996         },
16997 
16998         _keydown: function( event ) {
16999                 var options = this.options,
17000                         keyCode = $.ui.keyCode;
17001 
17002                 switch ( event.keyCode ) {
17003                 case keyCode.UP:
17004                         this._repeat( null, 1, event );
17005                         return true;
17006                 case keyCode.DOWN:
17007                         this._repeat( null, -1, event );
17008                         return true;
17009                 case keyCode.PAGE_UP:
17010                         this._repeat( null, options.page, event );
17011                         return true;
17012                 case keyCode.PAGE_DOWN:
17013                         this._repeat( null, -options.page, event );
17014                         return true;
17015                 }
17016 
17017                 return false;
17018         },
17019 
17020         _start: function( event ) {
17021                 if ( !this.spinning && this._trigger( "start", event ) === false ) {
17022                         return false;
17023                 }
17024 
17025                 if ( !this.counter ) {
17026                         this.counter = 1;
17027                 }
17028                 this.spinning = true;
17029                 return true;
17030         },
17031 
17032         _repeat: function( i, steps, event ) {
17033                 i = i || 500;
17034 
17035                 clearTimeout( this.timer );
17036                 this.timer = this._delay( function() {
17037                         this._repeat( 40, steps, event );
17038                 }, i );
17039 
17040                 this._spin( steps * this.options.step, event );
17041         },
17042 
17043         _spin: function( step, event ) {
17044                 var value = this.value() || 0;
17045 
17046                 if ( !this.counter ) {
17047                         this.counter = 1;
17048                 }
17049 
17050                 value = this._adjustValue( value + step * this._increment( this.counter ) );
17051 
17052                 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17053                         this._value( value );
17054                         this.counter++;
17055                 }
17056         },
17057 
17058         _increment: function( i ) {
17059                 var incremental = this.options.incremental;
17060 
17061                 if ( incremental ) {
17062                         return $.isFunction( incremental ) ?
17063                                 incremental( i ) :
17064                                 Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17065                 }
17066 
17067                 return 1;
17068         },
17069 
17070         _precision: function() {
17071                 var precision = this._precisionOf( this.options.step );
17072                 if ( this.options.min !== null ) {
17073                         precision = Math.max( precision, this._precisionOf( this.options.min ) );
17074                 }
17075                 return precision;
17076         },
17077 
17078         _precisionOf: function( num ) {
17079                 var str = num.toString(),
17080                         decimal = str.indexOf( "." );
17081                 return decimal === -1 ? 0 : str.length - decimal - 1;
17082         },
17083 
17084         _adjustValue: function( value ) {
17085                 var base, aboveMin,
17086                         options = this.options;
17087 
17088                 // Make sure we're at a valid step
17089                 // - find out where we are relative to the base (min or 0)
17090                 base = options.min !== null ? options.min : 0;
17091                 aboveMin = value - base;
17092 
17093                 // - round to the nearest step
17094                 aboveMin = Math.round( aboveMin / options.step ) * options.step;
17095 
17096                 // - rounding is based on 0, so adjust back to our base
17097                 value = base + aboveMin;
17098 
17099                 // Fix precision from bad JS floating point math
17100                 value = parseFloat( value.toFixed( this._precision() ) );
17101 
17102                 // Clamp the value
17103                 if ( options.max !== null && value > options.max ) {
17104                         return options.max;
17105                 }
17106                 if ( options.min !== null && value < options.min ) {
17107                         return options.min;
17108                 }
17109 
17110                 return value;
17111         },
17112 
17113         _stop: function( event ) {
17114                 if ( !this.spinning ) {
17115                         return;
17116                 }
17117 
17118                 clearTimeout( this.timer );
17119                 clearTimeout( this.mousewheelTimer );
17120                 this.counter = 0;
17121                 this.spinning = false;
17122                 this._trigger( "stop", event );
17123         },
17124 
17125         _setOption: function( key, value ) {
17126                 var prevValue, first, last;
17127 
17128                 if ( key === "culture" || key === "numberFormat" ) {
17129                         prevValue = this._parse( this.element.val() );
17130                         this.options[ key ] = value;
17131                         this.element.val( this._format( prevValue ) );
17132                         return;
17133                 }
17134 
17135                 if ( key === "max" || key === "min" || key === "step" ) {
17136                         if ( typeof value === "string" ) {
17137                                 value = this._parse( value );
17138                         }
17139                 }
17140                 if ( key === "icons" ) {
17141                         first = this.buttons.first().find( ".ui-icon" );
17142                         this._removeClass( first, null, this.options.icons.up );
17143                         this._addClass( first, null, value.up );
17144                         last = this.buttons.last().find( ".ui-icon" );
17145                         this._removeClass( last, null, this.options.icons.down );
17146                         this._addClass( last, null, value.down );
17147                 }
17148 
17149                 this._super( key, value );
17150         },
17151 
17152         _setOptionDisabled: function( value ) {
17153                 this._super( value );
17154 
17155                 this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17156                 this.element.prop( "disabled", !!value );
17157                 this.buttons.button( value ? "disable" : "enable" );
17158         },
17159 
17160         _setOptions: spinnerModifer( function( options ) {
17161                 this._super( options );
17162         } ),
17163 
17164         _parse: function( val ) {
17165                 if ( typeof val === "string" && val !== "" ) {
17166                         val = window.Globalize && this.options.numberFormat ?
17167                                 Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17168                 }
17169                 return val === "" || isNaN( val ) ? null : val;
17170         },
17171 
17172         _format: function( value ) {
17173                 if ( value === "" ) {
17174                         return "";
17175                 }
17176                 return window.Globalize && this.options.numberFormat ?
17177                         Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17178                         value;
17179         },
17180 
17181         _refresh: function() {
17182                 this.element.attr( {
17183                         "aria-valuemin": this.options.min,
17184                         "aria-valuemax": this.options.max,
17185 
17186                         // TODO: what should we do with values that can't be parsed?
17187                         "aria-valuenow": this._parse( this.element.val() )
17188                 } );
17189         },
17190 
17191         isValid: function() {
17192                 var value = this.value();
17193 
17194                 // Null is invalid
17195                 if ( value === null ) {
17196                         return false;
17197                 }
17198 
17199                 // If value gets adjusted, it's invalid
17200                 return value === this._adjustValue( value );
17201         },
17202 
17203         // Update the value without triggering change
17204         _value: function( value, allowAny ) {
17205                 var parsed;
17206                 if ( value !== "" ) {
17207                         parsed = this._parse( value );
17208                         if ( parsed !== null ) {
17209                                 if ( !allowAny ) {
17210                                         parsed = this._adjustValue( parsed );
17211                                 }
17212                                 value = this._format( parsed );
17213                         }
17214                 }
17215                 this.element.val( value );
17216                 this._refresh();
17217         },
17218 
17219         _destroy: function() {
17220                 this.element
17221                         .prop( "disabled", false )
17222                         .removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17223 
17224                 this.uiSpinner.replaceWith( this.element );
17225         },
17226 
17227         stepUp: spinnerModifer( function( steps ) {
17228                 this._stepUp( steps );
17229         } ),
17230         _stepUp: function( steps ) {
17231                 if ( this._start() ) {
17232                         this._spin( ( steps || 1 ) * this.options.step );
17233                         this._stop();
17234                 }
17235         },
17236 
17237         stepDown: spinnerModifer( function( steps ) {
17238                 this._stepDown( steps );
17239         } ),
17240         _stepDown: function( steps ) {
17241                 if ( this._start() ) {
17242                         this._spin( ( steps || 1 ) * -this.options.step );
17243                         this._stop();
17244                 }
17245         },
17246 
17247         pageUp: spinnerModifer( function( pages ) {
17248                 this._stepUp( ( pages || 1 ) * this.options.page );
17249         } ),
17250 
17251         pageDown: spinnerModifer( function( pages ) {
17252                 this._stepDown( ( pages || 1 ) * this.options.page );
17253         } ),
17254 
17255         value: function( newVal ) {
17256                 if ( !arguments.length ) {
17257                         return this._parse( this.element.val() );
17258                 }
17259                 spinnerModifer( this._value ).call( this, newVal );
17260         },
17261 
17262         widget: function() {
17263                 return this.uiSpinner;
17264         }
17265 } );
17266 
17267 // DEPRECATED
17268 // TODO: switch return back to widget declaration at top of file when this is removed
17269 if ( $.uiBackCompat !== false ) {
17270 
17271         // Backcompat for spinner html extension points
17272         $.widget( "ui.spinner", $.ui.spinner, {
17273                 _enhance: function() {
17274                         this.uiSpinner = this.element
17275                                 .attr( "autocomplete", "off" )
17276                                 .wrap( this._uiSpinnerHtml() )
17277                                 .parent()
17278 
17279                                         // Add buttons
17280                                         .append( this._buttonHtml() );
17281                 },
17282                 _uiSpinnerHtml: function() {
17283                         return "<span>";
17284                 },
17285 
17286                 _buttonHtml: function() {
17287                         return "<a></a><a></a>";
17288                 }
17289         } );
17290 }
17291 
17292 var widgetsSpinner = $.ui.spinner;
17293 
17294 
17295 /*!
17296  * jQuery UI Tabs 1.12.1
17297  * http://jqueryui.com
17298  *
17299  * Copyright jQuery Foundation and other contributors
17300  * Released under the MIT license.
17301  * http://jquery.org/license
17302  */
17303 
17304 //>>label: Tabs
17305 //>>group: Widgets
17306 //>>description: Transforms a set of container elements into a tab structure.
17307 //>>docs: http://api.jqueryui.com/tabs/
17308 //>>demos: http://jqueryui.com/tabs/
17309 //>>css.structure: ../../themes/base/core.css
17310 //>>css.structure: ../../themes/base/tabs.css
17311 //>>css.theme: ../../themes/base/theme.css
17312 
17313 
17314 
17315 $.widget( "ui.tabs", {
17316         version: "1.12.1",
17317         delay: 300,
17318         options: {
17319                 active: null,
17320                 classes: {
17321                         "ui-tabs": "ui-corner-all",
17322                         "ui-tabs-nav": "ui-corner-all",
17323                         "ui-tabs-panel": "ui-corner-bottom",
17324                         "ui-tabs-tab": "ui-corner-top"
17325                 },
17326                 collapsible: false,
17327                 event: "click",
17328                 heightStyle: "content",
17329                 hide: null,
17330                 show: null,
17331 
17332                 // Callbacks
17333                 activate: null,
17334                 beforeActivate: null,
17335                 beforeLoad: null,
17336                 load: null
17337         },
17338 
17339         _isLocal: ( function() {
17340                 var rhash = /#.*$/;
17341 
17342                 return function( anchor ) {
17343                         var anchorUrl, locationUrl;
17344 
17345                         anchorUrl = anchor.href.replace( rhash, "" );
17346                         locationUrl = location.href.replace( rhash, "" );
17347 
17348                         // Decoding may throw an error if the URL isn't UTF-8 (#9518)
17349                         try {
17350                                 anchorUrl = decodeURIComponent( anchorUrl );
17351                         } catch ( error ) {}
17352                         try {
17353                                 locationUrl = decodeURIComponent( locationUrl );
17354                         } catch ( error ) {}
17355 
17356                         return anchor.hash.length > 1 && anchorUrl === locationUrl;
17357                 };
17358         } )(),
17359 
17360         _create: function() {
17361                 var that = this,
17362                         options = this.options;
17363 
17364                 this.running = false;
17365 
17366                 this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17367                 this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17368 
17369                 this._processTabs();
17370                 options.active = this._initialActive();
17371 
17372                 // Take disabling tabs via class attribute from HTML
17373                 // into account and update option properly.
17374                 if ( $.isArray( options.disabled ) ) {
17375                         options.disabled = $.unique( options.disabled.concat(
17376                                 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17377                                         return that.tabs.index( li );
17378                                 } )
17379                         ) ).sort();
17380                 }
17381 
17382                 // Check for length avoids error when initializing empty list
17383                 if ( this.options.active !== false && this.anchors.length ) {
17384                         this.active = this._findActive( options.active );
17385                 } else {
17386                         this.active = $();
17387                 }
17388 
17389                 this._refresh();
17390 
17391                 if ( this.active.length ) {
17392                         this.load( options.active );
17393                 }
17394         },
17395 
17396         _initialActive: function() {
17397                 var active = this.options.active,
17398                         collapsible = this.options.collapsible,
17399                         locationHash = location.hash.substring( 1 );
17400 
17401                 if ( active === null ) {
17402 
17403                         // check the fragment identifier in the URL
17404                         if ( locationHash ) {
17405                                 this.tabs.each( function( i, tab ) {
17406                                         if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17407                                                 active = i;
17408                                                 return false;
17409                                         }
17410                                 } );
17411                         }
17412 
17413                         // Check for a tab marked active via a class
17414                         if ( active === null ) {
17415                                 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17416                         }
17417 
17418                         // No active tab, set to false
17419                         if ( active === null || active === -1 ) {
17420                                 active = this.tabs.length ? 0 : false;
17421                         }
17422                 }
17423 
17424                 // Handle numbers: negative, out of range
17425                 if ( active !== false ) {
17426                         active = this.tabs.index( this.tabs.eq( active ) );
17427                         if ( active === -1 ) {
17428                                 active = collapsible ? false : 0;
17429                         }
17430                 }
17431 
17432                 // Don't allow collapsible: false and active: false
17433                 if ( !collapsible && active === false && this.anchors.length ) {
17434                         active = 0;
17435                 }
17436 
17437                 return active;
17438         },
17439 
17440         _getCreateEventData: function() {
17441                 return {
17442                         tab: this.active,
17443                         panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17444                 };
17445         },
17446 
17447         _tabKeydown: function( event ) {
17448                 var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17449                         selectedIndex = this.tabs.index( focusedTab ),
17450                         goingForward = true;
17451 
17452                 if ( this._handlePageNav( event ) ) {
17453                         return;
17454                 }
17455 
17456                 switch ( event.keyCode ) {
17457                 case $.ui.keyCode.RIGHT:
17458                 case $.ui.keyCode.DOWN:
17459                         selectedIndex++;
17460                         break;
17461                 case $.ui.keyCode.UP:
17462                 case $.ui.keyCode.LEFT:
17463                         goingForward = false;
17464                         selectedIndex--;
17465                         break;
17466                 case $.ui.keyCode.END:
17467                         selectedIndex = this.anchors.length - 1;
17468                         break;
17469                 case $.ui.keyCode.HOME:
17470                         selectedIndex = 0;
17471                         break;
17472                 case $.ui.keyCode.SPACE:
17473 
17474                         // Activate only, no collapsing
17475                         event.preventDefault();
17476                         clearTimeout( this.activating );
17477                         this._activate( selectedIndex );
17478                         return;
17479                 case $.ui.keyCode.ENTER:
17480 
17481                         // Toggle (cancel delayed activation, allow collapsing)
17482                         event.preventDefault();
17483                         clearTimeout( this.activating );
17484 
17485                         // Determine if we should collapse or activate
17486                         this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17487                         return;
17488                 default:
17489                         return;
17490                 }
17491 
17492                 // Focus the appropriate tab, based on which key was pressed
17493                 event.preventDefault();
17494                 clearTimeout( this.activating );
17495                 selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17496 
17497                 // Navigating with control/command key will prevent automatic activation
17498                 if ( !event.ctrlKey && !event.metaKey ) {
17499 
17500                         // Update aria-selected immediately so that AT think the tab is already selected.
17501                         // Otherwise AT may confuse the user by stating that they need to activate the tab,
17502                         // but the tab will already be activated by the time the announcement finishes.
17503                         focusedTab.attr( "aria-selected", "false" );
17504                         this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17505 
17506                         this.activating = this._delay( function() {
17507                                 this.option( "active", selectedIndex );
17508                         }, this.delay );
17509                 }
17510         },
17511 
17512         _panelKeydown: function( event ) {
17513                 if ( this._handlePageNav( event ) ) {
17514                         return;
17515                 }
17516 
17517                 // Ctrl+up moves focus to the current tab
17518                 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17519                         event.preventDefault();
17520                         this.active.trigger( "focus" );
17521                 }
17522         },
17523 
17524         // Alt+page up/down moves focus to the previous/next tab (and activates)
17525         _handlePageNav: function( event ) {
17526                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17527                         this._activate( this._focusNextTab( this.options.active - 1, false ) );
17528                         return true;
17529                 }
17530                 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17531                         this._activate( this._focusNextTab( this.options.active + 1, true ) );
17532                         return true;
17533                 }
17534         },
17535 
17536         _findNextTab: function( index, goingForward ) {
17537                 var lastTabIndex = this.tabs.length - 1;
17538 
17539                 function constrain() {
17540                         if ( index > lastTabIndex ) {
17541                                 index = 0;
17542                         }
17543                         if ( index < 0 ) {
17544                                 index = lastTabIndex;
17545                         }
17546                         return index;
17547                 }
17548 
17549                 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17550                         index = goingForward ? index + 1 : index - 1;
17551                 }
17552 
17553                 return index;
17554         },
17555 
17556         _focusNextTab: function( index, goingForward ) {
17557                 index = this._findNextTab( index, goingForward );
17558                 this.tabs.eq( index ).trigger( "focus" );
17559                 return index;
17560         },
17561 
17562         _setOption: function( key, value ) {
17563                 if ( key === "active" ) {
17564 
17565                         // _activate() will handle invalid values and update this.options
17566                         this._activate( value );
17567                         return;
17568                 }
17569 
17570                 this._super( key, value );
17571 
17572                 if ( key === "collapsible" ) {
17573                         this._toggleClass( "ui-tabs-collapsible", null, value );
17574 
17575                         // Setting collapsible: false while collapsed; open first panel
17576                         if ( !value && this.options.active === false ) {
17577                                 this._activate( 0 );
17578                         }
17579                 }
17580 
17581                 if ( key === "event" ) {
17582                         this._setupEvents( value );
17583                 }
17584 
17585                 if ( key === "heightStyle" ) {
17586                         this._setupHeightStyle( value );
17587                 }
17588         },
17589 
17590         _sanitizeSelector: function( hash ) {
17591                 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17592         },
17593 
17594         refresh: function() {
17595                 var options = this.options,
17596                         lis = this.tablist.children( ":has(a[href])" );
17597 
17598                 // Get disabled tabs from class attribute from HTML
17599                 // this will get converted to a boolean if needed in _refresh()
17600                 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17601                         return lis.index( tab );
17602                 } );
17603 
17604                 this._processTabs();
17605 
17606                 // Was collapsed or no tabs
17607                 if ( options.active === false || !this.anchors.length ) {
17608                         options.active = false;
17609                         this.active = $();
17610 
17611                 // was active, but active tab is gone
17612                 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17613 
17614                         // all remaining tabs are disabled
17615                         if ( this.tabs.length === options.disabled.length ) {
17616                                 options.active = false;
17617                                 this.active = $();
17618 
17619                         // activate previous tab
17620                         } else {
17621                                 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17622                         }
17623 
17624                 // was active, active tab still exists
17625                 } else {
17626 
17627                         // make sure active index is correct
17628                         options.active = this.tabs.index( this.active );
17629                 }
17630 
17631                 this._refresh();
17632         },
17633 
17634         _refresh: function() {
17635                 this._setOptionDisabled( this.options.disabled );
17636                 this._setupEvents( this.options.event );
17637                 this._setupHeightStyle( this.options.heightStyle );
17638 
17639                 this.tabs.not( this.active ).attr( {
17640                         "aria-selected": "false",
17641                         "aria-expanded": "false",
17642                         tabIndex: -1
17643                 } );
17644                 this.panels.not( this._getPanelForTab( this.active ) )
17645                         .hide()
17646                         .attr( {
17647                                 "aria-hidden": "true"
17648                         } );
17649 
17650                 // Make sure one tab is in the tab order
17651                 if ( !this.active.length ) {
17652                         this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17653                 } else {
17654                         this.active
17655                                 .attr( {
17656                                         "aria-selected": "true",
17657                                         "aria-expanded": "true",
17658                                         tabIndex: 0
17659                                 } );
17660                         this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17661                         this._getPanelForTab( this.active )
17662                                 .show()
17663                                 .attr( {
17664                                         "aria-hidden": "false"
17665                                 } );
17666                 }
17667         },
17668 
17669         _processTabs: function() {
17670                 var that = this,
17671                         prevTabs = this.tabs,
17672                         prevAnchors = this.anchors,
17673                         prevPanels = this.panels;
17674 
17675                 this.tablist = this._getList().attr( "role", "tablist" );
17676                 this._addClass( this.tablist, "ui-tabs-nav",
17677                         "ui-helper-reset ui-helper-clearfix ui-widget-header" );
17678 
17679                 // Prevent users from focusing disabled tabs via click
17680                 this.tablist
17681                         .on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17682                                 if ( $( this ).is( ".ui-state-disabled" ) ) {
17683                                         event.preventDefault();
17684                                 }
17685                         } )
17686 
17687                         // Support: IE <9
17688                         // Preventing the default action in mousedown doesn't prevent IE
17689                         // from focusing the element, so if the anchor gets focused, blur.
17690                         // We don't have to worry about focusing the previously focused
17691                         // element since clicking on a non-focusable element should focus
17692                         // the body anyway.
17693                         .on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17694                                 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17695                                         this.blur();
17696                                 }
17697                         } );
17698 
17699                 this.tabs = this.tablist.find( "> li:has(a[href])" )
17700                         .attr( {
17701                                 role: "tab",
17702                                 tabIndex: -1
17703                         } );
17704                 this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17705 
17706                 this.anchors = this.tabs.map( function() {
17707                         return $( "a", this )[ 0 ];
17708                 } )
17709                         .attr( {
17710                                 role: "presentation",
17711                                 tabIndex: -1
17712                         } );
17713                 this._addClass( this.anchors, "ui-tabs-anchor" );
17714 
17715                 this.panels = $();
17716 
17717                 this.anchors.each( function( i, anchor ) {
17718                         var selector, panel, panelId,
17719                                 anchorId = $( anchor ).uniqueId().attr( "id" ),
17720                                 tab = $( anchor ).closest( "li" ),
17721                                 originalAriaControls = tab.attr( "aria-controls" );
17722 
17723                         // Inline tab
17724                         if ( that._isLocal( anchor ) ) {
17725                                 selector = anchor.hash;
17726                                 panelId = selector.substring( 1 );
17727                                 panel = that.element.find( that._sanitizeSelector( selector ) );
17728 
17729                         // remote tab
17730                         } else {
17731 
17732                                 // If the tab doesn't already have aria-controls,
17733                                 // generate an id by using a throw-away element
17734                                 panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17735                                 selector = "#" + panelId;
17736                                 panel = that.element.find( selector );
17737                                 if ( !panel.length ) {
17738                                         panel = that._createPanel( panelId );
17739                                         panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17740                                 }
17741                                 panel.attr( "aria-live", "polite" );
17742                         }
17743 
17744                         if ( panel.length ) {
17745                                 that.panels = that.panels.add( panel );
17746                         }
17747                         if ( originalAriaControls ) {
17748                                 tab.data( "ui-tabs-aria-controls", originalAriaControls );
17749                         }
17750                         tab.attr( {
17751                                 "aria-controls": panelId,
17752                                 "aria-labelledby": anchorId
17753                         } );
17754                         panel.attr( "aria-labelledby", anchorId );
17755                 } );
17756 
17757                 this.panels.attr( "role", "tabpanel" );
17758                 this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17759 
17760                 // Avoid memory leaks (#10056)
17761                 if ( prevTabs ) {
17762                         this._off( prevTabs.not( this.tabs ) );
17763                         this._off( prevAnchors.not( this.anchors ) );
17764                         this._off( prevPanels.not( this.panels ) );
17765                 }
17766         },
17767 
17768         // Allow overriding how to find the list for rare usage scenarios (#7715)
17769         _getList: function() {
17770                 return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17771         },
17772 
17773         _createPanel: function( id ) {
17774                 return $( "<div>" )
17775                         .attr( "id", id )
17776                         .data( "ui-tabs-destroy", true );
17777         },
17778 
17779         _setOptionDisabled: function( disabled ) {
17780                 var currentItem, li, i;
17781 
17782                 if ( $.isArray( disabled ) ) {
17783                         if ( !disabled.length ) {
17784                                 disabled = false;
17785                         } else if ( disabled.length === this.anchors.length ) {
17786                                 disabled = true;
17787                         }
17788                 }
17789 
17790                 // Disable tabs
17791                 for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17792                         currentItem = $( li );
17793                         if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17794                                 currentItem.attr( "aria-disabled", "true" );
17795                                 this._addClass( currentItem, null, "ui-state-disabled" );
17796                         } else {
17797                                 currentItem.removeAttr( "aria-disabled" );
17798                                 this._removeClass( currentItem, null, "ui-state-disabled" );
17799                         }
17800                 }
17801 
17802                 this.options.disabled = disabled;
17803 
17804                 this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17805                         disabled === true );
17806         },
17807 
17808         _setupEvents: function( event ) {
17809                 var events = {};
17810                 if ( event ) {
17811                         $.each( event.split( " " ), function( index, eventName ) {
17812                                 events[ eventName ] = "_eventHandler";
17813                         } );
17814                 }
17815 
17816                 this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17817 
17818                 // Always prevent the default action, even when disabled
17819                 this._on( true, this.anchors, {
17820                         click: function( event ) {
17821                                 event.preventDefault();
17822                         }
17823                 } );
17824                 this._on( this.anchors, events );
17825                 this._on( this.tabs, { keydown: "_tabKeydown" } );
17826                 this._on( this.panels, { keydown: "_panelKeydown" } );
17827 
17828                 this._focusable( this.tabs );
17829                 this._hoverable( this.tabs );
17830         },
17831 
17832         _setupHeightStyle: function( heightStyle ) {
17833                 var maxHeight,
17834                         parent = this.element.parent();
17835 
17836                 if ( heightStyle === "fill" ) {
17837                         maxHeight = parent.height();
17838                         maxHeight -= this.element.outerHeight() - this.element.height();
17839 
17840                         this.element.siblings( ":visible" ).each( function() {
17841                                 var elem = $( this ),
17842                                         position = elem.css( "position" );
17843 
17844                                 if ( position === "absolute" || position === "fixed" ) {
17845                                         return;
17846                                 }
17847                                 maxHeight -= elem.outerHeight( true );
17848                         } );
17849 
17850                         this.element.children().not( this.panels ).each( function() {
17851                                 maxHeight -= $( this ).outerHeight( true );
17852                         } );
17853 
17854                         this.panels.each( function() {
17855                                 $( this ).height( Math.max( 0, maxHeight -
17856                                         $( this ).innerHeight() + $( this ).height() ) );
17857                         } )
17858                                 .css( "overflow", "auto" );
17859                 } else if ( heightStyle === "auto" ) {
17860                         maxHeight = 0;
17861                         this.panels.each( function() {
17862                                 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17863                         } ).height( maxHeight );
17864                 }
17865         },
17866 
17867         _eventHandler: function( event ) {
17868                 var options = this.options,
17869                         active = this.active,
17870                         anchor = $( event.currentTarget ),
17871                         tab = anchor.closest( "li" ),
17872                         clickedIsActive = tab[ 0 ] === active[ 0 ],
17873                         collapsing = clickedIsActive && options.collapsible,
17874                         toShow = collapsing ? $() : this._getPanelForTab( tab ),
17875                         toHide = !active.length ? $() : this._getPanelForTab( active ),
17876                         eventData = {
17877                                 oldTab: active,
17878                                 oldPanel: toHide,
17879                                 newTab: collapsing ? $() : tab,
17880                                 newPanel: toShow
17881                         };
17882 
17883                 event.preventDefault();
17884 
17885                 if ( tab.hasClass( "ui-state-disabled" ) ||
17886 
17887                                 // tab is already loading
17888                                 tab.hasClass( "ui-tabs-loading" ) ||
17889 
17890                                 // can't switch durning an animation
17891                                 this.running ||
17892 
17893                                 // click on active header, but not collapsible
17894                                 ( clickedIsActive && !options.collapsible ) ||
17895 
17896                                 // allow canceling activation
17897                                 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17898                         return;
17899                 }
17900 
17901                 options.active = collapsing ? false : this.tabs.index( tab );
17902 
17903                 this.active = clickedIsActive ? $() : tab;
17904                 if ( this.xhr ) {
17905                         this.xhr.abort();
17906                 }
17907 
17908                 if ( !toHide.length && !toShow.length ) {
17909                         $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17910                 }
17911 
17912                 if ( toShow.length ) {
17913                         this.load( this.tabs.index( tab ), event );
17914                 }
17915                 this._toggle( event, eventData );
17916         },
17917 
17918         // Handles show/hide for selecting tabs
17919         _toggle: function( event, eventData ) {
17920                 var that = this,
17921                         toShow = eventData.newPanel,
17922                         toHide = eventData.oldPanel;
17923 
17924                 this.running = true;
17925 
17926                 function complete() {
17927                         that.running = false;
17928                         that._trigger( "activate", event, eventData );
17929                 }
17930 
17931                 function show() {
17932                         that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17933 
17934                         if ( toShow.length && that.options.show ) {
17935                                 that._show( toShow, that.options.show, complete );
17936                         } else {
17937                                 toShow.show();
17938                                 complete();
17939                         }
17940                 }
17941 
17942                 // Start out by hiding, then showing, then completing
17943                 if ( toHide.length && this.options.hide ) {
17944                         this._hide( toHide, this.options.hide, function() {
17945                                 that._removeClass( eventData.oldTab.closest( "li" ),
17946                                         "ui-tabs-active", "ui-state-active" );
17947                                 show();
17948                         } );
17949                 } else {
17950                         this._removeClass( eventData.oldTab.closest( "li" ),
17951                                 "ui-tabs-active", "ui-state-active" );
17952                         toHide.hide();
17953                         show();
17954                 }
17955 
17956                 toHide.attr( "aria-hidden", "true" );
17957                 eventData.oldTab.attr( {
17958                         "aria-selected": "false",
17959                         "aria-expanded": "false"
17960                 } );
17961 
17962                 // If we're switching tabs, remove the old tab from the tab order.
17963                 // If we're opening from collapsed state, remove the previous tab from the tab order.
17964                 // If we're collapsing, then keep the collapsing tab in the tab order.
17965                 if ( toShow.length && toHide.length ) {
17966                         eventData.oldTab.attr( "tabIndex", -1 );
17967                 } else if ( toShow.length ) {
17968                         this.tabs.filter( function() {
17969                                 return $( this ).attr( "tabIndex" ) === 0;
17970                         } )
17971                                 .attr( "tabIndex", -1 );
17972                 }
17973 
17974                 toShow.attr( "aria-hidden", "false" );
17975                 eventData.newTab.attr( {
17976                         "aria-selected": "true",
17977                         "aria-expanded": "true",
17978                         tabIndex: 0
17979                 } );
17980         },
17981 
17982         _activate: function( index ) {
17983                 var anchor,
17984                         active = this._findActive( index );
17985 
17986                 // Trying to activate the already active panel
17987                 if ( active[ 0 ] === this.active[ 0 ] ) {
17988                         return;
17989                 }
17990 
17991                 // Trying to collapse, simulate a click on the current active header
17992                 if ( !active.length ) {
17993                         active = this.active;
17994                 }
17995 
17996                 anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17997                 this._eventHandler( {
17998                         target: anchor,
17999                         currentTarget: anchor,
18000                         preventDefault: $.noop
18001                 } );
18002         },
18003 
18004         _findActive: function( index ) {
18005                 return index === false ? $() : this.tabs.eq( index );
18006         },
18007 
18008         _getIndex: function( index ) {
18009 
18010                 // meta-function to give users option to provide a href string instead of a numerical index.
18011                 if ( typeof index === "string" ) {
18012                         index = this.anchors.index( this.anchors.filter( "[href$='" +
18013                                 $.ui.escapeSelector( index ) + "']" ) );
18014                 }
18015 
18016                 return index;
18017         },
18018 
18019         _destroy: function() {
18020                 if ( this.xhr ) {
18021                         this.xhr.abort();
18022                 }
18023 
18024                 this.tablist
18025                         .removeAttr( "role" )
18026                         .off( this.eventNamespace );
18027 
18028                 this.anchors
18029                         .removeAttr( "role tabIndex" )
18030                         .removeUniqueId();
18031 
18032                 this.tabs.add( this.panels ).each( function() {
18033                         if ( $.data( this, "ui-tabs-destroy" ) ) {
18034                                 $( this ).remove();
18035                         } else {
18036                                 $( this ).removeAttr( "role tabIndex " +
18037                                         "aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18038                         }
18039                 } );
18040 
18041                 this.tabs.each( function() {
18042                         var li = $( this ),
18043                                 prev = li.data( "ui-tabs-aria-controls" );
18044                         if ( prev ) {
18045                                 li
18046                                         .attr( "aria-controls", prev )
18047                                         .removeData( "ui-tabs-aria-controls" );
18048                         } else {
18049                                 li.removeAttr( "aria-controls" );
18050                         }
18051                 } );
18052 
18053                 this.panels.show();
18054 
18055                 if ( this.options.heightStyle !== "content" ) {
18056                         this.panels.css( "height", "" );
18057                 }
18058         },
18059 
18060         enable: function( index ) {
18061                 var disabled = this.options.disabled;
18062                 if ( disabled === false ) {
18063                         return;
18064                 }
18065 
18066                 if ( index === undefined ) {
18067                         disabled = false;
18068                 } else {
18069                         index = this._getIndex( index );
18070                         if ( $.isArray( disabled ) ) {
18071                                 disabled = $.map( disabled, function( num ) {
18072                                         return num !== index ? num : null;
18073                                 } );
18074                         } else {
18075                                 disabled = $.map( this.tabs, function( li, num ) {
18076                                         return num !== index ? num : null;
18077                                 } );
18078                         }
18079                 }
18080                 this._setOptionDisabled( disabled );
18081         },
18082 
18083         disable: function( index ) {
18084                 var disabled = this.options.disabled;
18085                 if ( disabled === true ) {
18086                         return;
18087                 }
18088 
18089                 if ( index === undefined ) {
18090                         disabled = true;
18091                 } else {
18092                         index = this._getIndex( index );
18093                         if ( $.inArray( index, disabled ) !== -1 ) {
18094                                 return;
18095                         }
18096                         if ( $.isArray( disabled ) ) {
18097                                 disabled = $.merge( [ index ], disabled ).sort();
18098                         } else {
18099                                 disabled = [ index ];
18100                         }
18101                 }
18102                 this._setOptionDisabled( disabled );
18103         },
18104 
18105         load: function( index, event ) {
18106                 index = this._getIndex( index );
18107                 var that = this,
18108                         tab = this.tabs.eq( index ),
18109                         anchor = tab.find( ".ui-tabs-anchor" ),
18110                         panel = this._getPanelForTab( tab ),
18111                         eventData = {
18112                                 tab: tab,
18113                                 panel: panel
18114                         },
18115                         complete = function( jqXHR, status ) {
18116                                 if ( status === "abort" ) {
18117                                         that.panels.stop( false, true );
18118                                 }
18119 
18120                                 that._removeClass( tab, "ui-tabs-loading" );
18121                                 panel.removeAttr( "aria-busy" );
18122 
18123                                 if ( jqXHR === that.xhr ) {
18124                                         delete that.xhr;
18125                                 }
18126                         };
18127 
18128                 // Not remote
18129                 if ( this._isLocal( anchor[ 0 ] ) ) {
18130                         return;
18131                 }
18132 
18133                 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18134 
18135                 // Support: jQuery <1.8
18136                 // jQuery <1.8 returns false if the request is canceled in beforeSend,
18137                 // but as of 1.8, $.ajax() always returns a jqXHR object.
18138                 if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18139                         this._addClass( tab, "ui-tabs-loading" );
18140                         panel.attr( "aria-busy", "true" );
18141 
18142                         this.xhr
18143                                 .done( function( response, status, jqXHR ) {
18144 
18145                                         // support: jQuery <1.8
18146                                         // http://bugs.jquery.com/ticket/11778
18147                                         setTimeout( function() {
18148                                                 panel.html( response );
18149                                                 that._trigger( "load", event, eventData );
18150 
18151                                                 complete( jqXHR, status );
18152                                         }, 1 );
18153                                 } )
18154                                 .fail( function( jqXHR, status ) {
18155 
18156                                         // support: jQuery <1.8
18157                                         // http://bugs.jquery.com/ticket/11778
18158                                         setTimeout( function() {
18159                                                 complete( jqXHR, status );
18160                                         }, 1 );
18161                                 } );
18162                 }
18163         },
18164 
18165         _ajaxSettings: function( anchor, event, eventData ) {
18166                 var that = this;
18167                 return {
18168 
18169                         // Support: IE <11 only
18170                         // Strip any hash that exists to prevent errors with the Ajax request
18171                         url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18172                         beforeSend: function( jqXHR, settings ) {
18173                                 return that._trigger( "beforeLoad", event,
18174                                         $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18175                         }
18176                 };
18177         },
18178 
18179         _getPanelForTab: function( tab ) {
18180                 var id = $( tab ).attr( "aria-controls" );
18181                 return this.element.find( this._sanitizeSelector( "#" + id ) );
18182         }
18183 } );
18184 
18185 // DEPRECATED
18186 // TODO: Switch return back to widget declaration at top of file when this is removed
18187 if ( $.uiBackCompat !== false ) {
18188 
18189         // Backcompat for ui-tab class (now ui-tabs-tab)
18190         $.widget( "ui.tabs", $.ui.tabs, {
18191                 _processTabs: function() {
18192                         this._superApply( arguments );
18193                         this._addClass( this.tabs, "ui-tab" );
18194                 }
18195         } );
18196 }
18197 
18198 var widgetsTabs = $.ui.tabs;
18199 
18200 
18201 /*!
18202  * jQuery UI Tooltip 1.12.1
18203  * http://jqueryui.com
18204  *
18205  * Copyright jQuery Foundation and other contributors
18206  * Released under the MIT license.
18207  * http://jquery.org/license
18208  */
18209 
18210 //>>label: Tooltip
18211 //>>group: Widgets
18212 //>>description: Shows additional information for any element on hover or focus.
18213 //>>docs: http://api.jqueryui.com/tooltip/
18214 //>>demos: http://jqueryui.com/tooltip/
18215 //>>css.structure: ../../themes/base/core.css
18216 //>>css.structure: ../../themes/base/tooltip.css
18217 //>>css.theme: ../../themes/base/theme.css
18218 
18219 
18220 
18221 $.widget( "ui.tooltip", {
18222         version: "1.12.1",
18223         options: {
18224                 classes: {
18225                         "ui-tooltip": "ui-corner-all ui-widget-shadow"
18226                 },
18227                 content: function() {
18228 
18229                         // support: IE<9, Opera in jQuery <1.7
18230                         // .text() can't accept undefined, so coerce to a string
18231                         var title = $( this ).attr( "title" ) || "";
18232 
18233                         // Escape title, since we're going from an attribute to raw HTML
18234                         return $( "<a>" ).text( title ).html();
18235                 },
18236                 hide: true,
18237 
18238                 // Disabled elements have inconsistent behavior across browsers (#8661)
18239                 items: "[title]:not([disabled])",
18240                 position: {
18241                         my: "left top+15",
18242                         at: "left bottom",
18243                         collision: "flipfit flip"
18244                 },
18245                 show: true,
18246                 track: false,
18247 
18248                 // Callbacks
18249                 close: null,
18250                 open: null
18251         },
18252 
18253         _addDescribedBy: function( elem, id ) {
18254                 var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18255                 describedby.push( id );
18256                 elem
18257                         .data( "ui-tooltip-id", id )
18258                         .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18259         },
18260 
18261         _removeDescribedBy: function( elem ) {
18262                 var id = elem.data( "ui-tooltip-id" ),
18263                         describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18264                         index = $.inArray( id, describedby );
18265 
18266                 if ( index !== -1 ) {
18267                         describedby.splice( index, 1 );
18268                 }
18269 
18270                 elem.removeData( "ui-tooltip-id" );
18271                 describedby = $.trim( describedby.join( " " ) );
18272                 if ( describedby ) {
18273                         elem.attr( "aria-describedby", describedby );
18274                 } else {
18275                         elem.removeAttr( "aria-describedby" );
18276                 }
18277         },
18278 
18279         _create: function() {
18280                 this._on( {
18281                         mouseover: "open",
18282                         focusin: "open"
18283                 } );
18284 
18285                 // IDs of generated tooltips, needed for destroy
18286                 this.tooltips = {};
18287 
18288                 // IDs of parent tooltips where we removed the title attribute
18289                 this.parents = {};
18290 
18291                 // Append the aria-live region so tooltips announce correctly
18292                 this.liveRegion = $( "<div>" )
18293                         .attr( {
18294                                 role: "log",
18295                                 "aria-live": "assertive",
18296                                 "aria-relevant": "additions"
18297                         } )
18298                         .appendTo( this.document[ 0 ].body );
18299                 this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18300 
18301                 this.disabledTitles = $( [] );
18302         },
18303 
18304         _setOption: function( key, value ) {
18305                 var that = this;
18306 
18307                 this._super( key, value );
18308 
18309                 if ( key === "content" ) {
18310                         $.each( this.tooltips, function( id, tooltipData ) {
18311                                 that._updateContent( tooltipData.element );
18312                         } );
18313                 }
18314         },
18315 
18316         _setOptionDisabled: function( value ) {
18317                 this[ value ? "_disable" : "_enable" ]();
18318         },
18319 
18320         _disable: function() {
18321                 var that = this;
18322 
18323                 // Close open tooltips
18324                 $.each( this.tooltips, function( id, tooltipData ) {
18325                         var event = $.Event( "blur" );
18326                         event.target = event.currentTarget = tooltipData.element[ 0 ];
18327                         that.close( event, true );
18328                 } );
18329 
18330                 // Remove title attributes to prevent native tooltips
18331                 this.disabledTitles = this.disabledTitles.add(
18332                         this.element.find( this.options.items ).addBack()
18333                                 .filter( function() {
18334                                         var element = $( this );
18335                                         if ( element.is( "[title]" ) ) {
18336                                                 return element
18337                                                         .data( "ui-tooltip-title", element.attr( "title" ) )
18338                                                         .removeAttr( "title" );
18339                                         }
18340                                 } )
18341                 );
18342         },
18343 
18344         _enable: function() {
18345 
18346                 // restore title attributes
18347                 this.disabledTitles.each( function() {
18348                         var element = $( this );
18349                         if ( element.data( "ui-tooltip-title" ) ) {
18350                                 element.attr( "title", element.data( "ui-tooltip-title" ) );
18351                         }
18352                 } );
18353                 this.disabledTitles = $( [] );
18354         },
18355 
18356         open: function( event ) {
18357                 var that = this,
18358                         target = $( event ? event.target : this.element )
18359 
18360                                 // we need closest here due to mouseover bubbling,
18361                                 // but always pointing at the same event target
18362                                 .closest( this.options.items );
18363 
18364                 // No element to show a tooltip for or the tooltip is already open
18365                 if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18366                         return;
18367                 }
18368 
18369                 if ( target.attr( "title" ) ) {
18370                         target.data( "ui-tooltip-title", target.attr( "title" ) );
18371                 }
18372 
18373                 target.data( "ui-tooltip-open", true );
18374 
18375                 // Kill parent tooltips, custom or native, for hover
18376                 if ( event && event.type === "mouseover" ) {
18377                         target.parents().each( function() {
18378                                 var parent = $( this ),
18379                                         blurEvent;
18380                                 if ( parent.data( "ui-tooltip-open" ) ) {
18381                                         blurEvent = $.Event( "blur" );
18382                                         blurEvent.target = blurEvent.currentTarget = this;
18383                                         that.close( blurEvent, true );
18384                                 }
18385                                 if ( parent.attr( "title" ) ) {
18386                                         parent.uniqueId();
18387                                         that.parents[ this.id ] = {
18388                                                 element: this,
18389                                                 title: parent.attr( "title" )
18390                                         };
18391                                         parent.attr( "title", "" );
18392                                 }
18393                         } );
18394                 }
18395 
18396                 this._registerCloseHandlers( event, target );
18397                 this._updateContent( target, event );
18398         },
18399 
18400         _updateContent: function( target, event ) {
18401                 var content,
18402                         contentOption = this.options.content,
18403                         that = this,
18404                         eventType = event ? event.type : null;
18405 
18406                 if ( typeof contentOption === "string" || contentOption.nodeType ||
18407                                 contentOption.jquery ) {
18408                         return this._open( event, target, contentOption );
18409                 }
18410 
18411                 content = contentOption.call( target[ 0 ], function( response ) {
18412 
18413                         // IE may instantly serve a cached response for ajax requests
18414                         // delay this call to _open so the other call to _open runs first
18415                         that._delay( function() {
18416 
18417                                 // Ignore async response if tooltip was closed already
18418                                 if ( !target.data( "ui-tooltip-open" ) ) {
18419                                         return;
18420                                 }
18421 
18422                                 // JQuery creates a special event for focusin when it doesn't
18423                                 // exist natively. To improve performance, the native event
18424                                 // object is reused and the type is changed. Therefore, we can't
18425                                 // rely on the type being correct after the event finished
18426                                 // bubbling, so we set it back to the previous value. (#8740)
18427                                 if ( event ) {
18428                                         event.type = eventType;
18429                                 }
18430                                 this._open( event, target, response );
18431                         } );
18432                 } );
18433                 if ( content ) {
18434                         this._open( event, target, content );
18435                 }
18436         },
18437 
18438         _open: function( event, target, content ) {
18439                 var tooltipData, tooltip, delayedShow, a11yContent,
18440                         positionOption = $.extend( {}, this.options.position );
18441 
18442                 if ( !content ) {
18443                         return;
18444                 }
18445 
18446                 // Content can be updated multiple times. If the tooltip already
18447                 // exists, then just update the content and bail.
18448                 tooltipData = this._find( target );
18449                 if ( tooltipData ) {
18450                         tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18451                         return;
18452                 }
18453 
18454                 // If we have a title, clear it to prevent the native tooltip
18455                 // we have to check first to avoid defining a title if none exists
18456                 // (we don't want to cause an element to start matching [title])
18457                 //
18458                 // We use removeAttr only for key events, to allow IE to export the correct
18459                 // accessible attributes. For mouse events, set to empty string to avoid
18460                 // native tooltip showing up (happens only when removing inside mouseover).
18461                 if ( target.is( "[title]" ) ) {
18462                         if ( event && event.type === "mouseover" ) {
18463                                 target.attr( "title", "" );
18464                         } else {
18465                                 target.removeAttr( "title" );
18466                         }
18467                 }
18468 
18469                 tooltipData = this._tooltip( target );
18470                 tooltip = tooltipData.tooltip;
18471                 this._addDescribedBy( target, tooltip.attr( "id" ) );
18472                 tooltip.find( ".ui-tooltip-content" ).html( content );
18473 
18474                 // Support: Voiceover on OS X, JAWS on IE <= 9
18475                 // JAWS announces deletions even when aria-relevant="additions"
18476                 // Voiceover will sometimes re-read the entire log region's contents from the beginning
18477                 this.liveRegion.children().hide();
18478                 a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18479                 a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18480                 a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18481                 a11yContent.appendTo( this.liveRegion );
18482 
18483                 function position( event ) {
18484                         positionOption.of = event;
18485                         if ( tooltip.is( ":hidden" ) ) {
18486                                 return;
18487                         }
18488                         tooltip.position( positionOption );
18489                 }
18490                 if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18491                         this._on( this.document, {
18492                                 mousemove: position
18493                         } );
18494 
18495                         // trigger once to override element-relative positioning
18496                         position( event );
18497                 } else {
18498                         tooltip.position( $.extend( {
18499                                 of: target
18500                         }, this.options.position ) );
18501                 }
18502 
18503                 tooltip.hide();
18504 
18505                 this._show( tooltip, this.options.show );
18506 
18507                 // Handle tracking tooltips that are shown with a delay (#8644). As soon
18508                 // as the tooltip is visible, position the tooltip using the most recent
18509                 // event.
18510                 // Adds the check to add the timers only when both delay and track options are set (#14682)
18511                 if ( this.options.track && this.options.show && this.options.show.delay ) {
18512                         delayedShow = this.delayedShow = setInterval( function() {
18513                                 if ( tooltip.is( ":visible" ) ) {
18514                                         position( positionOption.of );
18515                                         clearInterval( delayedShow );
18516                                 }
18517                         }, $.fx.interval );
18518                 }
18519 
18520                 this._trigger( "open", event, { tooltip: tooltip } );
18521         },
18522 
18523         _registerCloseHandlers: function( event, target ) {
18524                 var events = {
18525                         keyup: function( event ) {
18526                                 if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18527                                         var fakeEvent = $.Event( event );
18528                                         fakeEvent.currentTarget = target[ 0 ];
18529                                         this.close( fakeEvent, true );
18530                                 }
18531                         }
18532                 };
18533 
18534                 // Only bind remove handler for delegated targets. Non-delegated
18535                 // tooltips will handle this in destroy.
18536                 if ( target[ 0 ] !== this.element[ 0 ] ) {
18537                         events.remove = function() {
18538                                 this._removeTooltip( this._find( target ).tooltip );
18539                         };
18540                 }
18541 
18542                 if ( !event || event.type === "mouseover" ) {
18543                         events.mouseleave = "close";
18544                 }
18545                 if ( !event || event.type === "focusin" ) {
18546                         events.focusout = "close";
18547                 }
18548                 this._on( true, target, events );
18549         },
18550 
18551         close: function( event ) {
18552                 var tooltip,
18553                         that = this,
18554                         target = $( event ? event.currentTarget : this.element ),
18555                         tooltipData = this._find( target );
18556 
18557                 // The tooltip may already be closed
18558                 if ( !tooltipData ) {
18559 
18560                         // We set ui-tooltip-open immediately upon open (in open()), but only set the
18561                         // additional data once there's actually content to show (in _open()). So even if the
18562                         // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18563                         // the period between open() and _open().
18564                         target.removeData( "ui-tooltip-open" );
18565                         return;
18566                 }
18567 
18568                 tooltip = tooltipData.tooltip;
18569 
18570                 // Disabling closes the tooltip, so we need to track when we're closing
18571                 // to avoid an infinite loop in case the tooltip becomes disabled on close
18572                 if ( tooltipData.closing ) {
18573                         return;
18574                 }
18575 
18576                 // Clear the interval for delayed tracking tooltips
18577                 clearInterval( this.delayedShow );
18578 
18579                 // Only set title if we had one before (see comment in _open())
18580                 // If the title attribute has changed since open(), don't restore
18581                 if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18582                         target.attr( "title", target.data( "ui-tooltip-title" ) );
18583                 }
18584 
18585                 this._removeDescribedBy( target );
18586 
18587                 tooltipData.hiding = true;
18588                 tooltip.stop( true );
18589                 this._hide( tooltip, this.options.hide, function() {
18590                         that._removeTooltip( $( this ) );
18591                 } );
18592 
18593                 target.removeData( "ui-tooltip-open" );
18594                 this._off( target, "mouseleave focusout keyup" );
18595 
18596                 // Remove 'remove' binding only on delegated targets
18597                 if ( target[ 0 ] !== this.element[ 0 ] ) {
18598                         this._off( target, "remove" );
18599                 }
18600                 this._off( this.document, "mousemove" );
18601 
18602                 if ( event && event.type === "mouseleave" ) {
18603                         $.each( this.parents, function( id, parent ) {
18604                                 $( parent.element ).attr( "title", parent.title );
18605                                 delete that.parents[ id ];
18606                         } );
18607                 }
18608 
18609                 tooltipData.closing = true;
18610                 this._trigger( "close", event, { tooltip: tooltip } );
18611                 if ( !tooltipData.hiding ) {
18612                         tooltipData.closing = false;
18613                 }
18614         },
18615 
18616         _tooltip: function( element ) {
18617                 var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18618                         content = $( "<div>" ).appendTo( tooltip ),
18619                         id = tooltip.uniqueId().attr( "id" );
18620 
18621                 this._addClass( content, "ui-tooltip-content" );
18622                 this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18623 
18624                 tooltip.appendTo( this._appendTo( element ) );
18625 
18626                 return this.tooltips[ id ] = {
18627                         element: element,
18628                         tooltip: tooltip
18629                 };
18630         },
18631 
18632         _find: function( target ) {
18633                 var id = target.data( "ui-tooltip-id" );
18634                 return id ? this.tooltips[ id ] : null;
18635         },
18636 
18637         _removeTooltip: function( tooltip ) {
18638                 tooltip.remove();
18639                 delete this.tooltips[ tooltip.attr( "id" ) ];
18640         },
18641 
18642         _appendTo: function( target ) {
18643                 var element = target.closest( ".ui-front, dialog" );
18644 
18645                 if ( !element.length ) {
18646                         element = this.document[ 0 ].body;
18647                 }
18648 
18649                 return element;
18650         },
18651 
18652         _destroy: function() {
18653                 var that = this;
18654 
18655                 // Close open tooltips
18656                 $.each( this.tooltips, function( id, tooltipData ) {
18657 
18658                         // Delegate to close method to handle common cleanup
18659                         var event = $.Event( "blur" ),
18660                                 element = tooltipData.element;
18661                         event.target = event.currentTarget = element[ 0 ];
18662                         that.close( event, true );
18663 
18664                         // Remove immediately; destroying an open tooltip doesn't use the
18665                         // hide animation
18666                         $( "#" + id ).remove();
18667 
18668                         // Restore the title
18669                         if ( element.data( "ui-tooltip-title" ) ) {
18670 
18671                                 // If the title attribute has changed since open(), don't restore
18672                                 if ( !element.attr( "title" ) ) {
18673                                         element.attr( "title", element.data( "ui-tooltip-title" ) );
18674                                 }
18675                                 element.removeData( "ui-tooltip-title" );
18676                         }
18677                 } );
18678                 this.liveRegion.remove();
18679         }
18680 } );
18681 
18682 // DEPRECATED
18683 // TODO: Switch return back to widget declaration at top of file when this is removed
18684 if ( $.uiBackCompat !== false ) {
18685 
18686         // Backcompat for tooltipClass option
18687         $.widget( "ui.tooltip", $.ui.tooltip, {
18688                 options: {
18689                         tooltipClass: null
18690                 },
18691                 _tooltip: function() {
18692                         var tooltipData = this._superApply( arguments );
18693                         if ( this.options.tooltipClass ) {
18694                                 tooltipData.tooltip.addClass( this.options.tooltipClass );
18695                         }
18696                         return tooltipData;
18697                 }
18698         } );
18699 }
18700 
18701 var widgetsTooltip = $.ui.tooltip;
18702 
18703 
18704 
18705 
18706 }));