PageSourceSearch

https://administracionelectronica.gob.es/resources/templating-kit/…jquery-ui-1_11_1_custom/jquery-ui_1_11_4.js

js administracionelectronica.gob.es collected 2026-10-01 08:51:28 UTC 525,352 bytes, 16,617 lines download raw bytes

vendor: 13,938 bytes, lines 1-447
1/*! jQuery UI - v1.11.4 - 2015-03-11
2* http://jqueryui.com
3* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
4* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7  if ( typeof define === "function" && define.amd ) {
8
9    // AMD. Register as an anonymous module.
10    define([ "jquery" ], factory );
11  } else {
12
13    // Browser globals
14    factory( jQuery );
15  }
16}(function( $ ) {
17/*!
18 * jQuery UI Core 1.11.4
19 * http://jqueryui.com
20 *
21 * Copyright jQuery Foundation and other contributors
22 * Released under the MIT license.
23 * http://jquery.org/license
24 *
25 * http://api.jqueryui.com/category/ui-core/
26 */
27
28
29// $.ui might exist from components with no dependencies, e.g., $.ui.position
30$.ui = $.ui || {};
31
32$.extend( $.ui, {
33  version: "1.11.4",
34
35  keyCode: {
36    BACKSPACE: 8,
37    COMMA: 188,
38    DELETE: 46,
39    DOWN: 40,
40    END: 35,
41    ENTER: 13,
42    ESCAPE: 27,
43    HOME: 36,
44    LEFT: 37,
45    PAGE_DOWN: 34,
46    PAGE_UP: 33,
47    PERIOD: 190,
48    RIGHT: 39,
49    SPACE: 32,
50    TAB: 9,
51    UP: 38
52  }
53});
54
55// plugins
56$.fn.extend({
57  scrollParent: function( includeHidden ) {
58    var position = this.css( "position" ),
59      excludeStaticParent = position === "absolute",
60      overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
61      scrollParent = this.parents().filter( function() {
62        var parent = $( this );
63        if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
64          return false;
65        }
66        return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
67      }).eq( 0 );
68
69    return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
70  },
71
72  uniqueId: (function() {
73    var uuid = 0;
74
75    return function() {
76      return this.each(function() {
77        if ( !this.id ) {
78          this.id = "ui-id-" + ( ++uuid );
79        }
80      });
81    };
82  })(),
83
84  removeUniqueId: function() {
85    return this.each(function() {
86      if ( /^ui-id-\d+$/.test( this.id ) ) {
87        $( this ).removeAttr( "id" );
88      }
89    });
90  }
91});
92
93// selectors
94function focusable( element, isTabIndexNotNaN ) {
95  var map, mapName, img,
96    nodeName = element.nodeName.toLowerCase();
97  if ( "area" === nodeName ) {
98    map = element.parentNode;
99    mapName = map.name;
100    if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
101      return false;
102    }
103    img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
104    return !!img && visible( img );
105  }
106  return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
107    !element.disabled :
108    "a" === nodeName ?
109      element.href || isTabIndexNotNaN :
110      isTabIndexNotNaN) &&
111    // the element and all of its ancestors must be visible
112    visible( element );
113}
114
115function visible( element ) {
116  return $.expr.filters.visible( element ) &&
117    !$( element ).parents().addBack().filter(function() {
118      return $.css( this, "visibility" ) === "hidden";
119    }).length;
120}
121
122$.extend( $.expr[ ":" ], {
123  data: $.expr.createPseudo ?
124    $.expr.createPseudo(function( dataName ) {
125      return function( elem ) {
126        return !!$.data( elem, dataName );
127      };
128    }) :
129    // support: jQuery <1.8
130    function( elem, i, match ) {
131      return !!$.data( elem, match[ 3 ] );
132    },
133
134  focusable: function( element ) {
135    return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
136  },
137
138  tabbable: function( element ) {
139    var tabIndex = $.attr( element, "tabindex" ),
140      isTabIndexNaN = isNaN( tabIndex );
141    return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
142  }
143});
144
145// support: jQuery <1.8
146if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
147  $.each( [ "Width", "Height" ], function( i, name ) {
148    var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
149      type = name.toLowerCase(),
150      orig = {
151        innerWidth: $.fn.innerWidth,
152        innerHeight: $.fn.innerHeight,
153        outerWidth: $.fn.outerWidth,
154        outerHeight: $.fn.outerHeight
155      };
156
157    function reduce( elem, size, border, margin ) {
158      $.each( side, function() {
159        size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
160        if ( border ) {
161          size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
162        }
163        if ( margin ) {
164          size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
165        }
166      });
167      return size;
168    }
169
170    $.fn[ "inner" + name ] = function( size ) {
171      if ( size === undefined ) {
172        return orig[ "inner" + name ].call( this );
173      }
174
175      return this.each(function() {
176        $( this ).css( type, reduce( this, size ) + "px" );
177      });
178    };
179
180    $.fn[ "outer" + name] = function( size, margin ) {
181      if ( typeof size !== "number" ) {
182        return orig[ "outer" + name ].call( this, size );
183      }
184
185      return this.each(function() {
186        $( this).css( type, reduce( this, size, true, margin ) + "px" );
187      });
188    };
189  });
190}
191
192// support: jQuery <1.8
193if ( !$.fn.addBack ) {
194  $.fn.addBack = function( selector ) {
195    return this.add( selector == null ?
196      this.prevObject : this.prevObject.filter( selector )
197    );
198  };
199}
200
201// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
202if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
203  $.fn.removeData = (function( removeData ) {
204    return function( key ) {
205      if ( arguments.length ) {
206        return removeData.call( this, $.camelCase( key ) );
207      } else {
208        return removeData.call( this );
209      }
210    };
211  })( $.fn.removeData );
212}
213
214// deprecated
215$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
216
217$.fn.extend({
218  focus: (function( orig ) {
219    return function( delay, fn ) {
220      return typeof delay === "number" ?
221        this.each(function() {
222          var elem = this;
223          setTimeout(function() {
224            $( elem ).focus();
225            if ( fn ) {
226              fn.call( elem );
227            }
228          }, delay );
229        }) :
230        orig.apply( this, arguments );
231    };
232  })( $.fn.focus ),
233
234  disableSelection: (function() {
235    var eventType = "onselectstart" in document.createElement( "div" ) ?
236      "selectstart" :
237      "mousedown";
238
239    return function() {
240      return this.bind( eventType + ".ui-disableSelection", function( event ) {
241        event.preventDefault();
242      });
243    };
244  })(),
245
246  enableSelection: function() {
247    return this.unbind( ".ui-disableSelection" );
248  },
249
250  zIndex: function( zIndex ) {
251    if ( zIndex !== undefined ) {
252      return this.css( "zIndex", zIndex );
253    }
254
255    if ( this.length ) {
256      var elem = $( this[ 0 ] ), position, value;
257      while ( elem.length && elem[ 0 ] !== document ) {
258        // Ignore z-index if position is set to a value where z-index is ignored by the browser
259        // This makes behavior of this function consistent across browsers
260        // WebKit always returns auto if the element is positioned
261        position = elem.css( "position" );
262        if ( position === "absolute" || position === "relative" || position === "fixed" ) {
263          // IE returns 0 when zIndex is not specified
264          // other browsers return a string
265          // we ignore the case of nested elements with an explicit value of 0
266          // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
267          value = parseInt( elem.css( "zIndex" ), 10 );
268          if ( !isNaN( value ) && value !== 0 ) {
269            return value;
270          }
271        }
272        elem = elem.parent();
273      }
274    }
275
276    return 0;
277  }
278});
279
280// $.ui.plugin is deprecated. Use $.widget() extensions instead.
281$.ui.plugin = {
282  add: function( module, option, set ) {
283    var i,
284      proto = $.ui[ module ].prototype;
285    for ( i in set ) {
286      proto.plugins[ i ] = proto.plugins[ i ] || [];
287      proto.plugins[ i ].push( [ option, set[ i ] ] );
288    }
289  },
290  call: function( instance, name, args, allowDisconnected ) {
291    var i,
292      set = instance.plugins[ name ];
293
294    if ( !set ) {
295      return;
296    }
297
298    if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
299      return;
300    }
301
302    for ( i = 0; i < set.length; i++ ) {
303      if ( instance.options[ set[ i ][ 0 ] ] ) {
304        set[ i ][ 1 ].apply( instance.element, args );
305      }
306    }
307  }
308};
309
310
311/*!
312 * jQuery UI Widget 1.11.4
313 * http://jqueryui.com
314 *
315 * Copyright jQuery Foundation and other contributors
316 * Released under the MIT license.
317 * http://jquery.org/license
318 *
319 * http://api.jqueryui.com/jQuery.widget/
320 */
321
322
323var widget_uuid = 0,
324  widget_slice = Array.prototype.slice;
325
326$.cleanData = (function( orig ) {
327  return function( elems ) {
328    var events, elem, i;
329    for ( i = 0; (elem = elems[i]) != null; i++ ) {
330      try {
331
332        // Only trigger remove when necessary to save time
333        events = $._data( elem, "events" );
334        if ( events && events.remove ) {
335          $( elem ).triggerHandler( "remove" );
336        }
337
338      // http://bugs.jquery.com/ticket/8235
339      } catch ( e ) {}
340    }
341    orig( elems );
342  };
343})( $.cleanData );
344
345$.widget = function( name, base, prototype ) {
346  var fullName, existingConstructor, constructor, basePrototype,
347    // proxiedPrototype allows the provided prototype to remain unmodified
348    // so that it can be used as a mixin for multiple widgets (#8876)
349    proxiedPrototype = {},
350    namespace = name.split( "." )[ 0 ];
351
352  name = name.split( "." )[ 1 ];
353  fullName = namespace + "-" + name;
354
355  if ( !prototype ) {
356    prototype = base;
357    base = $.Widget;
358  }
359
360  // create selector for plugin
361  $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
362    return !!$.data( elem, fullName );
363  };
364
365  $[ namespace ] = $[ namespace ] || {};
366  existingConstructor = $[ namespace ][ name ];
367  constructor = $[ namespace ][ name ] = function( options, element ) {
368    // allow instantiation without "new" keyword
369    if ( !this._createWidget ) {
370      return new constructor( options, element );
371    }
372
373    // allow instantiation without initializing for simple inheritance
374    // must use "new" keyword (the code above always passes args)
375    if ( arguments.length ) {
376      this._createWidget( options, element );
377    }
378  };
379  // extend with the existing constructor to carry over any static properties
380  $.extend( constructor, existingConstructor, {
381    version: prototype.version,
382    // copy the object used to create the prototype in case we need to
383    // redefine the widget later
384    _proto: $.extend( {}, prototype ),
385    // track widgets that inherit from this widget in case this widget is
386    // redefined after a widget inherits from it
387    _childConstructors: []
388  });
389
390  basePrototype = new base();
391  // we need to make the options hash a property directly on the new instance
392  // otherwise we'll modify the options hash on the prototype that we're
393  // inheriting from
394  basePrototype.options = $.widget.extend( {}, basePrototype.options );
395  $.each( prototype, function( prop, value ) {
396    if ( !$.isFunction( value ) ) {
397      proxiedPrototype[ prop ] = value;
398      return;
399    }
400    proxiedPrototype[ prop ] = (function() {
401      var _super = function() {
402          return base.prototype[ prop ].apply( this, arguments );
403        },
404        _superApply = function( args ) {
405          return base.prototype[ prop ].apply( this, args );
406        };
407      return function() {
408        var __super = this._super,
409          __superApply = this._superApply,
410          returnValue;
411
412        this._super = _super;
413        this._superApply = _superApply;
414
415        returnValue = value.apply( this, arguments );
416
417        this._super = __super;
418        this._superApply = __superApply;
419
420        return returnValue;
421      };
422    })();
423  });
424  constructor.prototype = $.widget.extend( basePrototype, {
425    // TODO: remove support for widgetEventPrefix
426    // always use the name + a colon as the prefix, e.g., draggable:start
427    // don't prefix for widgets that aren't DOM-based
428    widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
429  }, proxiedPrototype, {
430    constructor: constructor,
431    namespace: namespace,
432    widgetName: name,
433    widgetFullName: fullName
434  });
435
436  // If this widget is being redefined then we need to find all widgets that
437  // are inheriting from it and redefine all of them so that they inherit from
438  // the new version of this widget. We're essentially trying to replace one
439  // level in the prototype chain.
440  if ( existingConstructor ) {
441    $.each( existingConstructor._childConstructors, function( i, child ) {
442      var childPrototype = child.prototype;
443
444      // redefine the child widget using the same prototype that was
445      // originally used, but inherit from the new version of the base
446      $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
447    });
vendor: 18,331 bytes, lines 448-1047
448    // remove the list of existing child constructors from the old constructor
449    // so the old child constructors can be garbage collected
450    delete existingConstructor._childConstructors;
451  } else {
452    base._childConstructors.push( constructor );
453  }
454
455  $.widget.bridge( name, constructor );
456
457  return constructor;
458};
459
460$.widget.extend = function( target ) {
461  var input = widget_slice.call( arguments, 1 ),
462    inputIndex = 0,
463    inputLength = input.length,
464    key,
465    value;
466  for ( ; inputIndex < inputLength; inputIndex++ ) {
467    for ( key in input[ inputIndex ] ) {
468      value = input[ inputIndex ][ key ];
469      if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
470        // Clone objects
471        if ( $.isPlainObject( value ) ) {
472          target[ key ] = $.isPlainObject( target[ key ] ) ?
473            $.widget.extend( {}, target[ key ], value ) :
474            // Don't extend strings, arrays, etc. with objects
475            $.widget.extend( {}, value );
476        // Copy everything else by reference
477        } else {
478          target[ key ] = value;
479        }
480      }
481    }
482  }
483  return target;
484};
485
486$.widget.bridge = function( name, object ) {
487  var fullName = object.prototype.widgetFullName || name;
488  $.fn[ name ] = function( options ) {
489    var isMethodCall = typeof options === "string",
490      args = widget_slice.call( arguments, 1 ),
491      returnValue = this;
492
493    if ( isMethodCall ) {
494      this.each(function() {
495        var methodValue,
496          instance = $.data( this, fullName );
497        if ( options === "instance" ) {
498          returnValue = instance;
499          return false;
500        }
501        if ( !instance ) {
502          return $.error( "cannot call methods on " + name + " prior to initialization; " +
503            "attempted to call method '" + options + "'" );
504        }
505        if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
506          return $.error( "no such method '" + options + "' for " + name + " widget instance" );
507        }
508        methodValue = instance[ options ].apply( instance, args );
509        if ( methodValue !== instance && methodValue !== undefined ) {
510          returnValue = methodValue && methodValue.jquery ?
511            returnValue.pushStack( methodValue.get() ) :
512            methodValue;
513          return false;
514        }
515      });
516    } else {
517
518      // Allow multiple hashes to be passed on init
519      if ( args.length ) {
520        options = $.widget.extend.apply( null, [ options ].concat(args) );
521      }
522
523      this.each(function() {
524        var instance = $.data( this, fullName );
525        if ( instance ) {
526          instance.option( options || {} );
527          if ( instance._init ) {
528            instance._init();
529          }
530        } else {
531          $.data( this, fullName, new object( options, this ) );
532        }
533      });
534    }
535
536    return returnValue;
537  };
538};
539
540$.Widget = function( /* options, element */ ) {};
541$.Widget._childConstructors = [];
542
543$.Widget.prototype = {
544  widgetName: "widget",
545  widgetEventPrefix: "",
546  defaultElement: "<div>",
547  options: {
548    disabled: false,
549
550    // callbacks
551    create: null
552  },
553  _createWidget: function( options, element ) {
554    element = $( element || this.defaultElement || this )[ 0 ];
555    this.element = $( element );
556    this.uuid = widget_uuid++;
557    this.eventNamespace = "." + this.widgetName + this.uuid;
558
559    this.bindings = $();
560    this.hoverable = $();
561    this.focusable = $();
562
563    if ( element !== this ) {
564      $.data( element, this.widgetFullName, this );
565      this._on( true, this.element, {
566        remove: function( event ) {
567          if ( event.target === element ) {
568            this.destroy();
569          }
570        }
571      });
572      this.document = $( element.style ?
573        // element within the document
574        element.ownerDocument :
575        // element is window or document
576        element.document || element );
577      this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
578    }
579
580    this.options = $.widget.extend( {},
581      this.options,
582      this._getCreateOptions(),
583      options );
584
585    this._create();
586    this._trigger( "create", null, this._getCreateEventData() );
587    this._init();
588  },
589  _getCreateOptions: $.noop,
590  _getCreateEventData: $.noop,
591  _create: $.noop,
592  _init: $.noop,
593
594  destroy: function() {
595    this._destroy();
596    // we can probably remove the unbind calls in 2.0
597    // all event bindings should go through this._on()
598    this.element
599      .unbind( this.eventNamespace )
600      .removeData( this.widgetFullName )
601      // support: jquery <1.6.3
602      // http://bugs.jquery.com/ticket/9413
603      .removeData( $.camelCase( this.widgetFullName ) );
604    this.widget()
605      .unbind( this.eventNamespace )
606      .removeAttr( "aria-disabled" )
607      .removeClass(
608        this.widgetFullName + "-disabled " +
609        "ui-state-disabled" );
610
611    // clean up events and states
612    this.bindings.unbind( this.eventNamespace );
613    this.hoverable.removeClass( "ui-state-hover" );
614    this.focusable.removeClass( "ui-state-focus" );
615  },
616  _destroy: $.noop,
617
618  widget: function() {
619    return this.element;
620  },
621
622  option: function( key, value ) {
623    var options = key,
624      parts,
625      curOption,
626      i;
627
628    if ( arguments.length === 0 ) {
629      // don't return a reference to the internal hash
630      return $.widget.extend( {}, this.options );
631    }
632
633    if ( typeof key === "string" ) {
634      // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
635      options = {};
636      parts = key.split( "." );
637      key = parts.shift();
638      if ( parts.length ) {
639        curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
640        for ( i = 0; i < parts.length - 1; i++ ) {
641          curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
642          curOption = curOption[ parts[ i ] ];
643        }
644        key = parts.pop();
645        if ( arguments.length === 1 ) {
646          return curOption[ key ] === undefined ? null : curOption[ key ];
647        }
648        curOption[ key ] = value;
649      } else {
650        if ( arguments.length === 1 ) {
651          return this.options[ key ] === undefined ? null : this.options[ key ];
652        }
653        options[ key ] = value;
654      }
655    }
656
657    this._setOptions( options );
658
659    return this;
660  },
661  _setOptions: function( options ) {
662    var key;
663
664    for ( key in options ) {
665      this._setOption( key, options[ key ] );
666    }
667
668    return this;
669  },
670  _setOption: function( key, value ) {
671    this.options[ key ] = value;
672
673    if ( key === "disabled" ) {
674      this.widget()
675        .toggleClass( this.widgetFullName + "-disabled", !!value );
676
677      // If the widget is becoming disabled, then nothing is interactive
678      if ( value ) {
679        this.hoverable.removeClass( "ui-state-hover" );
680        this.focusable.removeClass( "ui-state-focus" );
681      }
682    }
683
684    return this;
685  },
686
687  enable: function() {
688    return this._setOptions({ disabled: false });
689  },
690  disable: function() {
691    return this._setOptions({ disabled: true });
692  },
693
694  _on: function( suppressDisabledCheck, element, handlers ) {
695    var delegateElement,
696      instance = this;
697
698    // no suppressDisabledCheck flag, shuffle arguments
699    if ( typeof suppressDisabledCheck !== "boolean" ) {
700      handlers = element;
701      element = suppressDisabledCheck;
702      suppressDisabledCheck = false;
703    }
704
705    // no element argument, shuffle and use this.element
706    if ( !handlers ) {
707      handlers = element;
708      element = this.element;
709      delegateElement = this.widget();
710    } else {
711      element = delegateElement = $( element );
712      this.bindings = this.bindings.add( element );
713    }
714
715    $.each( handlers, function( event, handler ) {
716      function handlerProxy() {
717        // allow widgets to customize the disabled handling
718        // - disabled as an array instead of boolean
719        // - disabled class as method for disabling individual parts
720        if ( !suppressDisabledCheck &&
721            ( instance.options.disabled === true ||
722              $( this ).hasClass( "ui-state-disabled" ) ) ) {
723          return;
724        }
725        return ( typeof handler === "string" ? instance[ handler ] : handler )
726          .apply( instance, arguments );
727      }
728
729      // copy the guid so direct unbinding works
730      if ( typeof handler !== "string" ) {
731        handlerProxy.guid = handler.guid =
732          handler.guid || handlerProxy.guid || $.guid++;
733      }
734
735      var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
736        eventName = match[1] + instance.eventNamespace,
737        selector = match[2];
738      if ( selector ) {
739        delegateElement.delegate( selector, eventName, handlerProxy );
740      } else {
741        element.bind( eventName, handlerProxy );
742      }
743    });
744  },
745
746  _off: function( element, eventName ) {
747    eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
748      this.eventNamespace;
749    element.unbind( eventName ).undelegate( eventName );
750
751    // Clear the stack to avoid memory leaks (#10056)
752    this.bindings = $( this.bindings.not( element ).get() );
753    this.focusable = $( this.focusable.not( element ).get() );
754    this.hoverable = $( this.hoverable.not( element ).get() );
755  },
756
757  _delay: function( handler, delay ) {
758    function handlerProxy() {
759      return ( typeof handler === "string" ? instance[ handler ] : handler )
760        .apply( instance, arguments );
761    }
762    var instance = this;
763    return setTimeout( handlerProxy, delay || 0 );
764  },
765
766  _hoverable: function( element ) {
767    this.hoverable = this.hoverable.add( element );
768    this._on( element, {
769      mouseenter: function( event ) {
770        $( event.currentTarget ).addClass( "ui-state-hover" );
771      },
772      mouseleave: function( event ) {
773        $( event.currentTarget ).removeClass( "ui-state-hover" );
774      }
775    });
776  },
777
778  _focusable: function( element ) {
779    this.focusable = this.focusable.add( element );
780    this._on( element, {
781      focusin: function( event ) {
782        $( event.currentTarget ).addClass( "ui-state-focus" );
783      },
784      focusout: function( event ) {
785        $( event.currentTarget ).removeClass( "ui-state-focus" );
786      }
787    });
788  },
789
790  _trigger: function( type, event, data ) {
791    var prop, orig,
792      callback = this.options[ type ];
793
794    data = data || {};
795    event = $.Event( event );
796    event.type = ( type === this.widgetEventPrefix ?
797      type :
798      this.widgetEventPrefix + type ).toLowerCase();
799    // the original event may come from any element
800    // so we need to reset the target on the new event
801    event.target = this.element[ 0 ];
802
803    // copy original event properties over to the new event
804    orig = event.originalEvent;
805    if ( orig ) {
806      for ( prop in orig ) {
807        if ( !( prop in event ) ) {
808          event[ prop ] = orig[ prop ];
809        }
810      }
811    }
812
813    this.element.trigger( event, data );
814    return !( $.isFunction( callback ) &&
815      callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
816      event.isDefaultPrevented() );
817  }
818};
819
820$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
821  $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
822    if ( typeof options === "string" ) {
823      options = { effect: options };
824    }
825    var hasOptions,
826      effectName = !options ?
827        method :
828        options === true || typeof options === "number" ?
829          defaultEffect :
830          options.effect || defaultEffect;
831    options = options || {};
832    if ( typeof options === "number" ) {
833      options = { duration: options };
834    }
835    hasOptions = !$.isEmptyObject( options );
836    options.complete = callback;
837    if ( options.delay ) {
838      element.delay( options.delay );
839    }
840    if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
841      element[ method ]( options );
842    } else if ( effectName !== method && element[ effectName ] ) {
843      element[ effectName ]( options.duration, options.easing, callback );
844    } else {
845      element.queue(function( next ) {
846        $( this )[ method ]();
847        if ( callback ) {
848          callback.call( element[ 0 ] );
849        }
850        next();
851      });
852    }
853  };
854});
855
856var widget = $.widget;
857
858
859/*!
860 * jQuery UI Mouse 1.11.4
861 * http://jqueryui.com
862 *
863 * Copyright jQuery Foundation and other contributors
864 * Released under the MIT license.
865 * http://jquery.org/license
866 *
867 * http://api.jqueryui.com/mouse/
868 */
869
870
871var mouseHandled = false;
872$( document ).mouseup( function() {
873  mouseHandled = false;
874});
875
876var mouse = $.widget("ui.mouse", {
877  version: "1.11.4",
878  options: {
879    cancel: "input,textarea,button,select,option",
880    distance: 1,
881    delay: 0
882  },
883  _mouseInit: function() {
884    var that = this;
885
886    this.element
887      .bind("mousedown." + this.widgetName, function(event) {
888        return that._mouseDown(event);
889      })
890      .bind("click." + this.widgetName, function(event) {
891        if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
892          $.removeData(event.target, that.widgetName + ".preventClickEvent");
893          event.stopImmediatePropagation();
894          return false;
895        }
896      });
897
898    this.started = false;
899  },
900
901  // TODO: make sure destroying one instance of mouse doesn't mess with
902  // other instances of mouse
903  _mouseDestroy: function() {
904    this.element.unbind("." + this.widgetName);
905    if ( this._mouseMoveDelegate ) {
906      this.document
907        .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
908        .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
909    }
910  },
911
912  _mouseDown: function(event) {
913    // don't let more than one widget handle mouseStart
914    if ( mouseHandled ) {
915      return;
916    }
917
918    this._mouseMoved = false;
919
920    // we may have missed mouseup (out of window)
921    (this._mouseStarted && this._mouseUp(event));
922
923    this._mouseDownEvent = event;
924
925    var that = this,
926      btnIsLeft = (event.which === 1),
927      // event.target.nodeName works around a bug in IE 8 with
928      // disabled inputs (#7620)
929      elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
930    if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
931      return true;
932    }
933
934    this.mouseDelayMet = !this.options.delay;
935    if (!this.mouseDelayMet) {
936      this._mouseDelayTimer = setTimeout(function() {
937        that.mouseDelayMet = true;
938      }, this.options.delay);
939    }
940
941    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
942      this._mouseStarted = (this._mouseStart(event) !== false);
943      if (!this._mouseStarted) {
944        event.preventDefault();
945        return true;
946      }
947    }
948
949    // Click event may never have fired (Gecko & Opera)
950    if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
951      $.removeData(event.target, this.widgetName + ".preventClickEvent");
952    }
953
954    // these delegates are required to keep context
955    this._mouseMoveDelegate = function(event) {
956      return that._mouseMove(event);
957    };
958    this._mouseUpDelegate = function(event) {
959      return that._mouseUp(event);
960    };
961
962    this.document
963      .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
964      .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
965
966    event.preventDefault();
967
968    mouseHandled = true;
969    return true;
970  },
971
972  _mouseMove: function(event) {
973    // Only check for mouseups outside the document if you've moved inside the document
974    // at least once. This prevents the firing of mouseup in the case of IE<9, which will
975    // fire a mousemove event if content is placed under the cursor. See #7778
976    // Support: IE <9
977    if ( this._mouseMoved ) {
978      // IE mouseup check - mouseup happened when mouse was out of window
979      if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
980        return this._mouseUp(event);
981
982      // Iframe mouseup check - mouseup occurred in another document
983      } else if ( !event.which ) {
984        return this._mouseUp( event );
985      }
986    }
987
988    if ( event.which || event.button ) {
989      this._mouseMoved = true;
990    }
991
992    if (this._mouseStarted) {
993      this._mouseDrag(event);
994      return event.preventDefault();
995    }
996
997    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
998      this._mouseStarted =
999        (this._mouseStart(this._mouseDownEvent, event) !== false);
1000      (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
1001    }
1002
1003    return !this._mouseStarted;
1004  },
1005
1006  _mouseUp: function(event) {
1007    this.document
1008      .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1009      .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
1010
1011    if (this._mouseStarted) {
1012      this._mouseStarted = false;
1013
1014      if (event.target === this._mouseDownEvent.target) {
1015        $.data(event.target, this.widgetName + ".preventClickEvent", true);
1016      }
1017
1018      this._mouseStop(event);
1019    }
1020
1021    mouseHandled = false;
1022    return false;
1023  },
1024
1025  _mouseDistanceMet: function(event) {
1026    return (Math.max(
1027        Math.abs(this._mouseDownEvent.pageX - event.pageX),
1028        Math.abs(this._mouseDownEvent.pageY - event.pageY)
1029      ) >= this.options.distance
1030    );
1031  },
1032
1033  _mouseDelayMet: function(/* event */) {
1034    return this.mouseDelayMet;
1035  },
1036
1037  // These are placeholder methods, to be overriden by extending plugin
1038  _mouseStart: function(/* event */) {},
1039  _mouseDrag: function(/* event */) {},
1040  _mouseStop: function(/* event */) {},
1041  _mouseCapture: function(/* event */) { return true; }
1042});
1043
1044
1045/*!
1046 * jQuery UI Position 1.11.4
1047 * http://jqueryui.com
vendor: 22,184 bytes, lines 1048-1720
1048 *
1049 * Copyright jQuery Foundation and other contributors
1050 * Released under the MIT license.
1051 * http://jquery.org/license
1052 *
1053 * http://api.jqueryui.com/position/
1054 */
1055
1056(function() {
1057
1058$.ui = $.ui || {};
1059
1060var cachedScrollbarWidth, supportsOffsetFractions,
1061  max = Math.max,
1062  abs = Math.abs,
1063  round = Math.round,
1064  rhorizontal = /left|center|right/,
1065  rvertical = /top|center|bottom/,
1066  roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1067  rposition = /^\w+/,
1068  rpercent = /%$/,
1069  _position = $.fn.position;
1070
1071function getOffsets( offsets, width, height ) {
1072  return [
1073    parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1074    parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1075  ];
1076}
1077
1078function parseCss( element, property ) {
1079  return parseInt( $.css( element, property ), 10 ) || 0;
1080}
1081
1082function getDimensions( elem ) {
1083  var raw = elem[0];
1084  if ( raw.nodeType === 9 ) {
1085    return {
1086      width: elem.width(),
1087      height: elem.height(),
1088      offset: { top: 0, left: 0 }
1089    };
1090  }
1091  if ( $.isWindow( raw ) ) {
1092    return {
1093      width: elem.width(),
1094      height: elem.height(),
1095      offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1096    };
1097  }
1098  if ( raw.preventDefault ) {
1099    return {
1100      width: 0,
1101      height: 0,
1102      offset: { top: raw.pageY, left: raw.pageX }
1103    };
1104  }
1105  return {
1106    width: elem.outerWidth(),
1107    height: elem.outerHeight(),
1108    offset: elem.offset()
1109  };
1110}
1111
1112$.position = {
1113  scrollbarWidth: function() {
1114    if ( cachedScrollbarWidth !== undefined ) {
1115      return cachedScrollbarWidth;
1116    }
1117    var w1, w2,
1118      div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1119      innerDiv = div.children()[0];
1120
1121    $( "body" ).append( div );
1122    w1 = innerDiv.offsetWidth;
1123    div.css( "overflow", "scroll" );
1124
1125    w2 = innerDiv.offsetWidth;
1126
1127    if ( w1 === w2 ) {
1128      w2 = div[0].clientWidth;
1129    }
1130
1131    div.remove();
1132
1133    return (cachedScrollbarWidth = w1 - w2);
1134  },
1135  getScrollInfo: function( within ) {
1136    var overflowX = within.isWindow || within.isDocument ? "" :
1137        within.element.css( "overflow-x" ),
1138      overflowY = within.isWindow || within.isDocument ? "" :
1139        within.element.css( "overflow-y" ),
1140      hasOverflowX = overflowX === "scroll" ||
1141        ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1142      hasOverflowY = overflowY === "scroll" ||
1143        ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1144    return {
1145      width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1146      height: hasOverflowX ? $.position.scrollbarWidth() : 0
1147    };
1148  },
1149  getWithinInfo: function( element ) {
1150    var withinElement = $( element || window ),
1151      isWindow = $.isWindow( withinElement[0] ),
1152      isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1153    return {
1154      element: withinElement,
1155      isWindow: isWindow,
1156      isDocument: isDocument,
1157      offset: withinElement.offset() || { left: 0, top: 0 },
1158      scrollLeft: withinElement.scrollLeft(),
1159      scrollTop: withinElement.scrollTop(),
1160
1161      // support: jQuery 1.6.x
1162      // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1163      width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1164      height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1165    };
1166  }
1167};
1168
1169$.fn.position = function( options ) {
1170  if ( !options || !options.of ) {
1171    return _position.apply( this, arguments );
1172  }
1173
1174  // make a copy, we don't want to modify arguments
1175  options = $.extend( {}, options );
1176
1177  var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1178    target = $( options.of ),
1179    within = $.position.getWithinInfo( options.within ),
1180    scrollInfo = $.position.getScrollInfo( within ),
1181    collision = ( options.collision || "flip" ).split( " " ),
1182    offsets = {};
1183
1184  dimensions = getDimensions( target );
1185  if ( target[0].preventDefault ) {
1186    // force left top to allow flipping
1187    options.at = "left top";
1188  }
1189  targetWidth = dimensions.width;
1190  targetHeight = dimensions.height;
1191  targetOffset = dimensions.offset;
1192  // clone to reuse original targetOffset later
1193  basePosition = $.extend( {}, targetOffset );
1194
1195  // force my and at to have valid horizontal and vertical positions
1196  // if a value is missing or invalid, it will be converted to center
1197  $.each( [ "my", "at" ], function() {
1198    var pos = ( options[ this ] || "" ).split( " " ),
1199      horizontalOffset,
1200      verticalOffset;
1201
1202    if ( pos.length === 1) {
1203      pos = rhorizontal.test( pos[ 0 ] ) ?
1204        pos.concat( [ "center" ] ) :
1205        rvertical.test( pos[ 0 ] ) ?
1206          [ "center" ].concat( pos ) :
1207          [ "center", "center" ];
1208    }
1209    pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1210    pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1211
1212    // calculate offsets
1213    horizontalOffset = roffset.exec( pos[ 0 ] );
1214    verticalOffset = roffset.exec( pos[ 1 ] );
1215    offsets[ this ] = [
1216      horizontalOffset ? horizontalOffset[ 0 ] : 0,
1217      verticalOffset ? verticalOffset[ 0 ] : 0
1218    ];
1219
1220    // reduce to just the positions without the offsets
1221    options[ this ] = [
1222      rposition.exec( pos[ 0 ] )[ 0 ],
1223      rposition.exec( pos[ 1 ] )[ 0 ]
1224    ];
1225  });
1226
1227  // normalize collision option
1228  if ( collision.length === 1 ) {
1229    collision[ 1 ] = collision[ 0 ];
1230  }
1231
1232  if ( options.at[ 0 ] === "right" ) {
1233    basePosition.left += targetWidth;
1234  } else if ( options.at[ 0 ] === "center" ) {
1235    basePosition.left += targetWidth / 2;
1236  }
1237
1238  if ( options.at[ 1 ] === "bottom" ) {
1239    basePosition.top += targetHeight;
1240  } else if ( options.at[ 1 ] === "center" ) {
1241    basePosition.top += targetHeight / 2;
1242  }
1243
1244  atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1245  basePosition.left += atOffset[ 0 ];
1246  basePosition.top += atOffset[ 1 ];
1247
1248  return this.each(function() {
1249    var collisionPosition, using,
1250      elem = $( this ),
1251      elemWidth = elem.outerWidth(),
1252      elemHeight = elem.outerHeight(),
1253      marginLeft = parseCss( this, "marginLeft" ),
1254      marginTop = parseCss( this, "marginTop" ),
1255      collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1256      collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1257      position = $.extend( {}, basePosition ),
1258      myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1259
1260    if ( options.my[ 0 ] === "right" ) {
1261      position.left -= elemWidth;
1262    } else if ( options.my[ 0 ] === "center" ) {
1263      position.left -= elemWidth / 2;
1264    }
1265
1266    if ( options.my[ 1 ] === "bottom" ) {
1267      position.top -= elemHeight;
1268    } else if ( options.my[ 1 ] === "center" ) {
1269      position.top -= elemHeight / 2;
1270    }
1271
1272    position.left += myOffset[ 0 ];
1273    position.top += myOffset[ 1 ];
1274
1275    // if the browser doesn't support fractions, then round for consistent results
1276    if ( !supportsOffsetFractions ) {
1277      position.left = round( position.left );
1278      position.top = round( position.top );
1279    }
1280
1281    collisionPosition = {
1282      marginLeft: marginLeft,
1283      marginTop: marginTop
1284    };
1285
1286    $.each( [ "left", "top" ], function( i, dir ) {
1287      if ( $.ui.position[ collision[ i ] ] ) {
1288        $.ui.position[ collision[ i ] ][ dir ]( position, {
1289          targetWidth: targetWidth,
1290          targetHeight: targetHeight,
1291          elemWidth: elemWidth,
1292          elemHeight: elemHeight,
1293          collisionPosition: collisionPosition,
1294          collisionWidth: collisionWidth,
1295          collisionHeight: collisionHeight,
1296          offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1297          my: options.my,
1298          at: options.at,
1299          within: within,
1300          elem: elem
1301        });
1302      }
1303    });
1304
1305    if ( options.using ) {
1306      // adds feedback as second argument to using callback, if present
1307      using = function( props ) {
1308        var left = targetOffset.left - position.left,
1309          right = left + targetWidth - elemWidth,
1310          top = targetOffset.top - position.top,
1311          bottom = top + targetHeight - elemHeight,
1312          feedback = {
1313            target: {
1314              element: target,
1315              left: targetOffset.left,
1316              top: targetOffset.top,
1317              width: targetWidth,
1318              height: targetHeight
1319            },
1320            element: {
1321              element: elem,
1322              left: position.left,
1323              top: position.top,
1324              width: elemWidth,
1325              height: elemHeight
1326            },
1327            horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1328            vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1329          };
1330        if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1331          feedback.horizontal = "center";
1332        }
1333        if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1334          feedback.vertical = "middle";
1335        }
1336        if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1337          feedback.important = "horizontal";
1338        } else {
1339          feedback.important = "vertical";
1340        }
1341        options.using.call( this, props, feedback );
1342      };
1343    }
1344
1345    elem.offset( $.extend( position, { using: using } ) );
1346  });
1347};
1348
1349$.ui.position = {
1350  fit: {
1351    left: function( position, data ) {
1352      var within = data.within,
1353        withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1354        outerWidth = within.width,
1355        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1356        overLeft = withinOffset - collisionPosLeft,
1357        overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1358        newOverRight;
1359
1360      // element is wider than within
1361      if ( data.collisionWidth > outerWidth ) {
1362        // element is initially over the left side of within
1363        if ( overLeft > 0 && overRight <= 0 ) {
1364          newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1365          position.left += overLeft - newOverRight;
1366        // element is initially over right side of within
1367        } else if ( overRight > 0 && overLeft <= 0 ) {
1368          position.left = withinOffset;
1369        // element is initially over both left and right sides of within
1370        } else {
1371          if ( overLeft > overRight ) {
1372            position.left = withinOffset + outerWidth - data.collisionWidth;
1373          } else {
1374            position.left = withinOffset;
1375          }
1376        }
1377      // too far left -> align with left edge
1378      } else if ( overLeft > 0 ) {
1379        position.left += overLeft;
1380      // too far right -> align with right edge
1381      } else if ( overRight > 0 ) {
1382        position.left -= overRight;
1383      // adjust based on position and margin
1384      } else {
1385        position.left = max( position.left - collisionPosLeft, position.left );
1386      }
1387    },
1388    top: function( position, data ) {
1389      var within = data.within,
1390        withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1391        outerHeight = data.within.height,
1392        collisionPosTop = position.top - data.collisionPosition.marginTop,
1393        overTop = withinOffset - collisionPosTop,
1394        overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1395        newOverBottom;
1396
1397      // element is taller than within
1398      if ( data.collisionHeight > outerHeight ) {
1399        // element is initially over the top of within
1400        if ( overTop > 0 && overBottom <= 0 ) {
1401          newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1402          position.top += overTop - newOverBottom;
1403        // element is initially over bottom of within
1404        } else if ( overBottom > 0 && overTop <= 0 ) {
1405          position.top = withinOffset;
1406        // element is initially over both top and bottom of within
1407        } else {
1408          if ( overTop > overBottom ) {
1409            position.top = withinOffset + outerHeight - data.collisionHeight;
1410          } else {
1411            position.top = withinOffset;
1412          }
1413        }
1414      // too far up -> align with top
1415      } else if ( overTop > 0 ) {
1416        position.top += overTop;
1417      // too far down -> align with bottom edge
1418      } else if ( overBottom > 0 ) {
1419        position.top -= overBottom;
1420      // adjust based on position and margin
1421      } else {
1422        position.top = max( position.top - collisionPosTop, position.top );
1423      }
1424    }
1425  },
1426  flip: {
1427    left: function( position, data ) {
1428      var within = data.within,
1429        withinOffset = within.offset.left + within.scrollLeft,
1430        outerWidth = within.width,
1431        offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1432        collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1433        overLeft = collisionPosLeft - offsetLeft,
1434        overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1435        myOffset = data.my[ 0 ] === "left" ?
1436          -data.elemWidth :
1437          data.my[ 0 ] === "right" ?
1438            data.elemWidth :
1439            0,
1440        atOffset = data.at[ 0 ] === "left" ?
1441          data.targetWidth :
1442          data.at[ 0 ] === "right" ?
1443            -data.targetWidth :
1444            0,
1445        offset = -2 * data.offset[ 0 ],
1446        newOverRight,
1447        newOverLeft;
1448
1449      if ( overLeft < 0 ) {
1450        newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1451        if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1452          position.left += myOffset + atOffset + offset;
1453        }
1454      } else if ( overRight > 0 ) {
1455        newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1456        if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1457          position.left += myOffset + atOffset + offset;
1458        }
1459      }
1460    },
1461    top: function( position, data ) {
1462      var within = data.within,
1463        withinOffset = within.offset.top + within.scrollTop,
1464        outerHeight = within.height,
1465        offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1466        collisionPosTop = position.top - data.collisionPosition.marginTop,
1467        overTop = collisionPosTop - offsetTop,
1468        overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1469        top = data.my[ 1 ] === "top",
1470        myOffset = top ?
1471          -data.elemHeight :
1472          data.my[ 1 ] === "bottom" ?
1473            data.elemHeight :
1474            0,
1475        atOffset = data.at[ 1 ] === "top" ?
1476          data.targetHeight :
1477          data.at[ 1 ] === "bottom" ?
1478            -data.targetHeight :
1479            0,
1480        offset = -2 * data.offset[ 1 ],
1481        newOverTop,
1482        newOverBottom;
1483      if ( overTop < 0 ) {
1484        newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1485        if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1486          position.top += myOffset + atOffset + offset;
1487        }
1488      } else if ( overBottom > 0 ) {
1489        newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1490        if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1491          position.top += myOffset + atOffset + offset;
1492        }
1493      }
1494    }
1495  },
1496  flipfit: {
1497    left: function() {
1498      $.ui.position.flip.left.apply( this, arguments );
1499      $.ui.position.fit.left.apply( this, arguments );
1500    },
1501    top: function() {
1502      $.ui.position.flip.top.apply( this, arguments );
1503      $.ui.position.fit.top.apply( this, arguments );
1504    }
1505  }
1506};
1507
1508// fraction support test
1509(function() {
1510  var testElement, testElementParent, testElementStyle, offsetLeft, i,
1511    body = document.getElementsByTagName( "body" )[ 0 ],
1512    div = document.createElement( "div" );
1513
1514  //Create a "fake body" for testing based on method used in jQuery.support
1515  testElement = document.createElement( body ? "div" : "body" );
1516  testElementStyle = {
1517    visibility: "hidden",
1518    width: 0,
1519    height: 0,
1520    border: 0,
1521    margin: 0,
1522    background: "none"
1523  };
1524  if ( body ) {
1525    $.extend( testElementStyle, {
1526      position: "absolute",
1527      left: "-1000px",
1528      top: "-1000px"
1529    });
1530  }
1531  for ( i in testElementStyle ) {
1532    testElement.style[ i ] = testElementStyle[ i ];
1533  }
1534  testElement.appendChild( div );
1535  testElementParent = body || document.documentElement;
1536  testElementParent.insertBefore( testElement, testElementParent.firstChild );
1537
1538  div.style.cssText = "position: absolute; left: 10.7432222px;";
1539
1540  offsetLeft = $( div ).offset().left;
1541  supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1542
1543  testElement.innerHTML = "";
1544  testElementParent.removeChild( testElement );
1545})();
1546
1547})();
1548
1549var position = $.ui.position;
1550
1551
1552/*!
1553 * jQuery UI Accordion 1.11.4
1554 * http://jqueryui.com
1555 *
1556 * Copyright jQuery Foundation and other contributors
1557 * Released under the MIT license.
1558 * http://jquery.org/license
1559 *
1560 * http://api.jqueryui.com/accordion/
1561 */
1562
1563
1564var accordion = $.widget( "ui.accordion", {
1565  version: "1.11.4",
1566  options: {
1567    active: 0,
1568    animate: {},
1569    collapsible: false,
1570    event: "click",
1571    header: "> li > :first-child,> :not(li):even",
1572    heightStyle: "auto",
1573    icons: {
1574      activeHeader: "ui-icon-triangle-1-s",
1575      header: "ui-icon-triangle-1-e"
1576    },
1577
1578    // callbacks
1579    activate: null,
1580    beforeActivate: null
1581  },
1582
1583  hideProps: {
1584    borderTopWidth: "hide",
1585    borderBottomWidth: "hide",
1586    paddingTop: "hide",
1587    paddingBottom: "hide",
1588    height: "hide"
1589  },
1590
1591  showProps: {
1592    borderTopWidth: "show",
1593    borderBottomWidth: "show",
1594    paddingTop: "show",
1595    paddingBottom: "show",
1596    height: "show"
1597  },
1598
1599  _create: function() {
1600    var options = this.options;
1601    this.prevShow = this.prevHide = $();
1602    this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1603      // ARIA
1604      .attr( "role", "tablist" );
1605
1606    // don't allow collapsible: false and active: false / null
1607    if ( !options.collapsible && (options.active === false || options.active == null) ) {
1608      options.active = 0;
1609    }
1610
1611    this._processPanels();
1612    // handle negative values
1613    if ( options.active < 0 ) {
1614      options.active += this.headers.length;
1615    }
1616    this._refresh();
1617  },
1618
1619  _getCreateEventData: function() {
1620    return {
1621      header: this.active,
1622      panel: !this.active.length ? $() : this.active.next()
1623    };
1624  },
1625
1626  _createIcons: function() {
1627    var icons = this.options.icons;
1628    if ( icons ) {
1629      $( "<span>" )
1630        .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1631        .prependTo( this.headers );
1632      this.active.children( ".ui-accordion-header-icon" )
1633        .removeClass( icons.header )
1634        .addClass( icons.activeHeader );
1635      this.headers.addClass( "ui-accordion-icons" );
1636    }
1637  },
1638
1639  _destroyIcons: function() {
1640    this.headers
1641      .removeClass( "ui-accordion-icons" )
1642      .children( ".ui-accordion-header-icon" )
1643        .remove();
1644  },
1645
1646  _destroy: function() {
1647    var contents;
1648
1649    // clean up main element
1650    this.element
1651      .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1652      .removeAttr( "role" );
1653
1654    // clean up headers
1655    this.headers
1656      .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1657        "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1658      .removeAttr( "role" )
1659      .removeAttr( "aria-expanded" )
1660      .removeAttr( "aria-selected" )
1661      .removeAttr( "aria-controls" )
1662      .removeAttr( "tabIndex" )
1663      .removeUniqueId();
1664
1665    this._destroyIcons();
1666
1667    // clean up content panels
1668    contents = this.headers.next()
1669      .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1670        "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1671      .css( "display", "" )
1672      .removeAttr( "role" )
1673      .removeAttr( "aria-hidden" )
1674      .removeAttr( "aria-labelledby" )
1675      .removeUniqueId();
1676
1677    if ( this.options.heightStyle !== "content" ) {
1678      contents.css( "height", "" );
1679    }
1680  },
1681
1682  _setOption: function( key, value ) {
1683    if ( key === "active" ) {
1684      // _activate() will handle invalid values and update this.options
1685      this._activate( value );
1686      return;
1687    }
1688
1689    if ( key === "event" ) {
1690      if ( this.options.event ) {
1691        this._off( this.headers, this.options.event );
1692      }
1693      this._setupEvents( value );
1694    }
1695
1696    this._super( key, value );
1697
1698    // setting collapsible: false while collapsed; open first panel
1699    if ( key === "collapsible" && !value && this.options.active === false ) {
1700      this._activate( 0 );
1701    }
1702
1703    if ( key === "icons" ) {
1704      this._destroyIcons();
1705      if ( value ) {
1706        this._createIcons();
1707      }
1708    }
1709
1710    // #5332 - opacity doesn't cascade to positioned elements in IE
1711    // so we need to add the disabled class to the headers and panels
1712    if ( key === "disabled" ) {
1713      this.element
1714        .toggleClass( "ui-state-disabled", !!value )
1715        .attr( "aria-disabled", value );
1716      this.headers.add( this.headers.next() )
1717        .toggleClass( "ui-state-disabled", !!value );
1718    }
1719  },
1720
vendor: 21,060 bytes, lines 1721-2422
1721  _keydown: function( event ) {
1722    if ( event.altKey || event.ctrlKey ) {
1723      return;
1724    }
1725
1726    var keyCode = $.ui.keyCode,
1727      length = this.headers.length,
1728      currentIndex = this.headers.index( event.target ),
1729      toFocus = false;
1730
1731    switch ( event.keyCode ) {
1732      case keyCode.RIGHT:
1733      case keyCode.DOWN:
1734        toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1735        break;
1736      case keyCode.LEFT:
1737      case keyCode.UP:
1738        toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1739        break;
1740      case keyCode.SPACE:
1741      case keyCode.ENTER:
1742        this._eventHandler( event );
1743        break;
1744      case keyCode.HOME:
1745        toFocus = this.headers[ 0 ];
1746        break;
1747      case keyCode.END:
1748        toFocus = this.headers[ length - 1 ];
1749        break;
1750    }
1751
1752    if ( toFocus ) {
1753      $( event.target ).attr( "tabIndex", -1 );
1754      $( toFocus ).attr( "tabIndex", 0 );
1755      toFocus.focus();
1756      event.preventDefault();
1757    }
1758  },
1759
1760  _panelKeyDown: function( event ) {
1761    if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1762      $( event.currentTarget ).prev().focus();
1763    }
1764  },
1765
1766  refresh: function() {
1767    var options = this.options;
1768    this._processPanels();
1769
1770    // was collapsed or no panel
1771    if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1772      options.active = false;
1773      this.active = $();
1774    // active false only when collapsible is true
1775    } else if ( options.active === false ) {
1776      this._activate( 0 );
1777    // was active, but active panel is gone
1778    } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1779      // all remaining panel are disabled
1780      if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1781        options.active = false;
1782        this.active = $();
1783      // activate previous panel
1784      } else {
1785        this._activate( Math.max( 0, options.active - 1 ) );
1786      }
1787    // was active, active panel still exists
1788    } else {
1789      // make sure active index is correct
1790      options.active = this.headers.index( this.active );
1791    }
1792
1793    this._destroyIcons();
1794
1795    this._refresh();
1796  },
1797
1798  _processPanels: function() {
1799    var prevHeaders = this.headers,
1800      prevPanels = this.panels;
1801
1802    this.headers = this.element.find( this.options.header )
1803      .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1804
1805    this.panels = this.headers.next()
1806      .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1807      .filter( ":not(.ui-accordion-content-active)" )
1808      .hide();
1809
1810    // Avoid memory leaks (#10056)
1811    if ( prevPanels ) {
1812      this._off( prevHeaders.not( this.headers ) );
1813      this._off( prevPanels.not( this.panels ) );
1814    }
1815  },
1816
1817  _refresh: function() {
1818    var maxHeight,
1819      options = this.options,
1820      heightStyle = options.heightStyle,
1821      parent = this.element.parent();
1822
1823    this.active = this._findActive( options.active )
1824      .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1825      .removeClass( "ui-corner-all" );
1826    this.active.next()
1827      .addClass( "ui-accordion-content-active" )
1828      .show();
1829
1830    this.headers
1831      .attr( "role", "tab" )
1832      .each(function() {
1833        var header = $( this ),
1834          headerId = header.uniqueId().attr( "id" ),
1835          panel = header.next(),
1836          panelId = panel.uniqueId().attr( "id" );
1837        header.attr( "aria-controls", panelId );
1838        panel.attr( "aria-labelledby", headerId );
1839      })
1840      .next()
1841        .attr( "role", "tabpanel" );
1842
1843    this.headers
1844      .not( this.active )
1845      .attr({
1846        "aria-selected": "false",
1847        "aria-expanded": "false",
1848        tabIndex: -1
1849      })
1850      .next()
1851        .attr({
1852          "aria-hidden": "true"
1853        })
1854        .hide();
1855
1856    // make sure at least one header is in the tab order
1857    if ( !this.active.length ) {
1858      this.headers.eq( 0 ).attr( "tabIndex", 0 );
1859    } else {
1860      this.active.attr({
1861        "aria-selected": "true",
1862        "aria-expanded": "true",
1863        tabIndex: 0
1864      })
1865      .next()
1866        .attr({
1867          "aria-hidden": "false"
1868        });
1869    }
1870
1871    this._createIcons();
1872
1873    this._setupEvents( options.event );
1874
1875    if ( heightStyle === "fill" ) {
1876      maxHeight = parent.height();
1877      this.element.siblings( ":visible" ).each(function() {
1878        var elem = $( this ),
1879          position = elem.css( "position" );
1880
1881        if ( position === "absolute" || position === "fixed" ) {
1882          return;
1883        }
1884        maxHeight -= elem.outerHeight( true );
1885      });
1886
1887      this.headers.each(function() {
1888        maxHeight -= $( this ).outerHeight( true );
1889      });
1890
1891      this.headers.next()
1892        .each(function() {
1893          $( this ).height( Math.max( 0, maxHeight -
1894            $( this ).innerHeight() + $( this ).height() ) );
1895        })
1896        .css( "overflow", "auto" );
1897    } else if ( heightStyle === "auto" ) {
1898      maxHeight = 0;
1899      this.headers.next()
1900        .each(function() {
1901          maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1902        })
1903        .height( maxHeight );
1904    }
1905  },
1906
1907  _activate: function( index ) {
1908    var active = this._findActive( index )[ 0 ];
1909
1910    // trying to activate the already active panel
1911    if ( active === this.active[ 0 ] ) {
1912      return;
1913    }
1914
1915    // trying to collapse, simulate a click on the currently active header
1916    active = active || this.active[ 0 ];
1917
1918    this._eventHandler({
1919      target: active,
1920      currentTarget: active,
1921      preventDefault: $.noop
1922    });
1923  },
1924
1925  _findActive: function( selector ) {
1926    return typeof selector === "number" ? this.headers.eq( selector ) : $();
1927  },
1928
1929  _setupEvents: function( event ) {
1930    var events = {
1931      keydown: "_keydown"
1932    };
1933    if ( event ) {
1934      $.each( event.split( " " ), function( index, eventName ) {
1935        events[ eventName ] = "_eventHandler";
1936      });
1937    }
1938
1939    this._off( this.headers.add( this.headers.next() ) );
1940    this._on( this.headers, events );
1941    this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1942    this._hoverable( this.headers );
1943    this._focusable( this.headers );
1944  },
1945
1946  _eventHandler: function( event ) {
1947    var options = this.options,
1948      active = this.active,
1949      clicked = $( event.currentTarget ),
1950      clickedIsActive = clicked[ 0 ] === active[ 0 ],
1951      collapsing = clickedIsActive && options.collapsible,
1952      toShow = collapsing ? $() : clicked.next(),
1953      toHide = active.next(),
1954      eventData = {
1955        oldHeader: active,
1956        oldPanel: toHide,
1957        newHeader: collapsing ? $() : clicked,
1958        newPanel: toShow
1959      };
1960
1961    event.preventDefault();
1962
1963    if (
1964        // click on active header, but not collapsible
1965        ( clickedIsActive && !options.collapsible ) ||
1966        // allow canceling activation
1967        ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1968      return;
1969    }
1970
1971    options.active = collapsing ? false : this.headers.index( clicked );
1972
1973    // when the call to ._toggle() comes after the class changes
1974    // it causes a very odd bug in IE 8 (see #6720)
1975    this.active = clickedIsActive ? $() : clicked;
1976    this._toggle( eventData );
1977
1978    // switch classes
1979    // corner classes on the previously active header stay after the animation
1980    active.removeClass( "ui-accordion-header-active ui-state-active" );
1981    if ( options.icons ) {
1982      active.children( ".ui-accordion-header-icon" )
1983        .removeClass( options.icons.activeHeader )
1984        .addClass( options.icons.header );
1985    }
1986
1987    if ( !clickedIsActive ) {
1988      clicked
1989        .removeClass( "ui-corner-all" )
1990        .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1991      if ( options.icons ) {
1992        clicked.children( ".ui-accordion-header-icon" )
1993          .removeClass( options.icons.header )
1994          .addClass( options.icons.activeHeader );
1995      }
1996
1997      clicked
1998        .next()
1999        .addClass( "ui-accordion-content-active" );
2000    }
2001  },
2002
2003  _toggle: function( data ) {
2004    var toShow = data.newPanel,
2005      toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
2006
2007    // handle activating a panel during the animation for another activation
2008    this.prevShow.add( this.prevHide ).stop( true, true );
2009    this.prevShow = toShow;
2010    this.prevHide = toHide;
2011
2012    if ( this.options.animate ) {
2013      this._animate( toShow, toHide, data );
2014    } else {
2015      toHide.hide();
2016      toShow.show();
2017      this._toggleComplete( data );
2018    }
2019
2020    toHide.attr({
2021      "aria-hidden": "true"
2022    });
2023    toHide.prev().attr({
2024      "aria-selected": "false",
2025      "aria-expanded": "false"
2026    });
2027    // if we're switching panels, remove the old header from the tab order
2028    // if we're opening from collapsed state, remove the previous header from the tab order
2029    // if we're collapsing, then keep the collapsing header in the tab order
2030    if ( toShow.length && toHide.length ) {
2031      toHide.prev().attr({
2032        "tabIndex": -1,
2033        "aria-expanded": "false"
2034      });
2035    } else if ( toShow.length ) {
2036      this.headers.filter(function() {
2037        return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
2038      })
2039      .attr( "tabIndex", -1 );
2040    }
2041
2042    toShow
2043      .attr( "aria-hidden", "false" )
2044      .prev()
2045        .attr({
2046          "aria-selected": "true",
2047          "aria-expanded": "true",
2048          tabIndex: 0
2049        });
2050  },
2051
2052  _animate: function( toShow, toHide, data ) {
2053    var total, easing, duration,
2054      that = this,
2055      adjust = 0,
2056      boxSizing = toShow.css( "box-sizing" ),
2057      down = toShow.length &&
2058        ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2059      animate = this.options.animate || {},
2060      options = down && animate.down || animate,
2061      complete = function() {
2062        that._toggleComplete( data );
2063      };
2064
2065    if ( typeof options === "number" ) {
2066      duration = options;
2067    }
2068    if ( typeof options === "string" ) {
2069      easing = options;
2070    }
2071    // fall back from options to animation in case of partial down settings
2072    easing = easing || options.easing || animate.easing;
2073    duration = duration || options.duration || animate.duration;
2074
2075    if ( !toHide.length ) {
2076      return toShow.animate( this.showProps, duration, easing, complete );
2077    }
2078    if ( !toShow.length ) {
2079      return toHide.animate( this.hideProps, duration, easing, complete );
2080    }
2081
2082    total = toShow.show().outerHeight();
2083    toHide.animate( this.hideProps, {
2084      duration: duration,
2085      easing: easing,
2086      step: function( now, fx ) {
2087        fx.now = Math.round( now );
2088      }
2089    });
2090    toShow
2091      .hide()
2092      .animate( this.showProps, {
2093        duration: duration,
2094        easing: easing,
2095        complete: complete,
2096        step: function( now, fx ) {
2097          fx.now = Math.round( now );
2098          if ( fx.prop !== "height" ) {
2099            if ( boxSizing === "content-box" ) {
2100              adjust += fx.now;
2101            }
2102          } else if ( that.options.heightStyle !== "content" ) {
2103            fx.now = Math.round( total - toHide.outerHeight() - adjust );
2104            adjust = 0;
2105          }
2106        }
2107      });
2108  },
2109
2110  _toggleComplete: function( data ) {
2111    var toHide = data.oldPanel;
2112
2113    toHide
2114      .removeClass( "ui-accordion-content-active" )
2115      .prev()
2116        .removeClass( "ui-corner-top" )
2117        .addClass( "ui-corner-all" );
2118
2119    // Work around for rendering bug in IE (#5421)
2120    if ( toHide.length ) {
2121      toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2122    }
2123    this._trigger( "activate", null, data );
2124  }
2125});
2126
2127
2128/*!
2129 * jQuery UI Menu 1.11.4
2130 * http://jqueryui.com
2131 *
2132 * Copyright jQuery Foundation and other contributors
2133 * Released under the MIT license.
2134 * http://jquery.org/license
2135 *
2136 * http://api.jqueryui.com/menu/
2137 */
2138
2139
2140var menu = $.widget( "ui.menu", {
2141  version: "1.11.4",
2142  defaultElement: "<ul>",
2143  delay: 300,
2144  options: {
2145    icons: {
2146      submenu: "ui-icon-carat-1-e"
2147    },
2148    items: "> *",
2149    menus: "ul",
2150    position: {
2151      my: "left-1 top",
2152      at: "right top"
2153    },
2154    role: "menu",
2155
2156    // callbacks
2157    blur: null,
2158    focus: null,
2159    select: null
2160  },
2161
2162  _create: function() {
2163    this.activeMenu = this.element;
2164
2165    // Flag used to prevent firing of the click handler
2166    // as the event bubbles up through nested menus
2167    this.mouseHandled = false;
2168    this.element
2169      .uniqueId()
2170      .addClass( "ui-menu ui-widget ui-widget-content" )
2171      .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2172      .attr({
2173        role: this.options.role,
2174        tabIndex: 0
2175      });
2176
2177    if ( this.options.disabled ) {
2178      this.element
2179        .addClass( "ui-state-disabled" )
2180        .attr( "aria-disabled", "true" );
2181    }
2182
2183    this._on({
2184      // Prevent focus from sticking to links inside menu after clicking
2185      // them (focus should always stay on UL during navigation).
2186      "mousedown .ui-menu-item": function( event ) {
2187        event.preventDefault();
2188      },
2189      "click .ui-menu-item": function( event ) {
2190        var target = $( event.target );
2191        if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2192          this.select( event );
2193
2194          // Only set the mouseHandled flag if the event will bubble, see #9469.
2195          if ( !event.isPropagationStopped() ) {
2196            this.mouseHandled = true;
2197          }
2198
2199          // Open submenu on click
2200          if ( target.has( ".ui-menu" ).length ) {
2201            this.expand( event );
2202          } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2203
2204            // Redirect focus to the menu
2205            this.element.trigger( "focus", [ true ] );
2206
2207            // If the active item is on the top level, let it stay active.
2208            // Otherwise, blur the active item since it is no longer visible.
2209            if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2210              clearTimeout( this.timer );
2211            }
2212          }
2213        }
2214      },
2215      "mouseenter .ui-menu-item": function( event ) {
2216        // Ignore mouse events while typeahead is active, see #10458.
2217        // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
2218        // is over an item in the menu
2219        if ( this.previousFilter ) {
2220          return;
2221        }
2222        var target = $( event.currentTarget );
2223        // Remove ui-state-active class from siblings of the newly focused menu item
2224        // to avoid a jump caused by adjacent elements both having a class with a border
2225        target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2226        this.focus( event, target );
2227      },
2228      mouseleave: "collapseAll",
2229      "mouseleave .ui-menu": "collapseAll",
2230      focus: function( event, keepActiveItem ) {
2231        // If there's already an active item, keep it active
2232        // If not, activate the first item
2233        var item = this.active || this.element.find( this.options.items ).eq( 0 );
2234
2235        if ( !keepActiveItem ) {
2236          this.focus( event, item );
2237        }
2238      },
2239      blur: function( event ) {
2240        this._delay(function() {
2241          if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2242            this.collapseAll( event );
2243          }
2244        });
2245      },
2246      keydown: "_keydown"
2247    });
2248
2249    this.refresh();
2250
2251    // Clicks outside of a menu collapse any open menus
2252    this._on( this.document, {
2253      click: function( event ) {
2254        if ( this._closeOnDocumentClick( event ) ) {
2255          this.collapseAll( event );
2256        }
2257
2258        // Reset the mouseHandled flag
2259        this.mouseHandled = false;
2260      }
2261    });
2262  },
2263
2264  _destroy: function() {
2265    // Destroy (sub)menus
2266    this.element
2267      .removeAttr( "aria-activedescendant" )
2268      .find( ".ui-menu" ).addBack()
2269        .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2270        .removeAttr( "role" )
2271        .removeAttr( "tabIndex" )
2272        .removeAttr( "aria-labelledby" )
2273        .removeAttr( "aria-expanded" )
2274        .removeAttr( "aria-hidden" )
2275        .removeAttr( "aria-disabled" )
2276        .removeUniqueId()
2277        .show();
2278
2279    // Destroy menu items
2280    this.element.find( ".ui-menu-item" )
2281      .removeClass( "ui-menu-item" )
2282      .removeAttr( "role" )
2283      .removeAttr( "aria-disabled" )
2284      .removeUniqueId()
2285      .removeClass( "ui-state-hover" )
2286      .removeAttr( "tabIndex" )
2287      .removeAttr( "role" )
2288      .removeAttr( "aria-haspopup" )
2289      .children().each( function() {
2290        var elem = $( this );
2291        if ( elem.data( "ui-menu-submenu-carat" ) ) {
2292          elem.remove();
2293        }
2294      });
2295
2296    // Destroy menu dividers
2297    this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2298  },
2299
2300  _keydown: function( event ) {
2301    var match, prev, character, skip,
2302      preventDefault = true;
2303
2304    switch ( event.keyCode ) {
2305    case $.ui.keyCode.PAGE_UP:
2306      this.previousPage( event );
2307      break;
2308    case $.ui.keyCode.PAGE_DOWN:
2309      this.nextPage( event );
2310      break;
2311    case $.ui.keyCode.HOME:
2312      this._move( "first", "first", event );
2313      break;
2314    case $.ui.keyCode.END:
2315      this._move( "last", "last", event );
2316      break;
2317    case $.ui.keyCode.UP:
2318      this.previous( event );
2319      break;
2320    case $.ui.keyCode.DOWN:
2321      this.next( event );
2322      break;
2323    case $.ui.keyCode.LEFT:
2324      this.collapse( event );
2325      break;
2326    case $.ui.keyCode.RIGHT:
2327      if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2328        this.expand( event );
2329      }
2330      break;
2331    case $.ui.keyCode.ENTER:
2332    case $.ui.keyCode.SPACE:
2333      this._activate( event );
2334      break;
2335    case $.ui.keyCode.ESCAPE:
2336      this.collapse( event );
2337      break;
2338    default:
2339      preventDefault = false;
2340      prev = this.previousFilter || "";
2341      character = String.fromCharCode( event.keyCode );
2342      skip = false;
2343
2344      clearTimeout( this.filterTimer );
2345
2346      if ( character === prev ) {
2347        skip = true;
2348      } else {
2349        character = prev + character;
2350      }
2351
2352      match = this._filterMenuItems( character );
2353      match = skip && match.index( this.active.next() ) !== -1 ?
2354        this.active.nextAll( ".ui-menu-item" ) :
2355        match;
2356
2357      // If no matches on the current filter, reset to the last character pressed
2358      // to move down the menu to the first item that starts with that character
2359      if ( !match.length ) {
2360        character = String.fromCharCode( event.keyCode );
2361        match = this._filterMenuItems( character );
2362      }
2363
2364      if ( match.length ) {
2365        this.focus( event, match );
2366        this.previousFilter = character;
2367        this.filterTimer = this._delay(function() {
2368          delete this.previousFilter;
2369        }, 1000 );
2370      } else {
2371        delete this.previousFilter;
2372      }
2373    }
2374
2375    if ( preventDefault ) {
2376      event.preventDefault();
2377    }
2378  },
2379
2380  _activate: function( event ) {
2381    if ( !this.active.is( ".ui-state-disabled" ) ) {
2382      if ( this.active.is( "[aria-haspopup='true']" ) ) {
2383        this.expand( event );
2384      } else {
2385        this.select( event );
2386      }
2387    }
2388  },
2389
2390  refresh: function() {
2391    var menus, items,
2392      that = this,
2393      icon = this.options.icons.submenu,
2394      submenus = this.element.find( this.options.menus );
2395
2396    this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2397
2398    // Initialize nested menus
2399    submenus.filter( ":not(.ui-menu)" )
2400      .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2401      .hide()
2402      .attr({
2403        role: this.options.role,
2404        "aria-hidden": "true",
2405        "aria-expanded": "false"
2406      })
2407      .each(function() {
2408        var menu = $( this ),
2409          item = menu.parent(),
2410          submenuCarat = $( "<span>" )
2411            .addClass( "ui-menu-icon ui-icon " + icon )
2412            .data( "ui-menu-submenu-carat", true );
2413
2414        item
2415          .attr( "aria-haspopup", "true" )
2416          .prepend( submenuCarat );
2417        menu.attr( "aria-labelledby", item.attr( "id" ) );
2418      });
2419
2420    menus = submenus.add( this.element );
2421    items = menus.find( this.options.items );
2422
vendor: 9,392 bytes, lines 2423-2742
2423    // Initialize menu-items containing spaces and/or dashes only as dividers
2424    items.not( ".ui-menu-item" ).each(function() {
2425      var item = $( this );
2426      if ( that._isDivider( item ) ) {
2427        item.addClass( "ui-widget-content ui-menu-divider" );
2428      }
2429    });
2430
2431    // Don't refresh list items that are already adapted
2432    items.not( ".ui-menu-item, .ui-menu-divider" )
2433      .addClass( "ui-menu-item" )
2434      .uniqueId()
2435      .attr({
2436        tabIndex: -1,
2437        role: this._itemRole()
2438      });
2439
2440    // Add aria-disabled attribute to any disabled menu item
2441    items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2442
2443    // If the active item has been removed, blur the menu
2444    if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2445      this.blur();
2446    }
2447  },
2448
2449  _itemRole: function() {
2450    return {
2451      menu: "menuitem",
2452      listbox: "option"
2453    }[ this.options.role ];
2454  },
2455
2456  _setOption: function( key, value ) {
2457    if ( key === "icons" ) {
2458      this.element.find( ".ui-menu-icon" )
2459        .removeClass( this.options.icons.submenu )
2460        .addClass( value.submenu );
2461    }
2462    if ( key === "disabled" ) {
2463      this.element
2464        .toggleClass( "ui-state-disabled", !!value )
2465        .attr( "aria-disabled", value );
2466    }
2467    this._super( key, value );
2468  },
2469
2470  focus: function( event, item ) {
2471    var nested, focused;
2472    this.blur( event, event && event.type === "focus" );
2473
2474    this._scrollIntoView( item );
2475
2476    this.active = item.first();
2477    focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2478    // Only update aria-activedescendant if there's a role
2479    // otherwise we assume focus is managed elsewhere
2480    if ( this.options.role ) {
2481      this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2482    }
2483
2484    // Highlight active parent menu item, if any
2485    this.active
2486      .parent()
2487      .closest( ".ui-menu-item" )
2488      .addClass( "ui-state-active" );
2489
2490    if ( event && event.type === "keydown" ) {
2491      this._close();
2492    } else {
2493      this.timer = this._delay(function() {
2494        this._close();
2495      }, this.delay );
2496    }
2497
2498    nested = item.children( ".ui-menu" );
2499    if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2500      this._startOpening(nested);
2501    }
2502    this.activeMenu = item.parent();
2503
2504    this._trigger( "focus", event, { item: item } );
2505  },
2506
2507  _scrollIntoView: function( item ) {
2508    var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2509    if ( this._hasScroll() ) {
2510      borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2511      paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2512      offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2513      scroll = this.activeMenu.scrollTop();
2514      elementHeight = this.activeMenu.height();
2515      itemHeight = item.outerHeight();
2516
2517      if ( offset < 0 ) {
2518        this.activeMenu.scrollTop( scroll + offset );
2519      } else if ( offset + itemHeight > elementHeight ) {
2520        this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2521      }
2522    }
2523  },
2524
2525  blur: function( event, fromFocus ) {
2526    if ( !fromFocus ) {
2527      clearTimeout( this.timer );
2528    }
2529
2530    if ( !this.active ) {
2531      return;
2532    }
2533
2534    this.active.removeClass( "ui-state-focus" );
2535    this.active = null;
2536
2537    this._trigger( "blur", event, { item: this.active } );
2538  },
2539
2540  _startOpening: function( submenu ) {
2541    clearTimeout( this.timer );
2542
2543    // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2544    // shift in the submenu position when mousing over the carat icon
2545    if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2546      return;
2547    }
2548
2549    this.timer = this._delay(function() {
2550      this._close();
2551      this._open( submenu );
2552    }, this.delay );
2553  },
2554
2555  _open: function( submenu ) {
2556    var position = $.extend({
2557      of: this.active
2558    }, this.options.position );
2559
2560    clearTimeout( this.timer );
2561    this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2562      .hide()
2563      .attr( "aria-hidden", "true" );
2564
2565    submenu
2566      .show()
2567      .removeAttr( "aria-hidden" )
2568      .attr( "aria-expanded", "true" )
2569      .position( position );
2570  },
2571
2572  collapseAll: function( event, all ) {
2573    clearTimeout( this.timer );
2574    this.timer = this._delay(function() {
2575      // If we were passed an event, look for the submenu that contains the event
2576      var currentMenu = all ? this.element :
2577        $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2578
2579      // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2580      if ( !currentMenu.length ) {
2581        currentMenu = this.element;
2582      }
2583
2584      this._close( currentMenu );
2585
2586      this.blur( event );
2587      this.activeMenu = currentMenu;
2588    }, this.delay );
2589  },
2590
2591  // With no arguments, closes the currently active menu - if nothing is active
2592  // it closes all menus.  If passed an argument, it will search for menus BELOW
2593  _close: function( startMenu ) {
2594    if ( !startMenu ) {
2595      startMenu = this.active ? this.active.parent() : this.element;
2596    }
2597
2598    startMenu
2599      .find( ".ui-menu" )
2600        .hide()
2601        .attr( "aria-hidden", "true" )
2602        .attr( "aria-expanded", "false" )
2603      .end()
2604      .find( ".ui-state-active" ).not( ".ui-state-focus" )
2605        .removeClass( "ui-state-active" );
2606  },
2607
2608  _closeOnDocumentClick: function( event ) {
2609    return !$( event.target ).closest( ".ui-menu" ).length;
2610  },
2611
2612  _isDivider: function( item ) {
2613
2614    // Match hyphen, em dash, en dash
2615    return !/[^\-\u2014\u2013\s]/.test( item.text() );
2616  },
2617
2618  collapse: function( event ) {
2619    var newItem = this.active &&
2620      this.active.parent().closest( ".ui-menu-item", this.element );
2621    if ( newItem && newItem.length ) {
2622      this._close();
2623      this.focus( event, newItem );
2624    }
2625  },
2626
2627  expand: function( event ) {
2628    var newItem = this.active &&
2629      this.active
2630        .children( ".ui-menu " )
2631        .find( this.options.items )
2632        .first();
2633
2634    if ( newItem && newItem.length ) {
2635      this._open( newItem.parent() );
2636
2637      // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2638      this._delay(function() {
2639        this.focus( event, newItem );
2640      });
2641    }
2642  },
2643
2644  next: function( event ) {
2645    this._move( "next", "first", event );
2646  },
2647
2648  previous: function( event ) {
2649    this._move( "prev", "last", event );
2650  },
2651
2652  isFirstItem: function() {
2653    return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2654  },
2655
2656  isLastItem: function() {
2657    return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2658  },
2659
2660  _move: function( direction, filter, event ) {
2661    var next;
2662    if ( this.active ) {
2663      if ( direction === "first" || direction === "last" ) {
2664        next = this.active
2665          [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2666          .eq( -1 );
2667      } else {
2668        next = this.active
2669          [ direction + "All" ]( ".ui-menu-item" )
2670          .eq( 0 );
2671      }
2672    }
2673    if ( !next || !next.length || !this.active ) {
2674      next = this.activeMenu.find( this.options.items )[ filter ]();
2675    }
2676
2677    this.focus( event, next );
2678  },
2679
2680  nextPage: function( event ) {
2681    var item, base, height;
2682
2683    if ( !this.active ) {
2684      this.next( event );
2685      return;
2686    }
2687    if ( this.isLastItem() ) {
2688      return;
2689    }
2690    if ( this._hasScroll() ) {
2691      base = this.active.offset().top;
2692      height = this.element.height();
2693      this.active.nextAll( ".ui-menu-item" ).each(function() {
2694        item = $( this );
2695        return item.offset().top - base - height < 0;
2696      });
2697
2698      this.focus( event, item );
2699    } else {
2700      this.focus( event, this.activeMenu.find( this.options.items )
2701        [ !this.active ? "first" : "last" ]() );
2702    }
2703  },
2704
2705  previousPage: function( event ) {
2706    var item, base, height;
2707    if ( !this.active ) {
2708      this.next( event );
2709      return;
2710    }
2711    if ( this.isFirstItem() ) {
2712      return;
2713    }
2714    if ( this._hasScroll() ) {
2715      base = this.active.offset().top;
2716      height = this.element.height();
2717      this.active.prevAll( ".ui-menu-item" ).each(function() {
2718        item = $( this );
2719        return item.offset().top - base + height > 0;
2720      });
2721
2722      this.focus( event, item );
2723    } else {
2724      this.focus( event, this.activeMenu.find( this.options.items ).first() );
2725    }
2726  },
2727
2728  _hasScroll: function() {
2729    return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2730  },
2731
2732  select: function( event ) {
2733    // TODO: It should never be possible to not have an active item at this
2734    // point, but the tests don't trigger mouseenter before click.
2735    this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2736    var ui = { item: this.active };
2737    if ( !this.active.has( ".ui-menu" ).length ) {
2738      this.collapseAll( event, true );
2739    }
2740    this._trigger( "select", event, ui );
2741  },
2742
vendor: 5,812 bytes, lines 2743-2930
2743  _filterMenuItems: function(character) {
2744    var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
2745      regex = new RegExp( "^" + escapedCharacter, "i" );
2746
2747    return this.activeMenu
2748      .find( this.options.items )
2749
2750      // Only match on items, not dividers or other content (#10571)
2751      .filter( ".ui-menu-item" )
2752      .filter(function() {
2753        return regex.test( $.trim( $( this ).text() ) );
2754      });
2755  }
2756});
2757
2758
2759/*!
2760 * jQuery UI Autocomplete 1.11.4
2761 * http://jqueryui.com
2762 *
2763 * Copyright jQuery Foundation and other contributors
2764 * Released under the MIT license.
2765 * http://jquery.org/license
2766 *
2767 * http://api.jqueryui.com/autocomplete/
2768 */
2769
2770
2771$.widget( "ui.autocomplete", {
2772  version: "1.11.4",
2773  defaultElement: "<input>",
2774  options: {
2775    appendTo: null,
2776    autoFocus: false,
2777    delay: 300,
2778    minLength: 1,
2779    position: {
2780      my: "left top",
2781      at: "left bottom",
2782      collision: "none"
2783    },
2784    source: null,
2785
2786    // callbacks
2787    change: null,
2788    close: null,
2789    focus: null,
2790    open: null,
2791    response: null,
2792    search: null,
2793    select: null
2794  },
2795
2796  requestIndex: 0,
2797  pending: 0,
2798
2799  _create: function() {
2800    // Some browsers only repeat keydown events, not keypress events,
2801    // so we use the suppressKeyPress flag to determine if we've already
2802    // handled the keydown event. #7269
2803    // Unfortunately the code for & in keypress is the same as the up arrow,
2804    // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2805    // events when we know the keydown event was used to modify the
2806    // search term. #7799
2807    var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2808      nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2809      isTextarea = nodeName === "textarea",
2810      isInput = nodeName === "input";
2811
2812    this.isMultiLine =
2813      // Textareas are always multi-line
2814      isTextarea ? true :
2815      // Inputs are always single-line, even if inside a contentEditable element
2816      // IE also treats inputs as contentEditable
2817      isInput ? false :
2818      // All other element types are determined by whether or not they're contentEditable
2819      this.element.prop( "isContentEditable" );
2820
2821    this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2822    this.isNewMenu = true;
2823
2824    this.element
2825      .addClass( "ui-autocomplete-input" )
2826      .attr( "autocomplete", "off" );
2827
2828    this._on( this.element, {
2829      keydown: function( event ) {
2830        if ( this.element.prop( "readOnly" ) ) {
2831          suppressKeyPress = true;
2832          suppressInput = true;
2833          suppressKeyPressRepeat = true;
2834          return;
2835        }
2836
2837        suppressKeyPress = false;
2838        suppressInput = false;
2839        suppressKeyPressRepeat = false;
2840        var keyCode = $.ui.keyCode;
2841        switch ( event.keyCode ) {
2842        case keyCode.PAGE_UP:
2843          suppressKeyPress = true;
2844          this._move( "previousPage", event );
2845          break;
2846        case keyCode.PAGE_DOWN:
2847          suppressKeyPress = true;
2848          this._move( "nextPage", event );
2849          break;
2850        case keyCode.UP:
2851          suppressKeyPress = true;
2852          this._keyEvent( "previous", event );
2853          break;
2854        case keyCode.DOWN:
2855          suppressKeyPress = true;
2856          this._keyEvent( "next", event );
2857          break;
2858        case keyCode.ENTER:
2859          // when menu is open and has focus
2860          if ( this.menu.active ) {
2861            // #6055 - Opera still allows the keypress to occur
2862            // which causes forms to submit
2863            suppressKeyPress = true;
2864            event.preventDefault();
2865            this.menu.select( event );
2866          }
2867          break;
2868        case keyCode.TAB:
2869          if ( this.menu.active ) {
2870            this.menu.select( event );
2871          }
2872          break;
2873        case keyCode.ESCAPE:
2874          if ( this.menu.element.is( ":visible" ) ) {
2875            if ( !this.isMultiLine ) {
2876              this._value( this.term );
2877            }
2878            this.close( event );
2879            // Different browsers have different default behavior for escape
2880            // Single press can mean undo or clear
2881            // Double press in IE means clear the whole form
2882            event.preventDefault();
2883          }
2884          break;
2885        default:
2886          suppressKeyPressRepeat = true;
2887          // search timeout should be triggered before the input value is changed
2888          this._searchTimeout( event );
2889          break;
2890        }
2891      },
2892      keypress: function( event ) {
2893        if ( suppressKeyPress ) {
2894          suppressKeyPress = false;
2895          if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2896            event.preventDefault();
2897          }
2898          return;
2899        }
2900        if ( suppressKeyPressRepeat ) {
2901          return;
2902        }
2903
2904        // replicate some key handlers to allow them to repeat in Firefox and Opera
2905        var keyCode = $.ui.keyCode;
2906        switch ( event.keyCode ) {
2907        case keyCode.PAGE_UP:
2908          this._move( "previousPage", event );
2909          break;
2910        case keyCode.PAGE_DOWN:
2911          this._move( "nextPage", event );
2912          break;
2913        case keyCode.UP:
2914          this._keyEvent( "previous", event );
2915          break;
2916        case keyCode.DOWN:
2917          this._keyEvent( "next", event );
2918          break;
2919        }
2920      },
2921      input: function( event ) {
2922        if ( suppressInput ) {
2923          suppressInput = false;
2924          event.preventDefault();
2925          return;
2926        }
2927        this._searchTimeout( event );
2928      },
2929      focus: function() {
2930        this.selectedItem = null;
vendor: 29,932 bytes, lines 2931-3847
2931        this.previous = this._value();
2932      },
2933      blur: function( event ) {
2934        if ( this.cancelBlur ) {
2935          delete this.cancelBlur;
2936          return;
2937        }
2938
2939        clearTimeout( this.searching );
2940        this.close( event );
2941        this._change( event );
2942      }
2943    });
2944
2945    this._initSource();
2946    this.menu = $( "<ul>" )
2947      .addClass( "ui-autocomplete ui-front" )
2948      .appendTo( this._appendTo() )
2949      .menu({
2950        // disable ARIA support, the live region takes care of that
2951        role: null
2952      })
2953      .hide()
2954      .menu( "instance" );
2955
2956    this._on( this.menu.element, {
2957      mousedown: function( event ) {
2958        // prevent moving focus out of the text field
2959        event.preventDefault();
2960
2961        // IE doesn't prevent moving focus even with event.preventDefault()
2962        // so we set a flag to know when we should ignore the blur event
2963        this.cancelBlur = true;
2964        this._delay(function() {
2965          delete this.cancelBlur;
2966        });
2967
2968        // clicking on the scrollbar causes focus to shift to the body
2969        // but we can't detect a mouseup or a click immediately afterward
2970        // so we have to track the next mousedown and close the menu if
2971        // the user clicks somewhere outside of the autocomplete
2972        var menuElement = this.menu.element[ 0 ];
2973        if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2974          this._delay(function() {
2975            var that = this;
2976            this.document.one( "mousedown", function( event ) {
2977              if ( event.target !== that.element[ 0 ] &&
2978                  event.target !== menuElement &&
2979                  !$.contains( menuElement, event.target ) ) {
2980                that.close();
2981              }
2982            });
2983          });
2984        }
2985      },
2986      menufocus: function( event, ui ) {
2987        var label, item;
2988        // support: Firefox
2989        // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2990        if ( this.isNewMenu ) {
2991          this.isNewMenu = false;
2992          if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2993            this.menu.blur();
2994
2995            this.document.one( "mousemove", function() {
2996              $( event.target ).trigger( event.originalEvent );
2997            });
2998
2999            return;
3000          }
3001        }
3002
3003        item = ui.item.data( "ui-autocomplete-item" );
3004        if ( false !== this._trigger( "focus", event, { item: item } ) ) {
3005          // use value to match what will end up in the input, if it was a key event
3006          if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
3007            this._value( item.value );
3008          }
3009        }
3010
3011        // Announce the value in the liveRegion
3012        label = ui.item.attr( "aria-label" ) || item.value;
3013        if ( label && $.trim( label ).length ) {
3014          this.liveRegion.children().hide();
3015          $( "<div>" ).text( label ).appendTo( this.liveRegion );
3016        }
3017      },
3018      menuselect: function( event, ui ) {
3019        var item = ui.item.data( "ui-autocomplete-item" ),
3020          previous = this.previous;
3021
3022        // only trigger when focus was lost (click on menu)
3023        if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
3024          this.element.focus();
3025          this.previous = previous;
3026          // #6109 - IE triggers two focus events and the second
3027          // is asynchronous, so we need to reset the previous
3028          // term synchronously and asynchronously :-(
3029          this._delay(function() {
3030            this.previous = previous;
3031            this.selectedItem = item;
3032          });
3033        }
3034
3035        if ( false !== this._trigger( "select", event, { item: item } ) ) {
3036          this._value( item.value );
3037        }
3038        // reset the term after the select event
3039        // this allows custom select handling to work properly
3040        this.term = this._value();
3041
3042        this.close( event );
3043        this.selectedItem = item;
3044      }
3045    });
3046
3047    this.liveRegion = $( "<span>", {
3048        role: "status",
3049        "aria-live": "assertive",
3050        "aria-relevant": "additions"
3051      })
3052      .addClass( "ui-helper-hidden-accessible" )
3053      .appendTo( this.document[ 0 ].body );
3054
3055    // turning off autocomplete prevents the browser from remembering the
3056    // value when navigating through history, so we re-enable autocomplete
3057    // if the page is unloaded before the widget is destroyed. #7790
3058    this._on( this.window, {
3059      beforeunload: function() {
3060        this.element.removeAttr( "autocomplete" );
3061      }
3062    });
3063  },
3064
3065  _destroy: function() {
3066    clearTimeout( this.searching );
3067    this.element
3068      .removeClass( "ui-autocomplete-input" )
3069      .removeAttr( "autocomplete" );
3070    this.menu.element.remove();
3071    this.liveRegion.remove();
3072  },
3073
3074  _setOption: function( key, value ) {
3075    this._super( key, value );
3076    if ( key === "source" ) {
3077      this._initSource();
3078    }
3079    if ( key === "appendTo" ) {
3080      this.menu.element.appendTo( this._appendTo() );
3081    }
3082    if ( key === "disabled" && value && this.xhr ) {
3083      this.xhr.abort();
3084    }
3085  },
3086
3087  _appendTo: function() {
3088    var element = this.options.appendTo;
3089
3090    if ( element ) {
3091      element = element.jquery || element.nodeType ?
3092        $( element ) :
3093        this.document.find( element ).eq( 0 );
3094    }
3095
3096    if ( !element || !element[ 0 ] ) {
3097      element = this.element.closest( ".ui-front" );
3098    }
3099
3100    if ( !element.length ) {
3101      element = this.document[ 0 ].body;
3102    }
3103
3104    return element;
3105  },
3106
3107  _initSource: function() {
3108    var array, url,
3109      that = this;
3110    if ( $.isArray( this.options.source ) ) {
3111      array = this.options.source;
3112      this.source = function( request, response ) {
3113        response( $.ui.autocomplete.filter( array, request.term ) );
3114      };
3115    } else if ( typeof this.options.source === "string" ) {
3116      url = this.options.source;
3117      this.source = function( request, response ) {
3118        if ( that.xhr ) {
3119          that.xhr.abort();
3120        }
3121        that.xhr = $.ajax({
3122          url: url,
3123          data: request,
3124          dataType: "json",
3125          success: function( data ) {
3126            response( data );
3127          },
3128          error: function() {
3129            response([]);
3130          }
3131        });
3132      };
3133    } else {
3134      this.source = this.options.source;
3135    }
3136  },
3137
3138  _searchTimeout: function( event ) {
3139    clearTimeout( this.searching );
3140    this.searching = this._delay(function() {
3141
3142      // Search if the value has changed, or if the user retypes the same value (see #7434)
3143      var equalValues = this.term === this._value(),
3144        menuVisible = this.menu.element.is( ":visible" ),
3145        modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3146
3147      if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3148        this.selectedItem = null;
3149        this.search( null, event );
3150      }
3151    }, this.options.delay );
3152  },
3153
3154  search: function( value, event ) {
3155    value = value != null ? value : this._value();
3156
3157    // always save the actual value, not the one passed as an argument
3158    this.term = this._value();
3159
3160    if ( value.length < this.options.minLength ) {
3161      return this.close( event );
3162    }
3163
3164    if ( this._trigger( "search", event ) === false ) {
3165      return;
3166    }
3167
3168    return this._search( value );
3169  },
3170
3171  _search: function( value ) {
3172    this.pending++;
3173    this.element.addClass( "ui-autocomplete-loading" );
3174    this.cancelSearch = false;
3175
3176    this.source( { term: value }, this._response() );
3177  },
3178
3179  _response: function() {
3180    var index = ++this.requestIndex;
3181
3182    return $.proxy(function( content ) {
3183      if ( index === this.requestIndex ) {
3184        this.__response( content );
3185      }
3186
3187      this.pending--;
3188      if ( !this.pending ) {
3189        this.element.removeClass( "ui-autocomplete-loading" );
3190      }
3191    }, this );
3192  },
3193
3194  __response: function( content ) {
3195    if ( content ) {
3196      content = this._normalize( content );
3197    }
3198    this._trigger( "response", null, { content: content } );
3199    if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3200      this._suggest( content );
3201      this._trigger( "open" );
3202    } else {
3203      // use ._close() instead of .close() so we don't cancel future searches
3204      this._close();
3205    }
3206  },
3207
3208  close: function( event ) {
3209    this.cancelSearch = true;
3210    this._close( event );
3211  },
3212
3213  _close: function( event ) {
3214    if ( this.menu.element.is( ":visible" ) ) {
3215      this.menu.element.hide();
3216      this.menu.blur();
3217      this.isNewMenu = true;
3218      this._trigger( "close", event );
3219    }
3220  },
3221
3222  _change: function( event ) {
3223    if ( this.previous !== this._value() ) {
3224      this._trigger( "change", event, { item: this.selectedItem } );
3225    }
3226  },
3227
3228  _normalize: function( items ) {
3229    // assume all items have the right format when the first item is complete
3230    if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3231      return items;
3232    }
3233    return $.map( items, function( item ) {
3234      if ( typeof item === "string" ) {
3235        return {
3236          label: item,
3237          value: item
3238        };
3239      }
3240      return $.extend( {}, item, {
3241        label: item.label || item.value,
3242        value: item.value || item.label
3243      });
3244    });
3245  },
3246
3247  _suggest: function( items ) {
3248    var ul = this.menu.element.empty();
3249    this._renderMenu( ul, items );
3250    this.isNewMenu = true;
3251    this.menu.refresh();
3252
3253    // size and position menu
3254    ul.show();
3255    this._resizeMenu();
3256    ul.position( $.extend({
3257      of: this.element
3258    }, this.options.position ) );
3259
3260    if ( this.options.autoFocus ) {
3261      this.menu.next();
3262    }
3263  },
3264
3265  _resizeMenu: function() {
3266    var ul = this.menu.element;
3267    ul.outerWidth( Math.max(
3268      // Firefox wraps long text (possibly a rounding bug)
3269      // so we add 1px to avoid the wrapping (#7513)
3270      ul.width( "" ).outerWidth() + 1,
3271      this.element.outerWidth()
3272    ) );
3273  },
3274
3275  _renderMenu: function( ul, items ) {
3276    var that = this;
3277    $.each( items, function( index, item ) {
3278      that._renderItemData( ul, item );
3279    });
3280  },
3281
3282  _renderItemData: function( ul, item ) {
3283    return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3284  },
3285
3286  _renderItem: function( ul, item ) {
3287    return $( "<li>" ).text( item.label ).appendTo( ul );
3288  },
3289
3290  _move: function( direction, event ) {
3291    if ( !this.menu.element.is( ":visible" ) ) {
3292      this.search( null, event );
3293      return;
3294    }
3295    if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3296        this.menu.isLastItem() && /^next/.test( direction ) ) {
3297
3298      if ( !this.isMultiLine ) {
3299        this._value( this.term );
3300      }
3301
3302      this.menu.blur();
3303      return;
3304    }
3305    this.menu[ direction ]( event );
3306  },
3307
3308  widget: function() {
3309    return this.menu.element;
3310  },
3311
3312  _value: function() {
3313    return this.valueMethod.apply( this.element, arguments );
3314  },
3315
3316  _keyEvent: function( keyEvent, event ) {
3317    if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3318      this._move( keyEvent, event );
3319
3320      // prevents moving cursor to beginning/end of the text field in some browsers
3321      event.preventDefault();
3322    }
3323  }
3324});
3325
3326$.extend( $.ui.autocomplete, {
3327  escapeRegex: function( value ) {
3328    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3329  },
3330  filter: function( array, term ) {
3331    var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3332    return $.grep( array, function( value ) {
3333      return matcher.test( value.label || value.value || value );
3334    });
3335  }
3336});
3337
3338// live region extension, adding a `messages` option
3339// NOTE: This is an experimental API. We are still investigating
3340// a full solution for string manipulation and internationalization.
3341$.widget( "ui.autocomplete", $.ui.autocomplete, {
3342  options: {
3343    messages: {
3344      noResults: "No search results.",
3345      results: function( amount ) {
3346        return amount + ( amount > 1 ? " results are" : " result is" ) +
3347          " available, use up and down arrow keys to navigate.";
3348      }
3349    }
3350  },
3351
3352  __response: function( content ) {
3353    var message;
3354    this._superApply( arguments );
3355    if ( this.options.disabled || this.cancelSearch ) {
3356      return;
3357    }
3358    if ( content && content.length ) {
3359      message = this.options.messages.results( content.length );
3360    } else {
3361      message = this.options.messages.noResults;
3362    }
3363    this.liveRegion.children().hide();
3364    $( "<div>" ).text( message ).appendTo( this.liveRegion );
3365  }
3366});
3367
3368var autocomplete = $.ui.autocomplete;
3369
3370
3371/*!
3372 * jQuery UI Button 1.11.4
3373 * http://jqueryui.com
3374 *
3375 * Copyright jQuery Foundation and other contributors
3376 * Released under the MIT license.
3377 * http://jquery.org/license
3378 *
3379 * http://api.jqueryui.com/button/
3380 */
3381
3382
3383var lastActive,
3384  baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3385  typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
3386  formResetHandler = function() {
3387    var form = $( this );
3388    setTimeout(function() {
3389      form.find( ":ui-button" ).button( "refresh" );
3390    }, 1 );
3391  },
3392  radioGroup = function( radio ) {
3393    var name = radio.name,
3394      form = radio.form,
3395      radios = $( [] );
3396    if ( name ) {
3397      name = name.replace( /'/g, "\\'" );
3398      if ( form ) {
3399        radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3400      } else {
3401        radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3402          .filter(function() {
3403            return !this.form;
3404          });
3405      }
3406    }
3407    return radios;
3408  };
3409
3410$.widget( "ui.button", {
3411  version: "1.11.4",
3412  defaultElement: "<button>",
3413  options: {
3414    disabled: null,
3415    text: true,
3416    label: null,
3417    icons: {
3418      primary: null,
3419      secondary: null
3420    }
3421  },
3422  _create: function() {
3423    this.element.closest( "form" )
3424      .unbind( "reset" + this.eventNamespace )
3425      .bind( "reset" + this.eventNamespace, formResetHandler );
3426
3427    if ( typeof this.options.disabled !== "boolean" ) {
3428      this.options.disabled = !!this.element.prop( "disabled" );
3429    } else {
3430      this.element.prop( "disabled", this.options.disabled );
3431    }
3432
3433    this._determineButtonType();
3434    this.hasTitle = !!this.buttonElement.attr( "title" );
3435
3436    var that = this,
3437      options = this.options,
3438      toggleButton = this.type === "checkbox" || this.type === "radio",
3439      activeClass = !toggleButton ? "ui-state-active" : "";
3440
3441    if ( options.label === null ) {
3442      options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3443    }
3444
3445    this._hoverable( this.buttonElement );
3446
3447    this.buttonElement
3448      .addClass( baseClasses )
3449      .attr( "role", "button" )
3450      .bind( "mouseenter" + this.eventNamespace, function() {
3451        if ( options.disabled ) {
3452          return;
3453        }
3454        if ( this === lastActive ) {
3455          $( this ).addClass( "ui-state-active" );
3456        }
3457      })
3458      .bind( "mouseleave" + this.eventNamespace, function() {
3459        if ( options.disabled ) {
3460          return;
3461        }
3462        $( this ).removeClass( activeClass );
3463      })
3464      .bind( "click" + this.eventNamespace, function( event ) {
3465        if ( options.disabled ) {
3466          event.preventDefault();
3467          event.stopImmediatePropagation();
3468        }
3469      });
3470
3471    // Can't use _focusable() because the element that receives focus
3472    // and the element that gets the ui-state-focus class are different
3473    this._on({
3474      focus: function() {
3475        this.buttonElement.addClass( "ui-state-focus" );
3476      },
3477      blur: function() {
3478        this.buttonElement.removeClass( "ui-state-focus" );
3479      }
3480    });
3481
3482    if ( toggleButton ) {
3483      this.element.bind( "change" + this.eventNamespace, function() {
3484        that.refresh();
3485      });
3486    }
3487
3488    if ( this.type === "checkbox" ) {
3489      this.buttonElement.bind( "click" + this.eventNamespace, function() {
3490        if ( options.disabled ) {
3491          return false;
3492        }
3493      });
3494    } else if ( this.type === "radio" ) {
3495      this.buttonElement.bind( "click" + this.eventNamespace, function() {
3496        if ( options.disabled ) {
3497          return false;
3498        }
3499        $( this ).addClass( "ui-state-active" );
3500        that.buttonElement.attr( "aria-pressed", "true" );
3501
3502        var radio = that.element[ 0 ];
3503        radioGroup( radio )
3504          .not( radio )
3505          .map(function() {
3506            return $( this ).button( "widget" )[ 0 ];
3507          })
3508          .removeClass( "ui-state-active" )
3509          .attr( "aria-pressed", "false" );
3510      });
3511    } else {
3512      this.buttonElement
3513        .bind( "mousedown" + this.eventNamespace, function() {
3514          if ( options.disabled ) {
3515            return false;
3516          }
3517          $( this ).addClass( "ui-state-active" );
3518          lastActive = this;
3519          that.document.one( "mouseup", function() {
3520            lastActive = null;
3521          });
3522        })
3523        .bind( "mouseup" + this.eventNamespace, function() {
3524          if ( options.disabled ) {
3525            return false;
3526          }
3527          $( this ).removeClass( "ui-state-active" );
3528        })
3529        .bind( "keydown" + this.eventNamespace, function(event) {
3530          if ( options.disabled ) {
3531            return false;
3532          }
3533          if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3534            $( this ).addClass( "ui-state-active" );
3535          }
3536        })
3537        // see #8559, we bind to blur here in case the button element loses
3538        // focus between keydown and keyup, it would be left in an "active" state
3539        .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3540          $( this ).removeClass( "ui-state-active" );
3541        });
3542
3543      if ( this.buttonElement.is("a") ) {
3544        this.buttonElement.keyup(function(event) {
3545          if ( event.keyCode === $.ui.keyCode.SPACE ) {
3546            // TODO pass through original event correctly (just as 2nd argument doesn't work)
3547            $( this ).click();
3548          }
3549        });
3550      }
3551    }
3552
3553    this._setOption( "disabled", options.disabled );
3554    this._resetButton();
3555  },
3556
3557  _determineButtonType: function() {
3558    var ancestor, labelSelector, checked;
3559
3560    if ( this.element.is("[type=checkbox]") ) {
3561      this.type = "checkbox";
3562    } else if ( this.element.is("[type=radio]") ) {
3563      this.type = "radio";
3564    } else if ( this.element.is("input") ) {
3565      this.type = "input";
3566    } else {
3567      this.type = "button";
3568    }
3569
3570    if ( this.type === "checkbox" || this.type === "radio" ) {
3571      // we don't search against the document in case the element
3572      // is disconnected from the DOM
3573      ancestor = this.element.parents().last();
3574      labelSelector = "label[for='" + this.element.attr("id") + "']";
3575      this.buttonElement = ancestor.find( labelSelector );
3576      if ( !this.buttonElement.length ) {
3577        ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3578        this.buttonElement = ancestor.filter( labelSelector );
3579        if ( !this.buttonElement.length ) {
3580          this.buttonElement = ancestor.find( labelSelector );
3581        }
3582      }
3583      this.element.addClass( "ui-helper-hidden-accessible" );
3584
3585      checked = this.element.is( ":checked" );
3586      if ( checked ) {
3587        this.buttonElement.addClass( "ui-state-active" );
3588      }
3589      this.buttonElement.prop( "aria-pressed", checked );
3590    } else {
3591      this.buttonElement = this.element;
3592    }
3593  },
3594
3595  widget: function() {
3596    return this.buttonElement;
3597  },
3598
3599  _destroy: function() {
3600    this.element
3601      .removeClass( "ui-helper-hidden-accessible" );
3602    this.buttonElement
3603      .removeClass( baseClasses + " ui-state-active " + typeClasses )
3604      .removeAttr( "role" )
3605      .removeAttr( "aria-pressed" )
3606      .html( this.buttonElement.find(".ui-button-text").html() );
3607
3608    if ( !this.hasTitle ) {
3609      this.buttonElement.removeAttr( "title" );
3610    }
3611  },
3612
3613  _setOption: function( key, value ) {
3614    this._super( key, value );
3615    if ( key === "disabled" ) {
3616      this.widget().toggleClass( "ui-state-disabled", !!value );
3617      this.element.prop( "disabled", !!value );
3618      if ( value ) {
3619        if ( this.type === "checkbox" || this.type === "radio" ) {
3620          this.buttonElement.removeClass( "ui-state-focus" );
3621        } else {
3622          this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3623        }
3624      }
3625      return;
3626    }
3627    this._resetButton();
3628  },
3629
3630  refresh: function() {
3631    //See #8237 & #8828
3632    var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3633
3634    if ( isDisabled !== this.options.disabled ) {
3635      this._setOption( "disabled", isDisabled );
3636    }
3637    if ( this.type === "radio" ) {
3638      radioGroup( this.element[0] ).each(function() {
3639        if ( $( this ).is( ":checked" ) ) {
3640          $( this ).button( "widget" )
3641            .addClass( "ui-state-active" )
3642            .attr( "aria-pressed", "true" );
3643        } else {
3644          $( this ).button( "widget" )
3645            .removeClass( "ui-state-active" )
3646            .attr( "aria-pressed", "false" );
3647        }
3648      });
3649    } else if ( this.type === "checkbox" ) {
3650      if ( this.element.is( ":checked" ) ) {
3651        this.buttonElement
3652          .addClass( "ui-state-active" )
3653          .attr( "aria-pressed", "true" );
3654      } else {
3655        this.buttonElement
3656          .removeClass( "ui-state-active" )
3657          .attr( "aria-pressed", "false" );
3658      }
3659    }
3660  },
3661
3662  _resetButton: function() {
3663    if ( this.type === "input" ) {
3664      if ( this.options.label ) {
3665        this.element.val( this.options.label );
3666      }
3667      return;
3668    }
3669    var buttonElement = this.buttonElement.removeClass( typeClasses ),
3670      buttonText = $( "<span></span>", this.document[0] )
3671        .addClass( "ui-button-text" )
3672        .html( this.options.label )
3673        .appendTo( buttonElement.empty() )
3674        .text(),
3675      icons = this.options.icons,
3676      multipleIcons = icons.primary && icons.secondary,
3677      buttonClasses = [];
3678
3679    if ( icons.primary || icons.secondary ) {
3680      if ( this.options.text ) {
3681        buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3682      }
3683
3684      if ( icons.primary ) {
3685        buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3686      }
3687
3688      if ( icons.secondary ) {
3689        buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3690      }
3691
3692      if ( !this.options.text ) {
3693        buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3694
3695        if ( !this.hasTitle ) {
3696          buttonElement.attr( "title", $.trim( buttonText ) );
3697        }
3698      }
3699    } else {
3700      buttonClasses.push( "ui-button-text-only" );
3701    }
3702    buttonElement.addClass( buttonClasses.join( " " ) );
3703  }
3704});
3705
3706$.widget( "ui.buttonset", {
3707  version: "1.11.4",
3708  options: {
3709    items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3710  },
3711
3712  _create: function() {
3713    this.element.addClass( "ui-buttonset" );
3714  },
3715
3716  _init: function() {
3717    this.refresh();
3718  },
3719
3720  _setOption: function( key, value ) {
3721    if ( key === "disabled" ) {
3722      this.buttons.button( "option", key, value );
3723    }
3724
3725    this._super( key, value );
3726  },
3727
3728  refresh: function() {
3729    var rtl = this.element.css( "direction" ) === "rtl",
3730      allButtons = this.element.find( this.options.items ),
3731      existingButtons = allButtons.filter( ":ui-button" );
3732
3733    // Initialize new buttons
3734    allButtons.not( ":ui-button" ).button();
3735
3736    // Refresh existing buttons
3737    existingButtons.button( "refresh" );
3738
3739    this.buttons = allButtons
3740      .map(function() {
3741        return $( this ).button( "widget" )[ 0 ];
3742      })
3743        .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3744        .filter( ":first" )
3745          .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3746        .end()
3747        .filter( ":last" )
3748          .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3749        .end()
3750      .end();
3751  },
3752
3753  _destroy: function() {
3754    this.element.removeClass( "ui-buttonset" );
3755    this.buttons
3756      .map(function() {
3757        return $( this ).button( "widget" )[ 0 ];
3758      })
3759        .removeClass( "ui-corner-left ui-corner-right" )
3760      .end()
3761      .button( "destroy" );
3762  }
3763});
3764
3765var button = $.ui.button;
3766
3767
3768/*!
3769 * jQuery UI Datepicker 1.11.4
3770 * http://jqueryui.com
3771 *
3772 * Copyright jQuery Foundation and other contributors
3773 * Released under the MIT license.
3774 * http://jquery.org/license
3775 *
3776 * http://api.jqueryui.com/datepicker/
3777 */
3778
3779
3780$.extend($.ui, { datepicker: { version: "1.11.4" } });
3781
3782var datepicker_instActive;
3783
3784function datepicker_getZindex( elem ) {
3785  var position, value;
3786  while ( elem.length && elem[ 0 ] !== document ) {
3787    // Ignore z-index if position is set to a value where z-index is ignored by the browser
3788    // This makes behavior of this function consistent across browsers
3789    // WebKit always returns auto if the element is positioned
3790    position = elem.css( "position" );
3791    if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3792      // IE returns 0 when zIndex is not specified
3793      // other browsers return a string
3794      // we ignore the case of nested elements with an explicit value of 0
3795      // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3796      value = parseInt( elem.css( "zIndex" ), 10 );
3797      if ( !isNaN( value ) && value !== 0 ) {
3798        return value;
3799      }
3800    }
3801    elem = elem.parent();
3802  }
3803
3804  return 0;
3805}
3806/* Date picker manager.
3807   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3808   Settings for (groups of) date pickers are maintained in an instance object,
3809   allowing multiple different settings on the same page. */
3810
3811function Datepicker() {
3812  this._curInst = null; // The current instance in use
3813  this._keyEvent = false; // If the last event was a key event
3814  this._disabledInputs = []; // List of date picker inputs that have been disabled
3815  this._datepickerShowing = false; // True if the popup picker is showing , false if not
3816  this._inDialog = false; // True if showing within a "dialog", false if not
3817  this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3818  this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3819  this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3820  this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3821  this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3822  this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3823  this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3824  this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3825  this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3826  this.regional = []; // Available regional settings, indexed by language code
3827  this.regional[""] = { // Default regional settings
3828    closeText: "Done", // Display text for close link
3829    prevText: "Prev", // Display text for previous month link
3830    nextText: "Next", // Display text for next month link
3831    currentText: "Today", // Display text for current month link
3832    monthNames: ["January","February","March","April","May","June",
3833      "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3834    monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3835    dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3836    dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3837    dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3838    weekHeader: "Wk", // Column header for week of the year
3839    dateFormat: "mm/dd/yy", // See format options on parseDate
3840    firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3841    isRTL: false, // True if right-to-left language, false if left-to-right
3842    showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3843    yearSuffix: "" // Additional text to append to the year in the month headers
3844  };
3845  this._defaults = { // Global defaults for all the date picker instances
3846    showOn: "focus", // "focus" for popup on focus,
3847      // "button" for trigger button, or "both" for either
vendor: 6,085 bytes, lines 3848-3956
3848    showAnim: "fadeIn", // Name of jQuery animation for popup
3849    showOptions: {}, // Options for enhanced animations
3850    defaultDate: null, // Used when field is blank: actual date,
3851      // +/-number for offset from today, null for today
3852    appendText: "", // Display text following the input box, e.g. showing the format
3853    buttonText: "...", // Text for trigger button
3854    buttonImage: "", // URL for trigger button image
3855    buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3856    hideIfNoPrevNext: false, // True to hide next/previous month links
3857      // if not applicable, false to just disable them
3858    navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3859    gotoCurrent: false, // True if today link goes back to current selection instead
3860    changeMonth: false, // True if month can be selected directly, false if only prev/next
3861    changeYear: false, // True if year can be selected directly, false if only prev/next
3862    yearRange: "c-10:c+10", // Range of years to display in drop-down,
3863      // either relative to today's year (-nn:+nn), relative to currently displayed year
3864      // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3865    showOtherMonths: false, // True to show dates in other months, false to leave blank
3866    selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3867    showWeek: false, // True to show week of the year, false to not show it
3868    calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3869      // takes a Date and returns the number of the week for it
3870    shortYearCutoff: "+10", // Short year values < this are in the current century,
3871      // > this are in the previous century,
3872      // string value starting with "+" for current year + value
3873    minDate: null, // The earliest selectable date, or null for no limit
3874    maxDate: null, // The latest selectable date, or null for no limit
3875    duration: "fast", // Duration of display/closure
3876    beforeShowDay: null, // Function that takes a date and returns an array with
3877      // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3878      // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3879    beforeShow: null, // Function that takes an input field and
3880      // returns a set of custom settings for the date picker
3881    onSelect: null, // Define a callback function when a date is selected
3882    onChangeMonthYear: null, // Define a callback function when the month or year is changed
3883    onClose: null, // Define a callback function when the datepicker is closed
3884    numberOfMonths: 1, // Number of months to show at a time
3885    showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3886    stepMonths: 1, // Number of months to step back/forward
3887    stepBigMonths: 12, // Number of months to step back/forward for the big links
3888    altField: "", // Selector for an alternate field to store selected dates into
3889    altFormat: "", // The date format to use for the alternate field
3890    constrainInput: true, // The input is constrained by the current date format
3891    showButtonPanel: false, // True to show button panel, false to not show it
3892    autoSize: false, // True to size the input for the date format, false to leave as is
3893    disabled: false // The initial disabled state
3894  };
3895  $.extend(this._defaults, this.regional[""]);
3896  this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3897  this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3898  this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3899}
3900
3901$.extend(Datepicker.prototype, {
3902  /* Class name added to elements to indicate already configured with a date picker. */
3903  markerClassName: "hasDatepicker",
3904
3905  //Keep track of the maximum number of rows displayed (see #7043)
3906  maxRows: 4,
3907
3908  // TODO rename to "widget" when switching to widget factory
3909  _widgetDatepicker: function() {
3910    return this.dpDiv;
3911  },
3912
3913  /* Override the default settings for all instances of the date picker.
3914   * @param  settings  object - the new settings to use as defaults (anonymous object)
3915   * @return the manager object
3916   */
3917  setDefaults: function(settings) {
3918    datepicker_extendRemove(this._defaults, settings || {});
3919    return this;
3920  },
3921
3922  /* Attach the date picker to a jQuery selection.
3923   * @param  target  element - the target input field or division or span
3924   * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3925   */
3926  _attachDatepicker: function(target, settings) {
3927    var nodeName, inline, inst;
3928    nodeName = target.nodeName.toLowerCase();
3929    inline = (nodeName === "div" || nodeName === "span");
3930    if (!target.id) {
3931      this.uuid += 1;
3932      target.id = "dp" + this.uuid;
3933    }
3934    inst = this._newInst($(target), inline);
3935    inst.settings = $.extend({}, settings || {});
3936    if (nodeName === "input") {
3937      this._connectDatepicker(target, inst);
3938    } else if (inline) {
3939      this._inlineDatepicker(target, inst);
3940    }
3941  },
3942
3943  /* Create a new instance object. */
3944  _newInst: function(target, inline) {
3945    var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3946    return {id: id, input: target, // associated target
3947      selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3948      drawMonth: 0, drawYear: 0, // month being drawn
3949      inline: inline, // is datepicker inline or not
3950      dpDiv: (!inline ? this.dpDiv : // presentation div
3951      datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3952  },
3953
3954  /* Attach the date picker to an input field. */
3955  _connectDatepicker: function(target, inst) {
3956    var input = $(target);
vendor: 4,065 bytes, lines 3957-4063
3957    inst.append = $([]);
3958    inst.trigger = $([]);
3959    if (input.hasClass(this.markerClassName)) {
3960      return;
3961    }
3962    this._attachments(input, inst);
3963    input.addClass(this.markerClassName).keydown(this._doKeyDown).
3964      keypress(this._doKeyPress).keyup(this._doKeyUp);
3965    this._autoSize(inst);
3966    $.data(target, "datepicker", inst);
3967    //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3968    if( inst.settings.disabled ) {
3969      this._disableDatepicker( target );
3970    }
3971  },
3972
3973  /* Make attachments based on settings. */
3974  _attachments: function(input, inst) {
3975    var showOn, buttonText, buttonImage,
3976      appendText = this._get(inst, "appendText"),
3977      isRTL = this._get(inst, "isRTL");
3978
3979    if (inst.append) {
3980      inst.append.remove();
3981    }
3982    if (appendText) {
3983      inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3984      input[isRTL ? "before" : "after"](inst.append);
3985    }
3986
3987    input.unbind("focus", this._showDatepicker);
3988
3989    if (inst.trigger) {
3990      inst.trigger.remove();
3991    }
3992
3993    showOn = this._get(inst, "showOn");
3994    if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3995      input.focus(this._showDatepicker);
3996    }
3997    if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3998      buttonText = this._get(inst, "buttonText");
3999      buttonImage = this._get(inst, "buttonImage");
4000      inst.trigger = $(this._get(inst, "buttonImageOnly") ?
4001        $("<img/>").addClass(this._triggerClass).
4002          attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
4003        $("<button type='button'></button>").addClass(this._triggerClass).
4004          html(!buttonImage ? buttonText : $("<img/>").attr(
4005          { src:buttonImage, alt:buttonText, title:buttonText })));
4006      input[isRTL ? "before" : "after"](inst.trigger);
4007      inst.trigger.click(function() {
4008        if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
4009          $.datepicker._hideDatepicker();
4010        } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
4011          $.datepicker._hideDatepicker();
4012          $.datepicker._showDatepicker(input[0]);
4013        } else {
4014          $.datepicker._showDatepicker(input[0]);
4015        }
4016        return false;
4017      });
4018    }
4019  },
4020
4021  /* Apply the maximum length for the date format. */
4022  _autoSize: function(inst) {
4023    if (this._get(inst, "autoSize") && !inst.inline) {
4024      var findMax, max, maxI, i,
4025        date = new Date(2009, 12 - 1, 20), // Ensure double digits
4026        dateFormat = this._get(inst, "dateFormat");
4027
4028      if (dateFormat.match(/[DM]/)) {
4029        findMax = function(names) {
4030          max = 0;
4031          maxI = 0;
4032          for (i = 0; i < names.length; i++) {
4033            if (names[i].length > max) {
4034              max = names[i].length;
4035              maxI = i;
4036            }
4037          }
4038          return maxI;
4039        };
4040        date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4041          "monthNames" : "monthNamesShort"))));
4042        date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4043          "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4044      }
4045      inst.input.attr("size", this._formatDate(inst, date).length);
4046    }
4047  },
4048
4049  /* Attach an inline date picker to a div. */
4050  _inlineDatepicker: function(target, inst) {
4051    var divSpan = $(target);
4052    if (divSpan.hasClass(this.markerClassName)) {
4053      return;
4054    }
4055    divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4056    $.data(target, "datepicker", inst);
4057    this._setDate(inst, this._getDefaultDate(inst), true);
4058    this._updateDatepicker(inst);
4059    this._updateAlternate(inst);
4060    //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4061    if( inst.settings.disabled ) {
4062      this._disableDatepicker( target );
4063    }
vendor: 6,966 bytes, lines 4064-4241
4064    // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4065    // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4066    inst.dpDiv.css( "display", "block" );
4067  },
4068
4069  /* Pop-up the date picker in a "dialog" box.
4070   * @param  input element - ignored
4071   * @param  date  string or Date - the initial date to display
4072   * @param  onSelect  function - the function to call when a date is selected
4073   * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4074   * @param  pos int[2] - coordinates for the dialog's position within the screen or
4075   *          event - with x/y coordinates or
4076   *          leave empty for default (screen centre)
4077   * @return the manager object
4078   */
4079  _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4080    var id, browserWidth, browserHeight, scrollX, scrollY,
4081      inst = this._dialogInst; // internal instance
4082
4083    if (!inst) {
4084      this.uuid += 1;
4085      id = "dp" + this.uuid;
4086      this._dialogInput = $("<input type='text' id='" + id +
4087        "' style='position: absolute; top: -100px; width: 0px;'/>");
4088      this._dialogInput.keydown(this._doKeyDown);
4089      $("body").append(this._dialogInput);
4090      inst = this._dialogInst = this._newInst(this._dialogInput, false);
4091      inst.settings = {};
4092      $.data(this._dialogInput[0], "datepicker", inst);
4093    }
4094    datepicker_extendRemove(inst.settings, settings || {});
4095    date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4096    this._dialogInput.val(date);
4097
4098    this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4099    if (!this._pos) {
4100      browserWidth = document.documentElement.clientWidth;
4101      browserHeight = document.documentElement.clientHeight;
4102      scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4103      scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4104      this._pos = // should use actual width/height below
4105        [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4106    }
4107
4108    // move input on screen for focus, but hidden behind dialog
4109    this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4110    inst.settings.onSelect = onSelect;
4111    this._inDialog = true;
4112    this.dpDiv.addClass(this._dialogClass);
4113    this._showDatepicker(this._dialogInput[0]);
4114    if ($.blockUI) {
4115      $.blockUI(this.dpDiv);
4116    }
4117    $.data(this._dialogInput[0], "datepicker", inst);
4118    return this;
4119  },
4120
4121  /* Detach a datepicker from its control.
4122   * @param  target  element - the target input field or division or span
4123   */
4124  _destroyDatepicker: function(target) {
4125    var nodeName,
4126      $target = $(target),
4127      inst = $.data(target, "datepicker");
4128
4129    if (!$target.hasClass(this.markerClassName)) {
4130      return;
4131    }
4132
4133    nodeName = target.nodeName.toLowerCase();
4134    $.removeData(target, "datepicker");
4135    if (nodeName === "input") {
4136      inst.append.remove();
4137      inst.trigger.remove();
4138      $target.removeClass(this.markerClassName).
4139        unbind("focus", this._showDatepicker).
4140        unbind("keydown", this._doKeyDown).
4141        unbind("keypress", this._doKeyPress).
4142        unbind("keyup", this._doKeyUp);
4143    } else if (nodeName === "div" || nodeName === "span") {
4144      $target.removeClass(this.markerClassName).empty();
4145    }
4146
4147    if ( datepicker_instActive === inst ) {
4148      datepicker_instActive = null;
4149    }
4150  },
4151
4152  /* Enable the date picker to a jQuery selection.
4153   * @param  target  element - the target input field or division or span
4154   */
4155  _enableDatepicker: function(target) {
4156    var nodeName, inline,
4157      $target = $(target),
4158      inst = $.data(target, "datepicker");
4159
4160    if (!$target.hasClass(this.markerClassName)) {
4161      return;
4162    }
4163
4164    nodeName = target.nodeName.toLowerCase();
4165    if (nodeName === "input") {
4166      target.disabled = false;
4167      inst.trigger.filter("button").
4168        each(function() { this.disabled = false; }).end().
4169        filter("img").css({opacity: "1.0", cursor: ""});
4170    } else if (nodeName === "div" || nodeName === "span") {
4171      inline = $target.children("." + this._inlineClass);
4172      inline.children().removeClass("ui-state-disabled");
4173      inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4174        prop("disabled", false);
4175    }
4176    this._disabledInputs = $.map(this._disabledInputs,
4177      function(value) { return (value === target ? null : value); }); // delete entry
4178  },
4179
4180  /* Disable the date picker to a jQuery selection.
4181   * @param  target  element - the target input field or division or span
4182   */
4183  _disableDatepicker: function(target) {
4184    var nodeName, inline,
4185      $target = $(target),
4186      inst = $.data(target, "datepicker");
4187
4188    if (!$target.hasClass(this.markerClassName)) {
4189      return;
4190    }
4191
4192    nodeName = target.nodeName.toLowerCase();
4193    if (nodeName === "input") {
4194      target.disabled = true;
4195      inst.trigger.filter("button").
4196        each(function() { this.disabled = true; }).end().
4197        filter("img").css({opacity: "0.5", cursor: "default"});
4198    } else if (nodeName === "div" || nodeName === "span") {
4199      inline = $target.children("." + this._inlineClass);
4200      inline.children().addClass("ui-state-disabled");
4201      inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4202        prop("disabled", true);
4203    }
4204    this._disabledInputs = $.map(this._disabledInputs,
4205      function(value) { return (value === target ? null : value); }); // delete entry
4206    this._disabledInputs[this._disabledInputs.length] = target;
4207  },
4208
4209  /* Is the first field in a jQuery collection disabled as a datepicker?
4210   * @param  target  element - the target input field or division or span
4211   * @return boolean - true if disabled, false if enabled
4212   */
4213  _isDisabledDatepicker: function(target) {
4214    if (!target) {
4215      return false;
4216    }
4217    for (var i = 0; i < this._disabledInputs.length; i++) {
4218      if (this._disabledInputs[i] === target) {
4219        return true;
4220      }
4221    }
4222    return false;
4223  },
4224
4225  /* Retrieve the instance data for the target control.
4226   * @param  target  element - the target input field or division or span
4227   * @return  object - the associated instance data
4228   * @throws  error if a jQuery problem getting data
4229   */
4230  _getInst: function(target) {
4231    try {
4232      return $.data(target, "datepicker");
4233    }
4234    catch (err) {
4235      throw "Missing instance data for this datepicker";
4236    }
4237  },
4238
4239  /* Update or retrieve the settings for a date picker attached to an input field or division.
4240   * @param  target  element - the target input field or division or span
4241   * @param  name  object - the new settings to update or
vendor: 8,237 bytes, lines 4242-4451
4242   *        string - the name of the setting to change or retrieve,
4243   *        when retrieving also "all" for all instance settings or
4244   *        "defaults" for all global defaults
4245   * @param  value   any - the new value for the setting
4246   *        (omit if above is an object or to retrieve a value)
4247   */
4248  _optionDatepicker: function(target, name, value) {
4249    var settings, date, minDate, maxDate,
4250      inst = this._getInst(target);
4251
4252    if (arguments.length === 2 && typeof name === "string") {
4253      return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4254        (inst ? (name === "all" ? $.extend({}, inst.settings) :
4255        this._get(inst, name)) : null));
4256    }
4257
4258    settings = name || {};
4259    if (typeof name === "string") {
4260      settings = {};
4261      settings[name] = value;
4262    }
4263
4264    if (inst) {
4265      if (this._curInst === inst) {
4266        this._hideDatepicker();
4267      }
4268
4269      date = this._getDateDatepicker(target, true);
4270      minDate = this._getMinMaxDate(inst, "min");
4271      maxDate = this._getMinMaxDate(inst, "max");
4272      datepicker_extendRemove(inst.settings, settings);
4273      // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4274      if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4275        inst.settings.minDate = this._formatDate(inst, minDate);
4276      }
4277      if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4278        inst.settings.maxDate = this._formatDate(inst, maxDate);
4279      }
4280      if ( "disabled" in settings ) {
4281        if ( settings.disabled ) {
4282          this._disableDatepicker(target);
4283        } else {
4284          this._enableDatepicker(target);
4285        }
4286      }
4287      this._attachments($(target), inst);
4288      this._autoSize(inst);
4289      this._setDate(inst, date);
4290      this._updateAlternate(inst);
4291      this._updateDatepicker(inst);
4292    }
4293  },
4294
4295  // change method deprecated
4296  _changeDatepicker: function(target, name, value) {
4297    this._optionDatepicker(target, name, value);
4298  },
4299
4300  /* Redraw the date picker attached to an input field or division.
4301   * @param  target  element - the target input field or division or span
4302   */
4303  _refreshDatepicker: function(target) {
4304    var inst = this._getInst(target);
4305    if (inst) {
4306      this._updateDatepicker(inst);
4307    }
4308  },
4309
4310  /* Set the dates for a jQuery selection.
4311   * @param  target element - the target input field or division or span
4312   * @param  date  Date - the new date
4313   */
4314  _setDateDatepicker: function(target, date) {
4315    var inst = this._getInst(target);
4316    if (inst) {
4317      this._setDate(inst, date);
4318      this._updateDatepicker(inst);
4319      this._updateAlternate(inst);
4320    }
4321  },
4322
4323  /* Get the date(s) for the first entry in a jQuery selection.
4324   * @param  target element - the target input field or division or span
4325   * @param  noDefault boolean - true if no default date is to be used
4326   * @return Date - the current date
4327   */
4328  _getDateDatepicker: function(target, noDefault) {
4329    var inst = this._getInst(target);
4330    if (inst && !inst.inline) {
4331      this._setDateFromField(inst, noDefault);
4332    }
4333    return (inst ? this._getDate(inst) : null);
4334  },
4335
4336  /* Handle keystrokes. */
4337  _doKeyDown: function(event) {
4338    var onSelect, dateStr, sel,
4339      inst = $.datepicker._getInst(event.target),
4340      handled = true,
4341      isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4342
4343    inst._keyEvent = true;
4344    if ($.datepicker._datepickerShowing) {
4345      switch (event.keyCode) {
4346        case 9: $.datepicker._hideDatepicker();
4347            handled = false;
4348            break; // hide on tab out
4349        case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4350                  $.datepicker._currentClass + ")", inst.dpDiv);
4351            if (sel[0]) {
4352              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4353            }
4354
4355            onSelect = $.datepicker._get(inst, "onSelect");
4356            if (onSelect) {
4357              dateStr = $.datepicker._formatDate(inst);
4358
4359              // trigger custom callback
4360              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4361            } else {
4362              $.datepicker._hideDatepicker();
4363            }
4364
4365            return false; // don't submit the form
4366        case 27: $.datepicker._hideDatepicker();
4367            break; // hide on escape
4368        case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4369              -$.datepicker._get(inst, "stepBigMonths") :
4370              -$.datepicker._get(inst, "stepMonths")), "M");
4371            break; // previous month/year on page up/+ ctrl
4372        case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4373              +$.datepicker._get(inst, "stepBigMonths") :
4374              +$.datepicker._get(inst, "stepMonths")), "M");
4375            break; // next month/year on page down/+ ctrl
4376        case 35: if (event.ctrlKey || event.metaKey) {
4377              $.datepicker._clearDate(event.target);
4378            }
4379            handled = event.ctrlKey || event.metaKey;
4380            break; // clear on ctrl or command +end
4381        case 36: if (event.ctrlKey || event.metaKey) {
4382              $.datepicker._gotoToday(event.target);
4383            }
4384            handled = event.ctrlKey || event.metaKey;
4385            break; // current on ctrl or command +home
4386        case 37: if (event.ctrlKey || event.metaKey) {
4387              $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4388            }
4389            handled = event.ctrlKey || event.metaKey;
4390            // -1 day on ctrl or command +left
4391            if (event.originalEvent.altKey) {
4392              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4393                -$.datepicker._get(inst, "stepBigMonths") :
4394                -$.datepicker._get(inst, "stepMonths")), "M");
4395            }
4396            // next month/year on alt +left on Mac
4397            break;
4398        case 38: if (event.ctrlKey || event.metaKey) {
4399              $.datepicker._adjustDate(event.target, -7, "D");
4400            }
4401            handled = event.ctrlKey || event.metaKey;
4402            break; // -1 week on ctrl or command +up
4403        case 39: if (event.ctrlKey || event.metaKey) {
4404              $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4405            }
4406            handled = event.ctrlKey || event.metaKey;
4407            // +1 day on ctrl or command +right
4408            if (event.originalEvent.altKey) {
4409              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4410                +$.datepicker._get(inst, "stepBigMonths") :
4411                +$.datepicker._get(inst, "stepMonths")), "M");
4412            }
4413            // next month/year on alt +right
4414            break;
4415        case 40: if (event.ctrlKey || event.metaKey) {
4416              $.datepicker._adjustDate(event.target, +7, "D");
4417            }
4418            handled = event.ctrlKey || event.metaKey;
4419            break; // +1 week on ctrl or command +down
4420        default: handled = false;
4421      }
4422    } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4423      $.datepicker._showDatepicker(this);
4424    } else {
4425      handled = false;
4426    }
4427
4428    if (handled) {
4429      event.preventDefault();
4430      event.stopPropagation();
4431    }
4432  },
4433
4434  /* Filter entered characters - based on date format. */
4435  _doKeyPress: function(event) {
4436    var chars, chr,
4437      inst = $.datepicker._getInst(event.target);
4438
4439    if ($.datepicker._get(inst, "constrainInput")) {
4440      chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4441      chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4442      return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4443    }
4444  },
4445
4446  /* Synchronise manual entry and field/alternate field. */
4447  _doKeyUp: function(event) {
4448    var date,
4449      inst = $.datepicker._getInst(event.target);
4450
4451    if (inst.input.val() !== inst.lastVal) {
vendor: 15,715 bytes, lines 4452-4878
4452      try {
4453        date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4454          (inst.input ? inst.input.val() : null),
4455          $.datepicker._getFormatConfig(inst));
4456
4457        if (date) { // only if valid
4458          $.datepicker._setDateFromField(inst);
4459          $.datepicker._updateAlternate(inst);
4460          $.datepicker._updateDatepicker(inst);
4461        }
4462      }
4463      catch (err) {
4464      }
4465    }
4466    return true;
4467  },
4468
4469  /* Pop-up the date picker for a given input field.
4470   * If false returned from beforeShow event handler do not show.
4471   * @param  input  element - the input field attached to the date picker or
4472   *          event - if triggered by focus
4473   */
4474  _showDatepicker: function(input) {
4475    input = input.target || input;
4476    if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4477      input = $("input", input.parentNode)[0];
4478    }
4479
4480    if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4481      return;
4482    }
4483
4484    var inst, beforeShow, beforeShowSettings, isFixed,
4485      offset, showAnim, duration;
4486
4487    inst = $.datepicker._getInst(input);
4488    if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4489      $.datepicker._curInst.dpDiv.stop(true, true);
4490      if ( inst && $.datepicker._datepickerShowing ) {
4491        $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4492      }
4493    }
4494
4495    beforeShow = $.datepicker._get(inst, "beforeShow");
4496    beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4497    if(beforeShowSettings === false){
4498      return;
4499    }
4500    datepicker_extendRemove(inst.settings, beforeShowSettings);
4501
4502    inst.lastVal = null;
4503    $.datepicker._lastInput = input;
4504    $.datepicker._setDateFromField(inst);
4505
4506    if ($.datepicker._inDialog) { // hide cursor
4507      input.value = "";
4508    }
4509    if (!$.datepicker._pos) { // position below input
4510      $.datepicker._pos = $.datepicker._findPos(input);
4511      $.datepicker._pos[1] += input.offsetHeight; // add the height
4512    }
4513
4514    isFixed = false;
4515    $(input).parents().each(function() {
4516      isFixed |= $(this).css("position") === "fixed";
4517      return !isFixed;
4518    });
4519
4520    offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4521    $.datepicker._pos = null;
4522    //to avoid flashes on Firefox
4523    inst.dpDiv.empty();
4524    // determine sizing offscreen
4525    inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4526    $.datepicker._updateDatepicker(inst);
4527    // fix width for dynamic number of date pickers
4528    // and adjust position before showing
4529    offset = $.datepicker._checkOffset(inst, offset, isFixed);
4530    inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4531      "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4532      left: offset.left + "px", top: offset.top + "px"});
4533
4534    if (!inst.inline) {
4535      showAnim = $.datepicker._get(inst, "showAnim");
4536      duration = $.datepicker._get(inst, "duration");
4537      inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4538      $.datepicker._datepickerShowing = true;
4539
4540      if ( $.effects && $.effects.effect[ showAnim ] ) {
4541        inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4542      } else {
4543        inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4544      }
4545
4546      if ( $.datepicker._shouldFocusInput( inst ) ) {
4547        inst.input.focus();
4548      }
4549
4550      $.datepicker._curInst = inst;
4551    }
4552  },
4553
4554  /* Generate the date picker content. */
4555  _updateDatepicker: function(inst) {
4556    this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4557    datepicker_instActive = inst; // for delegate hover events
4558    inst.dpDiv.empty().append(this._generateHTML(inst));
4559    this._attachHandlers(inst);
4560
4561    var origyearshtml,
4562      numMonths = this._getNumberOfMonths(inst),
4563      cols = numMonths[1],
4564      width = 17,
4565      activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4566
4567    if ( activeCell.length > 0 ) {
4568      datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4569    }
4570
4571    inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4572    if (cols > 1) {
4573      inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4574    }
4575    inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4576      "Class"]("ui-datepicker-multi");
4577    inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4578      "Class"]("ui-datepicker-rtl");
4579
4580    if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4581      inst.input.focus();
4582    }
4583
4584    // deffered render of the years select (to avoid flashes on Firefox)
4585    if( inst.yearshtml ){
4586      origyearshtml = inst.yearshtml;
4587      setTimeout(function(){
4588        //assure that inst.yearshtml didn't change.
4589        if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4590          inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4591        }
4592        origyearshtml = inst.yearshtml = null;
4593      }, 0);
4594    }
4595  },
4596
4597  // #6694 - don't focus the input if it's already focused
4598  // this breaks the change event in IE
4599  // Support: IE and jQuery <1.9
4600  _shouldFocusInput: function( inst ) {
4601    return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4602  },
4603
4604  /* Check positioning to remain on screen. */
4605  _checkOffset: function(inst, offset, isFixed) {
4606    var dpWidth = inst.dpDiv.outerWidth(),
4607      dpHeight = inst.dpDiv.outerHeight(),
4608      inputWidth = inst.input ? inst.input.outerWidth() : 0,
4609      inputHeight = inst.input ? inst.input.outerHeight() : 0,
4610      viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4611      viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4612
4613    offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4614    offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4615    offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4616
4617    // now check if datepicker is showing outside window viewport - move to a better place if so.
4618    offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4619      Math.abs(offset.left + dpWidth - viewWidth) : 0);
4620    offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4621      Math.abs(dpHeight + inputHeight) : 0);
4622
4623    return offset;
4624  },
4625
4626  /* Find an object's position on the screen. */
4627  _findPos: function(obj) {
4628    var position,
4629      inst = this._getInst(obj),
4630      isRTL = this._get(inst, "isRTL");
4631
4632    while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4633      obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4634    }
4635
4636    position = $(obj).offset();
4637    return [position.left, position.top];
4638  },
4639
4640  /* Hide the date picker from view.
4641   * @param  input  element - the input field attached to the date picker
4642   */
4643  _hideDatepicker: function(input) {
4644    var showAnim, duration, postProcess, onClose,
4645      inst = this._curInst;
4646
4647    if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4648      return;
4649    }
4650
4651    if (this._datepickerShowing) {
4652      showAnim = this._get(inst, "showAnim");
4653      duration = this._get(inst, "duration");
4654      postProcess = function() {
4655        $.datepicker._tidyDialog(inst);
4656      };
4657
4658      // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4659      if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4660        inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4661      } else {
4662        inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4663          (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4664      }
4665
4666      if (!showAnim) {
4667        postProcess();
4668      }
4669      this._datepickerShowing = false;
4670
4671      onClose = this._get(inst, "onClose");
4672      if (onClose) {
4673        onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4674      }
4675
4676      this._lastInput = null;
4677      if (this._inDialog) {
4678        this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4679        if ($.blockUI) {
4680          $.unblockUI();
4681          $("body").append(this.dpDiv);
4682        }
4683      }
4684      this._inDialog = false;
4685    }
4686  },
4687
4688  /* Tidy up after a dialog display. */
4689  _tidyDialog: function(inst) {
4690    inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4691  },
4692
4693  /* Close date picker if clicked elsewhere. */
4694  _checkExternalClick: function(event) {
4695    if (!$.datepicker._curInst) {
4696      return;
4697    }
4698
4699    var $target = $(event.target),
4700      inst = $.datepicker._getInst($target[0]);
4701
4702    if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4703        $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4704        !$target.hasClass($.datepicker.markerClassName) &&
4705        !$target.closest("." + $.datepicker._triggerClass).length &&
4706        $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4707      ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4708        $.datepicker._hideDatepicker();
4709    }
4710  },
4711
4712  /* Adjust one of the date sub-fields. */
4713  _adjustDate: function(id, offset, period) {
4714    var target = $(id),
4715      inst = this._getInst(target[0]);
4716
4717    if (this._isDisabledDatepicker(target[0])) {
4718      return;
4719    }
4720    this._adjustInstDate(inst, offset +
4721      (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4722      period);
4723    this._updateDatepicker(inst);
4724  },
4725
4726  /* Action for current link. */
4727  _gotoToday: function(id) {
4728    var date,
4729      target = $(id),
4730      inst = this._getInst(target[0]);
4731
4732    if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4733      inst.selectedDay = inst.currentDay;
4734      inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4735      inst.drawYear = inst.selectedYear = inst.currentYear;
4736    } else {
4737      date = new Date();
4738      inst.selectedDay = date.getDate();
4739      inst.drawMonth = inst.selectedMonth = date.getMonth();
4740      inst.drawYear = inst.selectedYear = date.getFullYear();
4741    }
4742    this._notifyChange(inst);
4743    this._adjustDate(target);
4744  },
4745
4746  /* Action for selecting a new month/year. */
4747  _selectMonthYear: function(id, select, period) {
4748    var target = $(id),
4749      inst = this._getInst(target[0]);
4750
4751    inst["selected" + (period === "M" ? "Month" : "Year")] =
4752    inst["draw" + (period === "M" ? "Month" : "Year")] =
4753      parseInt(select.options[select.selectedIndex].value,10);
4754
4755    this._notifyChange(inst);
4756    this._adjustDate(target);
4757  },
4758
4759  /* Action for selecting a day. */
4760  _selectDay: function(id, month, year, td) {
4761    var inst,
4762      target = $(id);
4763
4764    if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4765      return;
4766    }
4767
4768    inst = this._getInst(target[0]);
4769    inst.selectedDay = inst.currentDay = $("a", td).html();
4770    inst.selectedMonth = inst.currentMonth = month;
4771    inst.selectedYear = inst.currentYear = year;
4772    this._selectDate(id, this._formatDate(inst,
4773      inst.currentDay, inst.currentMonth, inst.currentYear));
4774  },
4775
4776  /* Erase the input field and hide the date picker. */
4777  _clearDate: function(id) {
4778    var target = $(id);
4779    this._selectDate(target, "");
4780  },
4781
4782  /* Update the input field with the selected date. */
4783  _selectDate: function(id, dateStr) {
4784    var onSelect,
4785      target = $(id),
4786      inst = this._getInst(target[0]);
4787
4788    dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4789    if (inst.input) {
4790      inst.input.val(dateStr);
4791    }
4792    this._updateAlternate(inst);
4793
4794    onSelect = this._get(inst, "onSelect");
4795    if (onSelect) {
4796      onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4797    } else if (inst.input) {
4798      inst.input.trigger("change"); // fire the change event
4799    }
4800
4801    if (inst.inline){
4802      this._updateDatepicker(inst);
4803    } else {
4804      this._hideDatepicker();
4805      this._lastInput = inst.input[0];
4806      if (typeof(inst.input[0]) !== "object") {
4807        inst.input.focus(); // restore focus
4808      }
4809      this._lastInput = null;
4810    }
4811  },
4812
4813  /* Update any alternate field to synchronise with the main field. */
4814  _updateAlternate: function(inst) {
4815    var altFormat, date, dateStr,
4816      altField = this._get(inst, "altField");
4817
4818    if (altField) { // update alternate field too
4819      altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4820      date = this._getDate(inst);
4821      dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4822      $(altField).each(function() { $(this).val(dateStr); });
4823    }
4824  },
4825
4826  /* Set as beforeShowDay function to prevent selection of weekends.
4827   * @param  date  Date - the date to customise
4828   * @return [boolean, string] - is this date selectable?, what is its CSS class?
4829   */
4830  noWeekends: function(date) {
4831    var day = date.getDay();
4832    return [(day > 0 && day < 6), ""];
4833  },
4834
4835  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4836   * @param  date  Date - the date to get the week for
4837   * @return  number - the number of the week within the year that contains this date
4838   */
4839  iso8601Week: function(date) {
4840    var time,
4841      checkDate = new Date(date.getTime());
4842
4843    // Find Thursday of this week starting on Monday
4844    checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4845
4846    time = checkDate.getTime();
4847    checkDate.setMonth(0); // Compare with Jan 1
4848    checkDate.setDate(1);
4849    return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4850  },
4851
4852  /* Parse a string value into a date object.
4853   * See formatDate below for the possible formats.
4854   *
4855   * @param  format string - the expected format of the date
4856   * @param  value string - the date in the above format
4857   * @param  settings Object - attributes include:
4858   *          shortYearCutoff  number - the cutoff year for determining the century (optional)
4859   *          dayNamesShort  string[7] - abbreviated names of the days from Sunday (optional)
4860   *          dayNames    string[7] - names of the days from Sunday (optional)
4861   *          monthNamesShort string[12] - abbreviated names of the months (optional)
4862   *          monthNames    string[12] - names of the months (optional)
4863   * @return  Date - the extracted date value or null if value is blank
4864   */
4865  parseDate: function (format, value, settings) {
4866    if (format == null || value == null) {
4867      throw "Invalid arguments";
4868    }
4869
4870    value = (typeof value === "object" ? value.toString() : value + "");
4871    if (value === "") {
4872      return null;
4873    }
4874
4875    var iFormat, dim, extra,
4876      iValue = 0,
4877      shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4878      shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 14,710 bytes, lines 4878-5301
4878:
4879        new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4880      dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4881      dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4882      monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4883      monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4884      year = -1,
4885      month = -1,
4886      day = -1,
4887      doy = -1,
4888      literal = false,
4889      date,
4890      // Check whether a format character is doubled
4891      lookAhead = function(match) {
4892        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4893        if (matches) {
4894          iFormat++;
4895        }
4896        return matches;
4897      },
4898      // Extract a number from the string value
4899      getNumber = function(match) {
4900        var isDoubled = lookAhead(match),
4901          size = (match === "@" ? 14 : (match === "!" ? 20 :
4902          (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4903          minSize = (match === "y" ? size : 1),
4904          digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4905          num = value.substring(iValue).match(digits);
4906        if (!num) {
4907          throw "Missing number at position " + iValue;
4908        }
4909        iValue += num[0].length;
4910        return parseInt(num[0], 10);
4911      },
4912      // Extract a name from the string value and convert to an index
4913      getName = function(match, shortNames, longNames) {
4914        var index = -1,
4915          names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4916            return [ [k, v] ];
4917          }).sort(function (a, b) {
4918            return -(a[1].length - b[1].length);
4919          });
4920
4921        $.each(names, function (i, pair) {
4922          var name = pair[1];
4923          if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4924            index = pair[0];
4925            iValue += name.length;
4926            return false;
4927          }
4928        });
4929        if (index !== -1) {
4930          return index + 1;
4931        } else {
4932          throw "Unknown name at position " + iValue;
4933        }
4934      },
4935      // Confirm that a literal character matches the string value
4936      checkLiteral = function() {
4937        if (value.charAt(iValue) !== format.charAt(iFormat)) {
4938          throw "Unexpected literal at position " + iValue;
4939        }
4940        iValue++;
4941      };
4942
4943    for (iFormat = 0; iFormat < format.length; iFormat++) {
4944      if (literal) {
4945        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4946          literal = false;
4947        } else {
4948          checkLiteral();
4949        }
4950      } else {
4951        switch (format.charAt(iFormat)) {
4952          case "d":
4953            day = getNumber("d");
4954            break;
4955          case "D":
4956            getName("D", dayNamesShort, dayNames);
4957            break;
4958          case "o":
4959            doy = getNumber("o");
4960            break;
4961          case "m":
4962            month = getNumber("m");
4963            break;
4964          case "M":
4965            month = getName("M", monthNamesShort, monthNames);
4966            break;
4967          case "y":
4968            year = getNumber("y");
4969            break;
4970          case "@":
4971            date = new Date(getNumber("@"));
4972            year = date.getFullYear();
4973            month = date.getMonth() + 1;
4974            day = date.getDate();
4975            break;
4976          case "!":
4977            date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4978            year = date.getFullYear();
4979            month = date.getMonth() + 1;
4980            day = date.getDate();
4981            break;
4982          case "'":
4983            if (lookAhead("'")){
4984              checkLiteral();
4985            } else {
4986              literal = true;
4987            }
4988            break;
4989          default:
4990            checkLiteral();
4991        }
4992      }
4993    }
4994
4995    if (iValue < value.length){
4996      extra = value.substr(iValue);
4997      if (!/^\s+/.test(extra)) {
4998        throw "Extra/unparsed characters found in date: " + extra;
4999      }
5000    }
5001
5002    if (year === -1) {
5003      year = new Date().getFullYear();
5004    } else if (year < 100) {
5005      year += new Date().getFullYear() - new Date().getFullYear() % 100 +
5006        (year <= shortYearCutoff ? 0 : -100);
5007    }
5008
5009    if (doy > -1) {
5010      month = 1;
5011      day = doy;
5012      do {
5013        dim = this._getDaysInMonth(year, month - 1);
5014        if (day <= dim) {
5015          break;
5016        }
5017        month++;
5018        day -= dim;
5019      } while (true);
5020    }
5021
5022    date = this._daylightSavingAdjust(new Date(year, month - 1, day));
5023    if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
5024      throw "Invalid date"; // E.g. 31/02/00
5025    }
5026    return date;
5027  },
5028
5029  /* Standard date formats. */
5030  ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
5031  COOKIE: "D, dd M yy",
5032  ISO_8601: "yy-mm-dd",
5033  RFC_822: "D, d M y",
5034  RFC_850: "DD, dd-M-y",
5035  RFC_1036: "D, d M y",
5036  RFC_1123: "D, d M yy",
5037  RFC_2822: "D, d M yy",
5038  RSS: "D, d M y", // RFC 822
5039  TICKS: "!",
5040  TIMESTAMP: "@",
5041  W3C: "yy-mm-dd", // ISO 8601
5042
5043  _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
5044    Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5045
5046  /* Format a date object into a string value.
5047   * The format can be combinations of the following:
5048   * d  - day of month (no leading zero)
5049   * dd - day of month (two digit)
5050   * o  - day of year (no leading zeros)
5051   * oo - day of year (three digit)
5052   * D  - day name short
5053   * DD - day name long
5054   * m  - month of year (no leading zero)
5055   * mm - month of year (two digit)
5056   * M  - month name short
5057   * MM - month name long
5058   * y  - year (two digit)
5059   * yy - year (four digit)
5060   * @ - Unix timestamp (ms since 01/01/1970)
5061   * ! - Windows ticks (100ns since 01/01/0001)
5062   * "..." - literal text
5063   * '' - single quote
5064   *
5065   * @param  format string - the desired format of the date
5066   * @param  date Date - the date value to format
5067   * @param  settings Object - attributes include:
5068   *          dayNamesShort  string[7] - abbreviated names of the days from Sunday (optional)
5069   *          dayNames    string[7] - names of the days from Sunday (optional)
5070   *          monthNamesShort string[12] - abbreviated names of the months (optional)
5071   *          monthNames    string[12] - names of the months (optional)
5072   * @return  string - the date in the above format
5073   */
5074  formatDate: function (format, date, settings) {
5075    if (!date) {
5076      return "";
5077    }
5078
5079    var iFormat,
5080      dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5081      dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5082      monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5083      monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5084      // Check whether a format character is doubled
5085      lookAhead = function(match) {
5086        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5087        if (matches) {
5088          iFormat++;
5089        }
5090        return matches;
5091      },
5092      // Format a number, with leading zero if necessary
5093      formatNumber = function(match, value, len) {
5094        var num = "" + value;
5095        if (lookAhead(match)) {
5096          while (num.length < len) {
5097            num = "0" + num;
5098          }
5099        }
5100        return num;
5101      },
5102      // Format a name, short or long as requested
5103      formatName = function(match, value, shortNames, longNames) {
5104        return (lookAhead(match) ? longNames[value] : shortNames[value]);
5105      },
5106      output = "",
5107      literal = false;
5108
5109    if (date) {
5110      for (iFormat = 0; iFormat < format.length; iFormat++) {
5111        if (literal) {
5112          if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5113            literal = false;
5114          } else {
5115            output += format.charAt(iFormat);
5116          }
5117        } else {
5118          switch (format.charAt(iFormat)) {
5119            case "d":
5120              output += formatNumber("d", date.getDate(), 2);
5121              break;
5122            case "D":
5123              output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5124              break;
5125            case "o":
5126              output += formatNumber("o",
5127                Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5128              break;
5129            case "m":
5130              output += formatNumber("m", date.getMonth() + 1, 2);
5131              break;
5132            case "M":
5133              output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5134              break;
5135            case "y":
5136              output += (lookAhead("y") ? date.getFullYear() :
5137                (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5138              break;
5139            case "@":
5140              output += date.getTime();
5141              break;
5142            case "!":
5143              output += date.getTime() * 10000 + this._ticksTo1970;
5144              break;
5145            case "'":
5146              if (lookAhead("'")) {
5147                output += "'";
5148              } else {
5149                literal = true;
5150              }
5151              break;
5152            default:
5153              output += format.charAt(iFormat);
5154          }
5155        }
5156      }
5157    }
5158    return output;
5159  },
5160
5161  /* Extract all possible characters from the date format. */
5162  _possibleChars: function (format) {
5163    var iFormat,
5164      chars = "",
5165      literal = false,
5166      // Check whether a format character is doubled
5167      lookAhead = function(match) {
5168        var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5169        if (matches) {
5170          iFormat++;
5171        }
5172        return matches;
5173      };
5174
5175    for (iFormat = 0; iFormat < format.length; iFormat++) {
5176      if (literal) {
5177        if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5178          literal = false;
5179        } else {
5180          chars += format.charAt(iFormat);
5181        }
5182      } else {
5183        switch (format.charAt(iFormat)) {
5184          case "d": case "m": case "y": case "@":
5185            chars += "0123456789";
5186            break;
5187          case "D": case "M":
5188            return null; // Accept anything
5189          case "'":
5190            if (lookAhead("'")) {
5191              chars += "'";
5192            } else {
5193              literal = true;
5194            }
5195            break;
5196          default:
5197            chars += format.charAt(iFormat);
5198        }
5199      }
5200    }
5201    return chars;
5202  },
5203
5204  /* Get a setting value, defaulting if necessary. */
5205  _get: function(inst, name) {
5206    return inst.settings[name] !== undefined ?
5207      inst.settings[name] : this._defaults[name];
5208  },
5209
5210  /* Parse existing date and initialise date picker. */
5211  _setDateFromField: function(inst, noDefault) {
5212    if (inst.input.val() === inst.lastVal) {
5213      return;
5214    }
5215
5216    var dateFormat = this._get(inst, "dateFormat"),
5217      dates = inst.lastVal = inst.input ? inst.input.val() : null,
5218      defaultDate = this._getDefaultDate(inst),
5219      date = defaultDate,
5220      settings = this._getFormatConfig(inst);
5221
5222    try {
5223      date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5224    } catch (event) {
5225      dates = (noDefault ? "" : dates);
5226    }
5227    inst.selectedDay = date.getDate();
5228    inst.drawMonth = inst.selectedMonth = date.getMonth();
5229    inst.drawYear = inst.selectedYear = date.getFullYear();
5230    inst.currentDay = (dates ? date.getDate() : 0);
5231    inst.currentMonth = (dates ? date.getMonth() : 0);
5232    inst.currentYear = (dates ? date.getFullYear() : 0);
5233    this._adjustInstDate(inst);
5234  },
5235
5236  /* Retrieve the default date shown on opening. */
5237  _getDefaultDate: function(inst) {
5238    return this._restrictMinMax(inst,
5239      this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5240  },
5241
5242  /* A date may be specified as an exact value or a relative one. */
5243  _determineDate: function(inst, date, defaultDate) {
5244    var offsetNumeric = function(offset) {
5245        var date = new Date();
5246        date.setDate(date.getDate() + offset);
5247        return date;
5248      },
5249      offsetString = function(offset) {
5250        try {
5251          return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5252            offset, $.datepicker._getFormatConfig(inst));
5253        }
5254        catch (e) {
5255          // Ignore
5256        }
5257
5258        var date = (offset.toLowerCase().match(/^c/) ?
5259          $.datepicker._getDate(inst) : null) || new Date(),
5260          year = date.getFullYear(),
5261          month = date.getMonth(),
5262          day = date.getDate(),
5263          pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5264          matches = pattern.exec(offset);
5265
5266        while (matches) {
5267          switch (matches[2] || "d") {
5268            case "d" : case "D" :
5269              day += parseInt(matches[1],10); break;
5270            case "w" : case "W" :
5271              day += parseInt(matches[1],10) * 7; break;
5272            case "m" : case "M" :
5273              month += parseInt(matches[1],10);
5274              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5275              break;
5276            case "y": case "Y" :
5277              year += parseInt(matches[1],10);
5278              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5279              break;
5280          }
5281          matches = pattern.exec(offset);
5282        }
5283        return new Date(year, month, day);
5284      },
5285      newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5286        (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5287
5288    newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5289    if (newDate) {
5290      newDate.setHours(0);
5291      newDate.setMinutes(0);
5292      newDate.setSeconds(0);
5293      newDate.setMilliseconds(0);
5294    }
5295    return this._daylightSavingAdjust(newDate);
5296  },
5297
5298  /* Handle switch to/from daylight saving.
5299   * Hours may be non-zero on daylight saving cut-over:
5300   * > 12 when midnight changeover, but then cannot generate
5301   * midnight datetime, so jump to 1AM, otherwise reset.
vendor: 25,244 bytes, lines 5302-5841
5302   * @param  date  (Date) the date to check
5303   * @return  (Date) the corrected date
5304   */
5305  _daylightSavingAdjust: function(date) {
5306    if (!date) {
5307      return null;
5308    }
5309    date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5310    return date;
5311  },
5312
5313  /* Set the date(s) directly. */
5314  _setDate: function(inst, date, noChange) {
5315    var clear = !date,
5316      origMonth = inst.selectedMonth,
5317      origYear = inst.selectedYear,
5318      newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5319
5320    inst.selectedDay = inst.currentDay = newDate.getDate();
5321    inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5322    inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5323    if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5324      this._notifyChange(inst);
5325    }
5326    this._adjustInstDate(inst);
5327    if (inst.input) {
5328      inst.input.val(clear ? "" : this._formatDate(inst));
5329    }
5330  },
5331
5332  /* Retrieve the date(s) directly. */
5333  _getDate: function(inst) {
5334    var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5335      this._daylightSavingAdjust(new Date(
5336      inst.currentYear, inst.currentMonth, inst.currentDay)));
5337      return startDate;
5338  },
5339
5340  /* Attach the onxxx handlers.  These are declared statically so
5341   * they work with static code transformers like Caja.
5342   */
5343  _attachHandlers: function(inst) {
5344    var stepMonths = this._get(inst, "stepMonths"),
5345      id = "#" + inst.id.replace( /\\\\/g, "\\" );
5346    inst.dpDiv.find("[data-handler]").map(function () {
5347      var handler = {
5348        prev: function () {
5349          $.datepicker._adjustDate(id, -stepMonths, "M");
5350        },
5351        next: function () {
5352          $.datepicker._adjustDate(id, +stepMonths, "M");
5353        },
5354        hide: function () {
5355          $.datepicker._hideDatepicker();
5356        },
5357        today: function () {
5358          $.datepicker._gotoToday(id);
5359        },
5360        selectDay: function () {
5361          $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5362          return false;
5363        },
5364        selectMonth: function () {
5365          $.datepicker._selectMonthYear(id, this, "M");
5366          return false;
5367        },
5368        selectYear: function () {
5369          $.datepicker._selectMonthYear(id, this, "Y");
5370          return false;
5371        }
5372      };
5373      $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5374    });
5375  },
5376
5377  /* Generate the HTML for the current state of the date picker. */
5378  _generateHTML: function(inst) {
5379    var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5380      controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5381      monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5382      selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5383      cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5384      printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5385      tempDate = new Date(),
5386      today = this._daylightSavingAdjust(
5387        new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5388      isRTL = this._get(inst, "isRTL"),
5389      showButtonPanel = this._get(inst, "showButtonPanel"),
5390      hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5391      navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5392      numMonths = this._getNumberOfMonths(inst),
5393      showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5394      stepMonths = this._get(inst, "stepMonths"),
5395      isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5396      currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5397        new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5398      minDate = this._getMinMaxDate(inst, "min"),
5399      maxDate = this._getMinMaxDate(inst, "max"),
5400      drawMonth = inst.drawMonth - showCurrentAtPos,
5401      drawYear = inst.drawYear;
5402
5403    if (drawMonth < 0) {
5404      drawMonth += 12;
5405      drawYear--;
5406    }
5407    if (maxDate) {
5408      maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5409        maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5410      maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5411      while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5412        drawMonth--;
5413        if (drawMonth < 0) {
5414          drawMonth = 11;
5415          drawYear--;
5416        }
5417      }
5418    }
5419    inst.drawMonth = drawMonth;
5420    inst.drawYear = drawYear;
5421
5422    prevText = this._get(inst, "prevText");
5423    prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5424      this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5425      this._getFormatConfig(inst)));
5426
5427    prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5428      "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5429      " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5430      (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>"));
5431
5432    nextText = this._get(inst, "nextText");
5433    nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5434      this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5435      this._getFormatConfig(inst)));
5436
5437    next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5438      "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5439      " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5440      (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>"));
5441
5442    currentText = this._get(inst, "currentText");
5443    gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5444    currentText = (!navigationAsDateFormat ? currentText :
5445      this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5446
5447    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'>" +
5448      this._get(inst, "closeText") + "</button>" : "");
5449
5450    buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5451      (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'" +
5452      ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5453
5454    firstDay = parseInt(this._get(inst, "firstDay"),10);
5455    firstDay = (isNaN(firstDay) ? 0 : firstDay);
5456
5457    showWeek = this._get(inst, "showWeek");
5458    dayNames = this._get(inst, "dayNames");
5459    dayNamesMin = this._get(inst, "dayNamesMin");
5460    monthNames = this._get(inst, "monthNames");
5461    monthNamesShort = this._get(inst, "monthNamesShort");
5462    beforeShowDay = this._get(inst, "beforeShowDay");
5463    showOtherMonths = this._get(inst, "showOtherMonths");
5464    selectOtherMonths = this._get(inst, "selectOtherMonths");
5465    defaultDate = this._getDefaultDate(inst);
5466    html = "";
5467    dow;
5468    for (row = 0; row < numMonths[0]; row++) {
5469      group = "";
5470      this.maxRows = 4;
5471      for (col = 0; col < numMonths[1]; col++) {
5472        selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5473        cornerClass = " ui-corner-all";
5474        calender = "";
5475        if (isMultiMonth) {
5476          calender += "<div class='ui-datepicker-group";
5477          if (numMonths[1] > 1) {
5478            switch (col) {
5479              case 0: calender += " ui-datepicker-group-first";
5480                cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5481              case numMonths[1]-1: calender += " ui-datepicker-group-last";
5482                cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5483              default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5484            }
5485          }
5486          calender += "'>";
5487        }
5488        calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5489          (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5490          (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5491          this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5492          row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5493          "</div><table class='ui-datepicker-calendar'><thead>" +
5494          "<tr>";
5495        thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5496        for (dow = 0; dow < 7; dow++) { // days of the week
5497          day = (dow + firstDay) % 7;
5498          thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5499            "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5500        }
5501        calender += thead + "</tr></thead><tbody>";
5502        daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5503        if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5504          inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5505        }
5506        leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5507        curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5508        numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5509        this.maxRows = numRows;
5510        printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5511        for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5512          calender += "<tr>";
5513          tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5514            this._get(inst, "calculateWeek")(printDate) + "</td>");
5515          for (dow = 0; dow < 7; dow++) { // create date picker days
5516            daySettings = (beforeShowDay ?
5517              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5518            otherMonth = (printDate.getMonth() !== drawMonth);
5519            unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5520              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5521            tbody += "<td class='" +
5522              ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5523              (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5524              ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5525              (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5526              // or defaultDate is current printedDate and defaultDate is selectedDate
5527              " " + this._dayOverClass : "") + // highlight selected day
5528              (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5529              (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5530              (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5531              (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5532              ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5533              (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5534              (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5535              (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5536              (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5537              (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5538              (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5539              "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5540            printDate.setDate(printDate.getDate() + 1);
5541            printDate = this._daylightSavingAdjust(printDate);
5542          }
5543          calender += tbody + "</tr>";
5544        }
5545        drawMonth++;
5546        if (drawMonth > 11) {
5547          drawMonth = 0;
5548          drawYear++;
5549        }
5550        calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5551              ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5552        group += calender;
5553      }
5554      html += group;
5555    }
5556    html += buttonPanel;
5557    inst._keyEvent = false;
5558    return html;
5559  },
5560
5561  /* Generate the month and year header. */
5562  _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5563      secondary, monthNames, monthNamesShort) {
5564
5565    var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5566      changeMonth = this._get(inst, "changeMonth"),
5567      changeYear = this._get(inst, "changeYear"),
5568      showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5569      html = "<div class='ui-datepicker-title'>",
5570      monthHtml = "";
5571
5572    // month selection
5573    if (secondary || !changeMonth) {
5574      monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5575    } else {
5576      inMinYear = (minDate && minDate.getFullYear() === drawYear);
5577      inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5578      monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5579      for ( month = 0; month < 12; month++) {
5580        if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5581          monthHtml += "<option value='" + month + "'" +
5582            (month === drawMonth ? " selected='selected'" : "") +
5583            ">" + monthNamesShort[month] + "</option>";
5584        }
5585      }
5586      monthHtml += "</select>";
5587    }
5588
5589    if (!showMonthAfterYear) {
5590      html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5591    }
5592
5593    // year selection
5594    if ( !inst.yearshtml ) {
5595      inst.yearshtml = "";
5596      if (secondary || !changeYear) {
5597        html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5598      } else {
5599        // determine range of years to display
5600        years = this._get(inst, "yearRange").split(":");
5601        thisYear = new Date().getFullYear();
5602        determineYear = function(value) {
5603          var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5604            (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5605            parseInt(value, 10)));
5606          return (isNaN(year) ? thisYear : year);
5607        };
5608        year = determineYear(years[0]);
5609        endYear = Math.max(year, determineYear(years[1] || ""));
5610        year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5611        endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5612        inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5613        for (; year <= endYear; year++) {
5614          inst.yearshtml += "<option value='" + year + "'" +
5615            (year === drawYear ? " selected='selected'" : "") +
5616            ">" + year + "</option>";
5617        }
5618        inst.yearshtml += "</select>";
5619
5620        html += inst.yearshtml;
5621        inst.yearshtml = null;
5622      }
5623    }
5624
5625    html += this._get(inst, "yearSuffix");
5626    if (showMonthAfterYear) {
5627      html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5628    }
5629    html += "</div>"; // Close datepicker_header
5630    return html;
5631  },
5632
5633  /* Adjust one of the date sub-fields. */
5634  _adjustInstDate: function(inst, offset, period) {
5635    var year = inst.drawYear + (period === "Y" ? offset : 0),
5636      month = inst.drawMonth + (period === "M" ? offset : 0),
5637      day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5638      date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5639
5640    inst.selectedDay = date.getDate();
5641    inst.drawMonth = inst.selectedMonth = date.getMonth();
5642    inst.drawYear = inst.selectedYear = date.getFullYear();
5643    if (period === "M" || period === "Y") {
5644      this._notifyChange(inst);
5645    }
5646  },
5647
5648  /* Ensure a date is within any min/max bounds. */
5649  _restrictMinMax: function(inst, date) {
5650    var minDate = this._getMinMaxDate(inst, "min"),
5651      maxDate = this._getMinMaxDate(inst, "max"),
5652      newDate = (minDate && date < minDate ? minDate : date);
5653    return (maxDate && newDate > maxDate ? maxDate : newDate);
5654  },
5655
5656  /* Notify change of month/year. */
5657  _notifyChange: function(inst) {
5658    var onChange = this._get(inst, "onChangeMonthYear");
5659    if (onChange) {
5660      onChange.apply((inst.input ? inst.input[0] : null),
5661        [inst.selectedYear, inst.selectedMonth + 1, inst]);
5662    }
5663  },
5664
5665  /* Determine the number of months to show. */
5666  _getNumberOfMonths: function(inst) {
5667    var numMonths = this._get(inst, "numberOfMonths");
5668    return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5669  },
5670
5671  /* Determine the current maximum date - ensure no time components are set. */
5672  _getMinMaxDate: function(inst, minMax) {
5673    return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5674  },
5675
5676  /* Find the number of days in a given month. */
5677  _getDaysInMonth: function(year, month) {
5678    return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5679  },
5680
5681  /* Find the day of the week of the first of a month. */
5682  _getFirstDayOfMonth: function(year, month) {
5683    return new Date(year, month, 1).getDay();
5684  },
5685
5686  /* Determines if we should allow a "next/prev" month display change. */
5687  _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5688    var numMonths = this._getNumberOfMonths(inst),
5689      date = this._daylightSavingAdjust(new Date(curYear,
5690      curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5691
5692    if (offset < 0) {
5693      date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5694    }
5695    return this._isInRange(inst, date);
5696  },
5697
5698  /* Is the given date in the accepted range? */
5699  _isInRange: function(inst, date) {
5700    var yearSplit, currentYear,
5701      minDate = this._getMinMaxDate(inst, "min"),
5702      maxDate = this._getMinMaxDate(inst, "max"),
5703      minYear = null,
5704      maxYear = null,
5705      years = this._get(inst, "yearRange");
5706      if (years){
5707        yearSplit = years.split(":");
5708        currentYear = new Date().getFullYear();
5709        minYear = parseInt(yearSplit[0], 10);
5710        maxYear = parseInt(yearSplit[1], 10);
5711        if ( yearSplit[0].match(/[+\-].*/) ) {
5712          minYear += currentYear;
5713        }
5714        if ( yearSplit[1].match(/[+\-].*/) ) {
5715          maxYear += currentYear;
5716        }
5717      }
5718
5719    return ((!minDate || date.getTime() >= minDate.getTime()) &&
5720      (!maxDate || date.getTime() <= maxDate.getTime()) &&
5721      (!minYear || date.getFullYear() >= minYear) &&
5722      (!maxYear || date.getFullYear() <= maxYear));
5723  },
5724
5725  /* Provide the configuration settings for formatting/parsing. */
5726  _getFormatConfig: function(inst) {
5727    var shortYearCutoff = this._get(inst, "shortYearCutoff");
5728    shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5729      new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5730    return {shortYearCutoff: shortYearCutoff,
5731      dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5732      monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5733  },
5734
5735  /* Format the given date for display. */
5736  _formatDate: function(inst, day, month, year) {
5737    if (!day) {
5738      inst.currentDay = inst.selectedDay;
5739      inst.currentMonth = inst.selectedMonth;
5740      inst.currentYear = inst.selectedYear;
5741    }
5742    var date = (day ? (typeof day === "object" ? day :
5743      this._daylightSavingAdjust(new Date(year, month, day))) :
5744      this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5745    return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5746  }
5747});
5748
5749/*
5750 * Bind hover events for datepicker elements.
5751 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5752 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5753 */
5754function datepicker_bindHover(dpDiv) {
5755  var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5756  return dpDiv.delegate(selector, "mouseout", function() {
5757      $(this).removeClass("ui-state-hover");
5758      if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5759        $(this).removeClass("ui-datepicker-prev-hover");
5760      }
5761      if (this.className.indexOf("ui-datepicker-next") !== -1) {
5762        $(this).removeClass("ui-datepicker-next-hover");
5763      }
5764    })
5765    .delegate( selector, "mouseover", datepicker_handleMouseover );
5766}
5767
5768function datepicker_handleMouseover() {
5769  if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5770    $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5771    $(this).addClass("ui-state-hover");
5772    if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5773      $(this).addClass("ui-datepicker-prev-hover");
5774    }
5775    if (this.className.indexOf("ui-datepicker-next") !== -1) {
5776      $(this).addClass("ui-datepicker-next-hover");
5777    }
5778  }
5779}
5780
5781/* jQuery extend now ignores nulls! */
5782function datepicker_extendRemove(target, props) {
5783  $.extend(target, props);
5784  for (var name in props) {
5785    if (props[name] == null) {
5786      target[name] = props[name];
5787    }
5788  }
5789  return target;
5790}
5791
5792/* Invoke the datepicker functionality.
5793   @param  options  string - a command, optionally followed by additional parameters or
5794          Object - settings for attaching new datepicker functionality
5795   @return  jQuery object */
5796$.fn.datepicker = function(options){
5797
5798  /* Verify an empty collection wasn't passed - Fixes #6976 */
5799  if ( !this.length ) {
5800    return this;
5801  }
5802
5803  /* Initialise the date picker. */
5804  if (!$.datepicker.initialized) {
5805    $(document).mousedown($.datepicker._checkExternalClick);
5806    $.datepicker.initialized = true;
5807  }
5808
5809  /* Append datepicker main container to body if not exist. */
5810  if ($("#"+$.datepicker._mainDivId).length === 0) {
5811    $("body").append($.datepicker.dpDiv);
5812  }
5813
5814  var otherArgs = Array.prototype.slice.call(arguments, 1);
5815  if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5816    return $.datepicker["_" + options + "Datepicker"].
5817      apply($.datepicker, [this[0]].concat(otherArgs));
5818  }
5819  if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5820    return $.datepicker["_" + options + "Datepicker"].
5821      apply($.datepicker, [this[0]].concat(otherArgs));
5822  }
5823  return this.each(function() {
5824    typeof options === "string" ?
5825      $.datepicker["_" + options + "Datepicker"].
5826        apply($.datepicker, [this].concat(otherArgs)) :
5827      $.datepicker._attachDatepicker(this, options);
5828  });
5829};
5830
5831$.datepicker = new Datepicker(); // singleton instance
5832$.datepicker.initialized = false;
5833$.datepicker.uuid = new Date().getTime();
5834$.datepicker.version = "1.11.4";
5835
5836var datepicker = $.datepicker;
5837
5838
5839/*!
5840 * jQuery UI Draggable 1.11.4
5841 * http://jqueryui.com
vendor: 10,248 bytes, lines 5842-6194
5842 *
5843 * Copyright jQuery Foundation and other contributors
5844 * Released under the MIT license.
5845 * http://jquery.org/license
5846 *
5847 * http://api.jqueryui.com/draggable/
5848 */
5849
5850
5851$.widget("ui.draggable", $.ui.mouse, {
5852  version: "1.11.4",
5853  widgetEventPrefix: "drag",
5854  options: {
5855    addClasses: true,
5856    appendTo: "parent",
5857    axis: false,
5858    connectToSortable: false,
5859    containment: false,
5860    cursor: "auto",
5861    cursorAt: false,
5862    grid: false,
5863    handle: false,
5864    helper: "original",
5865    iframeFix: false,
5866    opacity: false,
5867    refreshPositions: false,
5868    revert: false,
5869    revertDuration: 500,
5870    scope: "default",
5871    scroll: true,
5872    scrollSensitivity: 20,
5873    scrollSpeed: 20,
5874    snap: false,
5875    snapMode: "both",
5876    snapTolerance: 20,
5877    stack: false,
5878    zIndex: false,
5879
5880    // callbacks
5881    drag: null,
5882    start: null,
5883    stop: null
5884  },
5885  _create: function() {
5886
5887    if ( this.options.helper === "original" ) {
5888      this._setPositionRelative();
5889    }
5890    if (this.options.addClasses){
5891      this.element.addClass("ui-draggable");
5892    }
5893    if (this.options.disabled){
5894      this.element.addClass("ui-draggable-disabled");
5895    }
5896    this._setHandleClassName();
5897
5898    this._mouseInit();
5899  },
5900
5901  _setOption: function( key, value ) {
5902    this._super( key, value );
5903    if ( key === "handle" ) {
5904      this._removeHandleClassName();
5905      this._setHandleClassName();
5906    }
5907  },
5908
5909  _destroy: function() {
5910    if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5911      this.destroyOnClear = true;
5912      return;
5913    }
5914    this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5915    this._removeHandleClassName();
5916    this._mouseDestroy();
5917  },
5918
5919  _mouseCapture: function(event) {
5920    var o = this.options;
5921
5922    this._blurActiveElement( event );
5923
5924    // among others, prevent a drag on a resizable-handle
5925    if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5926      return false;
5927    }
5928
5929    //Quit if we're not on a valid handle
5930    this.handle = this._getHandle(event);
5931    if (!this.handle) {
5932      return false;
5933    }
5934
5935    this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
5936
5937    return true;
5938
5939  },
5940
5941  _blockFrames: function( selector ) {
5942    this.iframeBlocks = this.document.find( selector ).map(function() {
5943      var iframe = $( this );
5944
5945      return $( "<div>" )
5946        .css( "position", "absolute" )
5947        .appendTo( iframe.parent() )
5948        .outerWidth( iframe.outerWidth() )
5949        .outerHeight( iframe.outerHeight() )
5950        .offset( iframe.offset() )[ 0 ];
5951    });
5952  },
5953
5954  _unblockFrames: function() {
5955    if ( this.iframeBlocks ) {
5956      this.iframeBlocks.remove();
5957      delete this.iframeBlocks;
5958    }
5959  },
5960
5961  _blurActiveElement: function( event ) {
5962    var document = this.document[ 0 ];
5963
5964    // Only need to blur if the event occurred on the draggable itself, see #10527
5965    if ( !this.handleElement.is( event.target ) ) {
5966      return;
5967    }
5968
5969    // support: IE9
5970    // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5971    try {
5972
5973      // Support: IE9, IE10
5974      // If the <body> is blurred, IE will switch windows, see #9520
5975      if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5976
5977        // Blur any element that currently has focus, see #4261
5978        $( document.activeElement ).blur();
5979      }
5980    } catch ( error ) {}
5981  },
5982
5983  _mouseStart: function(event) {
5984
5985    var o = this.options;
5986
5987    //Create and append the visible helper
5988    this.helper = this._createHelper(event);
5989
5990    this.helper.addClass("ui-draggable-dragging");
5991
5992    //Cache the helper size
5993    this._cacheHelperProportions();
5994
5995    //If ddmanager is used for droppables, set the global draggable
5996    if ($.ui.ddmanager) {
5997      $.ui.ddmanager.current = this;
5998    }
5999
6000    /*
6001     * - Position generation -
6002     * This block generates everything position related - it's the core of draggables.
6003     */
6004
6005    //Cache the margins of the original element
6006    this._cacheMargins();
6007
6008    //Store the helper's css position
6009    this.cssPosition = this.helper.css( "position" );
6010    this.scrollParent = this.helper.scrollParent( true );
6011    this.offsetParent = this.helper.offsetParent();
6012    this.hasFixedAncestor = this.helper.parents().filter(function() {
6013        return $( this ).css( "position" ) === "fixed";
6014      }).length > 0;
6015
6016    //The element's absolute position on the page minus margins
6017    this.positionAbs = this.element.offset();
6018    this._refreshOffsets( event );
6019
6020    //Generate the original position
6021    this.originalPosition = this.position = this._generatePosition( event, false );
6022    this.originalPageX = event.pageX;
6023    this.originalPageY = event.pageY;
6024
6025    //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
6026    (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
6027
6028    //Set a containment if given in the options
6029    this._setContainment();
6030
6031    //Trigger event + callbacks
6032    if (this._trigger("start", event) === false) {
6033      this._clear();
6034      return false;
6035    }
6036
6037    //Recache the helper size
6038    this._cacheHelperProportions();
6039
6040    //Prepare the droppable offsets
6041    if ($.ui.ddmanager && !o.dropBehaviour) {
6042      $.ui.ddmanager.prepareOffsets(this, event);
6043    }
6044
6045    // Reset helper's right/bottom css if they're set and set explicit width/height instead
6046    // as this prevents resizing of elements with right/bottom set (see #7772)
6047    this._normalizeRightBottom();
6048
6049    this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
6050
6051    //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
6052    if ( $.ui.ddmanager ) {
6053      $.ui.ddmanager.dragStart(this, event);
6054    }
6055
6056    return true;
6057  },
6058
6059  _refreshOffsets: function( event ) {
6060    this.offset = {
6061      top: this.positionAbs.top - this.margins.top,
6062      left: this.positionAbs.left - this.margins.left,
6063      scroll: false,
6064      parent: this._getParentOffset(),
6065      relative: this._getRelativeOffset()
6066    };
6067
6068    this.offset.click = {
6069      left: event.pageX - this.offset.left,
6070      top: event.pageY - this.offset.top
6071    };
6072  },
6073
6074  _mouseDrag: function(event, noPropagation) {
6075    // reset any necessary cached properties (see #5009)
6076    if ( this.hasFixedAncestor ) {
6077      this.offset.parent = this._getParentOffset();
6078    }
6079
6080    //Compute the helpers position
6081    this.position = this._generatePosition( event, true );
6082    this.positionAbs = this._convertPositionTo("absolute");
6083
6084    //Call plugins and callbacks and use the resulting position if something is returned
6085    if (!noPropagation) {
6086      var ui = this._uiHash();
6087      if (this._trigger("drag", event, ui) === false) {
6088        this._mouseUp({});
6089        return false;
6090      }
6091      this.position = ui.position;
6092    }
6093
6094    this.helper[ 0 ].style.left = this.position.left + "px";
6095    this.helper[ 0 ].style.top = this.position.top + "px";
6096
6097    if ($.ui.ddmanager) {
6098      $.ui.ddmanager.drag(this, event);
6099    }
6100
6101    return false;
6102  },
6103
6104  _mouseStop: function(event) {
6105
6106    //If we are using droppables, inform the manager about the drop
6107    var that = this,
6108      dropped = false;
6109    if ($.ui.ddmanager && !this.options.dropBehaviour) {
6110      dropped = $.ui.ddmanager.drop(this, event);
6111    }
6112
6113    //if a drop comes from outside (a sortable)
6114    if (this.dropped) {
6115      dropped = this.dropped;
6116      this.dropped = false;
6117    }
6118
6119    if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
6120      $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6121        if (that._trigger("stop", event) !== false) {
6122          that._clear();
6123        }
6124      });
6125    } else {
6126      if (this._trigger("stop", event) !== false) {
6127        this._clear();
6128      }
6129    }
6130
6131    return false;
6132  },
6133
6134  _mouseUp: function( event ) {
6135    this._unblockFrames();
6136
6137    //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6138    if ( $.ui.ddmanager ) {
6139      $.ui.ddmanager.dragStop(this, event);
6140    }
6141
6142    // Only need to focus if the event occurred on the draggable itself, see #10527
6143    if ( this.handleElement.is( event.target ) ) {
6144      // The interaction is over; whether or not the click resulted in a drag, focus the element
6145      this.element.focus();
6146    }
6147
6148    return $.ui.mouse.prototype._mouseUp.call(this, event);
6149  },
6150
6151  cancel: function() {
6152
6153    if (this.helper.is(".ui-draggable-dragging")) {
6154      this._mouseUp({});
6155    } else {
6156      this._clear();
6157    }
6158
6159    return this;
6160
6161  },
6162
6163  _getHandle: function(event) {
6164    return this.options.handle ?
6165      !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6166      true;
6167  },
6168
6169  _setHandleClassName: function() {
6170    this.handleElement = this.options.handle ?
6171      this.element.find( this.options.handle ) : this.element;
6172    this.handleElement.addClass( "ui-draggable-handle" );
6173  },
6174
6175  _removeHandleClassName: function() {
6176    this.handleElement.removeClass( "ui-draggable-handle" );
6177  },
6178
6179  _createHelper: function(event) {
6180
6181    var o = this.options,
6182      helperIsFunction = $.isFunction( o.helper ),
6183      helper = helperIsFunction ?
6184        $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
6185        ( o.helper === "clone" ?
6186          this.element.clone().removeAttr( "id" ) :
6187          this.element );
6188
6189    if (!helper.parents("body").length) {
6190      helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6191    }
6192
6193    // http://bugs.jqueryui.com/ticket/9446
6194    // a helper function can return the original element
vendor: 4,734 bytes, lines 6195-6329
6195    // which wouldn't have been set to relative in _create
6196    if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
6197      this._setPositionRelative();
6198    }
6199
6200    if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6201      helper.css("position", "absolute");
6202    }
6203
6204    return helper;
6205
6206  },
6207
6208  _setPositionRelative: function() {
6209    if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
6210      this.element[ 0 ].style.position = "relative";
6211    }
6212  },
6213
6214  _adjustOffsetFromHelper: function(obj) {
6215    if (typeof obj === "string") {
6216      obj = obj.split(" ");
6217    }
6218    if ($.isArray(obj)) {
6219      obj = { left: +obj[0], top: +obj[1] || 0 };
6220    }
6221    if ("left" in obj) {
6222      this.offset.click.left = obj.left + this.margins.left;
6223    }
6224    if ("right" in obj) {
6225      this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6226    }
6227    if ("top" in obj) {
6228      this.offset.click.top = obj.top + this.margins.top;
6229    }
6230    if ("bottom" in obj) {
6231      this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6232    }
6233  },
6234
6235  _isRootNode: function( element ) {
6236    return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6237  },
6238
6239  _getParentOffset: function() {
6240
6241    //Get the offsetParent and cache its position
6242    var po = this.offsetParent.offset(),
6243      document = this.document[ 0 ];
6244
6245    // This is a special case where we need to modify a offset calculated on start, since the following happened:
6246    // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6247    // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6248    //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6249    if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6250      po.left += this.scrollParent.scrollLeft();
6251      po.top += this.scrollParent.scrollTop();
6252    }
6253
6254    if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6255      po = { top: 0, left: 0 };
6256    }
6257
6258    return {
6259      top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6260      left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6261    };
6262
6263  },
6264
6265  _getRelativeOffset: function() {
6266    if ( this.cssPosition !== "relative" ) {
6267      return { top: 0, left: 0 };
6268    }
6269
6270    var p = this.element.position(),
6271      scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272
6273    return {
6274      top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6275      left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6276    };
6277
6278  },
6279
6280  _cacheMargins: function() {
6281    this.margins = {
6282      left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6283      top: (parseInt(this.element.css("marginTop"), 10) || 0),
6284      right: (parseInt(this.element.css("marginRight"), 10) || 0),
6285      bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6286    };
6287  },
6288
6289  _cacheHelperProportions: function() {
6290    this.helperProportions = {
6291      width: this.helper.outerWidth(),
6292      height: this.helper.outerHeight()
6293    };
6294  },
6295
6296  _setContainment: function() {
6297
6298    var isUserScrollable, c, ce,
6299      o = this.options,
6300      document = this.document[ 0 ];
6301
6302    this.relativeContainer = null;
6303
6304    if ( !o.containment ) {
6305      this.containment = null;
6306      return;
6307    }
6308
6309    if ( o.containment === "window" ) {
6310      this.containment = [
6311        $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6312        $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6313        $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6314        $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6315      ];
6316      return;
6317    }
6318
6319    if ( o.containment === "document") {
6320      this.containment = [
6321        0,
6322        0,
6323        $( document ).width() - this.helperProportions.width - this.margins.left,
6324        ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6325      ];
6326      return;
6327    }
6328
6329    if ( o.containment.constructor === Array ) {
vendor: 7,479 bytes, lines 6330-6508
6330      this.containment = o.containment;
6331      return;
6332    }
6333
6334    if ( o.containment === "parent" ) {
6335      o.containment = this.helper[ 0 ].parentNode;
6336    }
6337
6338    c = $( o.containment );
6339    ce = c[ 0 ];
6340
6341    if ( !ce ) {
6342      return;
6343    }
6344
6345    isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
6346
6347    this.containment = [
6348      ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6349      ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6350      ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
6351        ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
6352        ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
6353        this.helperProportions.width -
6354        this.margins.left -
6355        this.margins.right,
6356      ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
6357        ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
6358        ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
6359        this.helperProportions.height -
6360        this.margins.top -
6361        this.margins.bottom
6362    ];
6363    this.relativeContainer = c;
6364  },
6365
6366  _convertPositionTo: function(d, pos) {
6367
6368    if (!pos) {
6369      pos = this.position;
6370    }
6371
6372    var mod = d === "absolute" ? 1 : -1,
6373      scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6374
6375    return {
6376      top: (
6377        pos.top  +                                // The absolute mouse position
6378        this.offset.relative.top * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
6379        this.offset.parent.top * mod -                    // The offsetParent's offset without borders (offset + border)
6380        ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6381      ),
6382      left: (
6383        pos.left +                                // The absolute mouse position
6384        this.offset.relative.left * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
6385        this.offset.parent.left * mod  -                    // The offsetParent's offset without borders (offset + border)
6386        ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6387      )
6388    };
6389
6390  },
6391
6392  _generatePosition: function( event, constrainPosition ) {
6393
6394    var containment, co, top, left,
6395      o = this.options,
6396      scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6397      pageX = event.pageX,
6398      pageY = event.pageY;
6399
6400    // Cache the scroll
6401    if ( !scrollIsRootNode || !this.offset.scroll ) {
6402      this.offset.scroll = {
6403        top: this.scrollParent.scrollTop(),
6404        left: this.scrollParent.scrollLeft()
6405      };
6406    }
6407
6408    /*
6409     * - Position constraining -
6410     * Constrain the position to a mix of grid, containment.
6411     */
6412
6413    // If we are not dragging yet, we won't check for options
6414    if ( constrainPosition ) {
6415      if ( this.containment ) {
6416        if ( this.relativeContainer ){
6417          co = this.relativeContainer.offset();
6418          containment = [
6419            this.containment[ 0 ] + co.left,
6420            this.containment[ 1 ] + co.top,
6421            this.containment[ 2 ] + co.left,
6422            this.containment[ 3 ] + co.top
6423          ];
6424        } else {
6425          containment = this.containment;
6426        }
6427
6428        if (event.pageX - this.offset.click.left < containment[0]) {
6429          pageX = containment[0] + this.offset.click.left;
6430        }
6431        if (event.pageY - this.offset.click.top < containment[1]) {
6432          pageY = containment[1] + this.offset.click.top;
6433        }
6434        if (event.pageX - this.offset.click.left > containment[2]) {
6435          pageX = containment[2] + this.offset.click.left;
6436        }
6437        if (event.pageY - this.offset.click.top > containment[3]) {
6438          pageY = containment[3] + this.offset.click.top;
6439        }
6440      }
6441
6442      if (o.grid) {
6443        //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6444        top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6445        pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
6446
6447        left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6448        pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
6449      }
6450
6451      if ( o.axis === "y" ) {
6452        pageX = this.originalPageX;
6453      }
6454
6455      if ( o.axis === "x" ) {
6456        pageY = this.originalPageY;
6457      }
6458    }
6459
6460    return {
6461      top: (
6462        pageY -                                  // The absolute mouse position
6463        this.offset.click.top  -                        // Click offset (relative to the element)
6464        this.offset.relative.top -                        // Only for relative positioned nodes: Relative offset from element to offset parent
6465        this.offset.parent.top +                        // The offsetParent's offset without borders (offset + border)
6466        ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6467      ),
6468      left: (
6469        pageX -                                  // The absolute mouse position
6470        this.offset.click.left -                        // Click offset (relative to the element)
6471        this.offset.relative.left -                        // Only for relative positioned nodes: Relative offset from element to offset parent
6472        this.offset.parent.left +                        // The offsetParent's offset without borders (offset + border)
6473        ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6474      )
6475    };
6476
6477  },
6478
6479  _clear: function() {
6480    this.helper.removeClass("ui-draggable-dragging");
6481    if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6482      this.helper.remove();
6483    }
6484    this.helper = null;
6485    this.cancelHelperRemoval = false;
6486    if ( this.destroyOnClear ) {
6487      this.destroy();
6488    }
6489  },
6490
6491  _normalizeRightBottom: function() {
6492    if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
6493      this.helper.width( this.helper.width() );
6494      this.helper.css( "right", "auto" );
6495    }
6496    if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
6497      this.helper.height( this.helper.height() );
6498      this.helper.css( "bottom", "auto" );
6499    }
6500  },
6501
6502  // From now on bulk stuff - mainly helpers
6503
6504  _trigger: function( type, event, ui ) {
6505    ui = ui || this._uiHash();
6506    $.ui.plugin.call( this, type, [ event, ui, this ], true );
6507
6508    // Absolute position and offset (see #6884 ) have to be recalculated after plugins
vendor: 12,195 bytes, lines 6509-6840
6509    if ( /^(drag|start|stop)/.test( type ) ) {
6510      this.positionAbs = this._convertPositionTo( "absolute" );
6511      ui.offset = this.positionAbs;
6512    }
6513    return $.Widget.prototype._trigger.call( this, type, event, ui );
6514  },
6515
6516  plugins: {},
6517
6518  _uiHash: function() {
6519    return {
6520      helper: this.helper,
6521      position: this.position,
6522      originalPosition: this.originalPosition,
6523      offset: this.positionAbs
6524    };
6525  }
6526
6527});
6528
6529$.ui.plugin.add( "draggable", "connectToSortable", {
6530  start: function( event, ui, draggable ) {
6531    var uiSortable = $.extend( {}, ui, {
6532      item: draggable.element
6533    });
6534
6535    draggable.sortables = [];
6536    $( draggable.options.connectToSortable ).each(function() {
6537      var sortable = $( this ).sortable( "instance" );
6538
6539      if ( sortable && !sortable.options.disabled ) {
6540        draggable.sortables.push( sortable );
6541
6542        // refreshPositions is called at drag start to refresh the containerCache
6543        // which is used in drag. This ensures it's initialized and synchronized
6544        // with any changes that might have happened on the page since initialization.
6545        sortable.refreshPositions();
6546        sortable._trigger("activate", event, uiSortable);
6547      }
6548    });
6549  },
6550  stop: function( event, ui, draggable ) {
6551    var uiSortable = $.extend( {}, ui, {
6552      item: draggable.element
6553    });
6554
6555    draggable.cancelHelperRemoval = false;
6556
6557    $.each( draggable.sortables, function() {
6558      var sortable = this;
6559
6560      if ( sortable.isOver ) {
6561        sortable.isOver = 0;
6562
6563        // Allow this sortable to handle removing the helper
6564        draggable.cancelHelperRemoval = true;
6565        sortable.cancelHelperRemoval = false;
6566
6567        // Use _storedCSS To restore properties in the sortable,
6568        // as this also handles revert (#9675) since the draggable
6569        // may have modified them in unexpected ways (#8809)
6570        sortable._storedCSS = {
6571          position: sortable.placeholder.css( "position" ),
6572          top: sortable.placeholder.css( "top" ),
6573          left: sortable.placeholder.css( "left" )
6574        };
6575
6576        sortable._mouseStop(event);
6577
6578        // Once drag has ended, the sortable should return to using
6579        // its original helper, not the shared helper from draggable
6580        sortable.options.helper = sortable.options._helper;
6581      } else {
6582        // Prevent this Sortable from removing the helper.
6583        // However, don't set the draggable to remove the helper
6584        // either as another connected Sortable may yet handle the removal.
6585        sortable.cancelHelperRemoval = true;
6586
6587        sortable._trigger( "deactivate", event, uiSortable );
6588      }
6589    });
6590  },
6591  drag: function( event, ui, draggable ) {
6592    $.each( draggable.sortables, function() {
6593      var innermostIntersecting = false,
6594        sortable = this;
6595
6596      // Copy over variables that sortable's _intersectsWith uses
6597      sortable.positionAbs = draggable.positionAbs;
6598      sortable.helperProportions = draggable.helperProportions;
6599      sortable.offset.click = draggable.offset.click;
6600
6601      if ( sortable._intersectsWith( sortable.containerCache ) ) {
6602        innermostIntersecting = true;
6603
6604        $.each( draggable.sortables, function() {
6605          // Copy over variables that sortable's _intersectsWith uses
6606          this.positionAbs = draggable.positionAbs;
6607          this.helperProportions = draggable.helperProportions;
6608          this.offset.click = draggable.offset.click;
6609
6610          if ( this !== sortable &&
6611              this._intersectsWith( this.containerCache ) &&
6612              $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
6613            innermostIntersecting = false;
6614          }
6615
6616          return innermostIntersecting;
6617        });
6618      }
6619
6620      if ( innermostIntersecting ) {
6621        // If it intersects, we use a little isOver variable and set it once,
6622        // so that the move-in stuff gets fired only once.
6623        if ( !sortable.isOver ) {
6624          sortable.isOver = 1;
6625
6626          // Store draggable's parent in case we need to reappend to it later.
6627          draggable._parent = ui.helper.parent();
6628
6629          sortable.currentItem = ui.helper
6630            .appendTo( sortable.element )
6631            .data( "ui-sortable-item", true );
6632
6633          // Store helper option to later restore it
6634          sortable.options._helper = sortable.options.helper;
6635
6636          sortable.options.helper = function() {
6637            return ui.helper[ 0 ];
6638          };
6639
6640          // Fire the start events of the sortable with our passed browser event,
6641          // and our own helper (so it doesn't create a new one)
6642          event.target = sortable.currentItem[ 0 ];
6643          sortable._mouseCapture( event, true );
6644          sortable._mouseStart( event, true, true );
6645
6646          // Because the browser event is way off the new appended portlet,
6647          // modify necessary variables to reflect the changes
6648          sortable.offset.click.top = draggable.offset.click.top;
6649          sortable.offset.click.left = draggable.offset.click.left;
6650          sortable.offset.parent.left -= draggable.offset.parent.left -
6651            sortable.offset.parent.left;
6652          sortable.offset.parent.top -= draggable.offset.parent.top -
6653            sortable.offset.parent.top;
6654
6655          draggable._trigger( "toSortable", event );
6656
6657          // Inform draggable that the helper is in a valid drop zone,
6658          // used solely in the revert option to handle "valid/invalid".
6659          draggable.dropped = sortable.element;
6660
6661          // Need to refreshPositions of all sortables in the case that
6662          // adding to one sortable changes the location of the other sortables (#9675)
6663          $.each( draggable.sortables, function() {
6664            this.refreshPositions();
6665          });
6666
6667          // hack so receive/update callbacks work (mostly)
6668          draggable.currentItem = draggable.element;
6669          sortable.fromOutside = draggable;
6670        }
6671
6672        if ( sortable.currentItem ) {
6673          sortable._mouseDrag( event );
6674          // Copy the sortable's position because the draggable's can potentially reflect
6675          // a relative position, while sortable is always absolute, which the dragged
6676          // element has now become. (#8809)
6677          ui.position = sortable.position;
6678        }
6679      } else {
6680        // If it doesn't intersect with the sortable, and it intersected before,
6681        // we fake the drag stop of the sortable, but make sure it doesn't remove
6682        // the helper by using cancelHelperRemoval.
6683        if ( sortable.isOver ) {
6684
6685          sortable.isOver = 0;
6686          sortable.cancelHelperRemoval = true;
6687
6688          // Calling sortable's mouseStop would trigger a revert,
6689          // so revert must be temporarily false until after mouseStop is called.
6690          sortable.options._revert = sortable.options.revert;
6691          sortable.options.revert = false;
6692
6693          sortable._trigger( "out", event, sortable._uiHash( sortable ) );
6694          sortable._mouseStop( event, true );
6695
6696          // restore sortable behaviors that were modfied
6697          // when the draggable entered the sortable area (#9481)
6698          sortable.options.revert = sortable.options._revert;
6699          sortable.options.helper = sortable.options._helper;
6700
6701          if ( sortable.placeholder ) {
6702            sortable.placeholder.remove();
6703          }
6704
6705          // Restore and recalculate the draggable's offset considering the sortable
6706          // may have modified them in unexpected ways. (#8809, #10669)
6707          ui.helper.appendTo( draggable._parent );
6708          draggable._refreshOffsets( event );
6709          ui.position = draggable._generatePosition( event, true );
6710
6711          draggable._trigger( "fromSortable", event );
6712
6713          // Inform draggable that the helper is no longer in a valid drop zone
6714          draggable.dropped = false;
6715
6716          // Need to refreshPositions of all sortables just in case removing
6717          // from one sortable changes the location of other sortables (#9675)
6718          $.each( draggable.sortables, function() {
6719            this.refreshPositions();
6720          });
6721        }
6722      }
6723    });
6724  }
6725});
6726
6727$.ui.plugin.add("draggable", "cursor", {
6728  start: function( event, ui, instance ) {
6729    var t = $( "body" ),
6730      o = instance.options;
6731
6732    if (t.css("cursor")) {
6733      o._cursor = t.css("cursor");
6734    }
6735    t.css("cursor", o.cursor);
6736  },
6737  stop: function( event, ui, instance ) {
6738    var o = instance.options;
6739    if (o._cursor) {
6740      $("body").css("cursor", o._cursor);
6741    }
6742  }
6743});
6744
6745$.ui.plugin.add("draggable", "opacity", {
6746  start: function( event, ui, instance ) {
6747    var t = $( ui.helper ),
6748      o = instance.options;
6749    if (t.css("opacity")) {
6750      o._opacity = t.css("opacity");
6751    }
6752    t.css("opacity", o.opacity);
6753  },
6754  stop: function( event, ui, instance ) {
6755    var o = instance.options;
6756    if (o._opacity) {
6757      $(ui.helper).css("opacity", o._opacity);
6758    }
6759  }
6760});
6761
6762$.ui.plugin.add("draggable", "scroll", {
6763  start: function( event, ui, i ) {
6764    if ( !i.scrollParentNotHidden ) {
6765      i.scrollParentNotHidden = i.helper.scrollParent( false );
6766    }
6767
6768    if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6769      i.overflowOffset = i.scrollParentNotHidden.offset();
6770    }
6771  },
6772  drag: function( event, ui, i  ) {
6773
6774    var o = i.options,
6775      scrolled = false,
6776      scrollParent = i.scrollParentNotHidden[ 0 ],
6777      document = i.document[ 0 ];
6778
6779    if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6780      if ( !o.axis || o.axis !== "x" ) {
6781        if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6782          scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6783        } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6784          scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6785        }
6786      }
6787
6788      if ( !o.axis || o.axis !== "y" ) {
6789        if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6790          scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6791        } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6792          scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6793        }
6794      }
6795
6796    } else {
6797
6798      if (!o.axis || o.axis !== "x") {
6799        if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6800          scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6801        } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6802          scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6803        }
6804      }
6805
6806      if (!o.axis || o.axis !== "y") {
6807        if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6808          scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6809        } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6810          scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6811        }
6812      }
6813
6814    }
6815
6816    if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6817      $.ui.ddmanager.prepareOffsets(i, event);
6818    }
6819
6820  }
6821});
6822
6823$.ui.plugin.add("draggable", "snap", {
6824  start: function( event, ui, i ) {
6825
6826    var o = i.options;
6827
6828    i.snapElements = [];
6829
6830    $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6831      var $t = $(this),
6832        $o = $t.offset();
6833      if (this !== i.element[0]) {
6834        i.snapElements.push({
6835          item: this,
6836          width: $t.outerWidth(), height: $t.outerHeight(),
6837          top: $o.top, left: $o.left
6838        });
6839      }
6840    });
vendor: 10,234 bytes, lines 6841-7180
6841
6842  },
6843  drag: function( event, ui, inst ) {
6844
6845    var ts, bs, ls, rs, l, r, t, b, i, first,
6846      o = inst.options,
6847      d = o.snapTolerance,
6848      x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6849      y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6850
6851    for (i = inst.snapElements.length - 1; i >= 0; i--){
6852
6853      l = inst.snapElements[i].left - inst.margins.left;
6854      r = l + inst.snapElements[i].width;
6855      t = inst.snapElements[i].top - inst.margins.top;
6856      b = t + inst.snapElements[i].height;
6857
6858      if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6859        if (inst.snapElements[i].snapping) {
6860          (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6861        }
6862        inst.snapElements[i].snapping = false;
6863        continue;
6864      }
6865
6866      if (o.snapMode !== "inner") {
6867        ts = Math.abs(t - y2) <= d;
6868        bs = Math.abs(b - y1) <= d;
6869        ls = Math.abs(l - x2) <= d;
6870        rs = Math.abs(r - x1) <= d;
6871        if (ts) {
6872          ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
6873        }
6874        if (bs) {
6875          ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
6876        }
6877        if (ls) {
6878          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
6879        }
6880        if (rs) {
6881          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
6882        }
6883      }
6884
6885      first = (ts || bs || ls || rs);
6886
6887      if (o.snapMode !== "outer") {
6888        ts = Math.abs(t - y1) <= d;
6889        bs = Math.abs(b - y2) <= d;
6890        ls = Math.abs(l - x1) <= d;
6891        rs = Math.abs(r - x2) <= d;
6892        if (ts) {
6893          ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
6894        }
6895        if (bs) {
6896          ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
6897        }
6898        if (ls) {
6899          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
6900        }
6901        if (rs) {
6902          ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
6903        }
6904      }
6905
6906      if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6907        (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6908      }
6909      inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6910
6911    }
6912
6913  }
6914});
6915
6916$.ui.plugin.add("draggable", "stack", {
6917  start: function( event, ui, instance ) {
6918    var min,
6919      o = instance.options,
6920      group = $.makeArray($(o.stack)).sort(function(a, b) {
6921        return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6922      });
6923
6924    if (!group.length) { return; }
6925
6926    min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6927    $(group).each(function(i) {
6928      $(this).css("zIndex", min + i);
6929    });
6930    this.css("zIndex", (min + group.length));
6931  }
6932});
6933
6934$.ui.plugin.add("draggable", "zIndex", {
6935  start: function( event, ui, instance ) {
6936    var t = $( ui.helper ),
6937      o = instance.options;
6938
6939    if (t.css("zIndex")) {
6940      o._zIndex = t.css("zIndex");
6941    }
6942    t.css("zIndex", o.zIndex);
6943  },
6944  stop: function( event, ui, instance ) {
6945    var o = instance.options;
6946
6947    if (o._zIndex) {
6948      $(ui.helper).css("zIndex", o._zIndex);
6949    }
6950  }
6951});
6952
6953var draggable = $.ui.draggable;
6954
6955
6956/*!
6957 * jQuery UI Resizable 1.11.4
6958 * http://jqueryui.com
6959 *
6960 * Copyright jQuery Foundation and other contributors
6961 * Released under the MIT license.
6962 * http://jquery.org/license
6963 *
6964 * http://api.jqueryui.com/resizable/
6965 */
6966
6967
6968$.widget("ui.resizable", $.ui.mouse, {
6969  version: "1.11.4",
6970  widgetEventPrefix: "resize",
6971  options: {
6972    alsoResize: false,
6973    animate: false,
6974    animateDuration: "slow",
6975    animateEasing: "swing",
6976    aspectRatio: false,
6977    autoHide: false,
6978    containment: false,
6979    ghost: false,
6980    grid: false,
6981    handles: "e,s,se",
6982    helper: false,
6983    maxHeight: null,
6984    maxWidth: null,
6985    minHeight: 10,
6986    minWidth: 10,
6987    // See #7960
6988    zIndex: 90,
6989
6990    // callbacks
6991    resize: null,
6992    start: null,
6993    stop: null
6994  },
6995
6996  _num: function( value ) {
6997    return parseInt( value, 10 ) || 0;
6998  },
6999
7000  _isNumber: function( value ) {
7001    return !isNaN( parseInt( value, 10 ) );
7002  },
7003
7004  _hasScroll: function( el, a ) {
7005
7006    if ( $( el ).css( "overflow" ) === "hidden") {
7007      return false;
7008    }
7009
7010    var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
7011      has = false;
7012
7013    if ( el[ scroll ] > 0 ) {
7014      return true;
7015    }
7016
7017    // TODO: determine which cases actually cause this to happen
7018    // if the element doesn't have the scroll set, see if it's possible to
7019    // set the scroll
7020    el[ scroll ] = 1;
7021    has = ( el[ scroll ] > 0 );
7022    el[ scroll ] = 0;
7023    return has;
7024  },
7025
7026  _create: function() {
7027
7028    var n, i, handle, axis, hname,
7029      that = this,
7030      o = this.options;
7031    this.element.addClass("ui-resizable");
7032
7033    $.extend(this, {
7034      _aspectRatio: !!(o.aspectRatio),
7035      aspectRatio: o.aspectRatio,
7036      originalElement: this.element,
7037      _proportionallyResizeElements: [],
7038      _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
7039    });
7040
7041    // Wrap the element if it cannot hold child nodes
7042    if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
7043
7044      this.element.wrap(
7045        $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
7046          position: this.element.css("position"),
7047          width: this.element.outerWidth(),
7048          height: this.element.outerHeight(),
7049          top: this.element.css("top"),
7050          left: this.element.css("left")
7051        })
7052      );
7053
7054      this.element = this.element.parent().data(
7055        "ui-resizable", this.element.resizable( "instance" )
7056      );
7057
7058      this.elementIsWrapper = true;
7059
7060      this.element.css({
7061        marginLeft: this.originalElement.css("marginLeft"),
7062        marginTop: this.originalElement.css("marginTop"),
7063        marginRight: this.originalElement.css("marginRight"),
7064        marginBottom: this.originalElement.css("marginBottom")
7065      });
7066      this.originalElement.css({
7067        marginLeft: 0,
7068        marginTop: 0,
7069        marginRight: 0,
7070        marginBottom: 0
7071      });
7072      // support: Safari
7073      // Prevent Safari textarea resize
7074      this.originalResizeStyle = this.originalElement.css("resize");
7075      this.originalElement.css("resize", "none");
7076
7077      this._proportionallyResizeElements.push( this.originalElement.css({
7078        position: "static",
7079        zoom: 1,
7080        display: "block"
7081      }) );
7082
7083      // support: IE9
7084      // avoid IE jump (hard set the margin)
7085      this.originalElement.css({ margin: this.originalElement.css("margin") });
7086
7087      this._proportionallyResize();
7088    }
7089
7090    this.handles = o.handles ||
7091      ( !$(".ui-resizable-handle", this.element).length ?
7092        "e,s,se" : {
7093          n: ".ui-resizable-n",
7094          e: ".ui-resizable-e",
7095          s: ".ui-resizable-s",
7096          w: ".ui-resizable-w",
7097          se: ".ui-resizable-se",
7098          sw: ".ui-resizable-sw",
7099          ne: ".ui-resizable-ne",
7100          nw: ".ui-resizable-nw"
7101        } );
7102
7103    this._handles = $();
7104    if ( this.handles.constructor === String ) {
7105
7106      if ( this.handles === "all") {
7107        this.handles = "n,e,s,w,se,sw,ne,nw";
7108      }
7109
7110      n = this.handles.split(",");
7111      this.handles = {};
7112
7113      for (i = 0; i < n.length; i++) {
7114
7115        handle = $.trim(n[i]);
7116        hname = "ui-resizable-" + handle;
7117        axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
7118
7119        axis.css({ zIndex: o.zIndex });
7120
7121        // TODO : What's going on here?
7122        if ("se" === handle) {
7123          axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
7124        }
7125
7126        this.handles[handle] = ".ui-resizable-" + handle;
7127        this.element.append(axis);
7128      }
7129
7130    }
7131
7132    this._renderAxis = function(target) {
7133
7134      var i, axis, padPos, padWrapper;
7135
7136      target = target || this.element;
7137
7138      for (i in this.handles) {
7139
7140        if (this.handles[i].constructor === String) {
7141          this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
7142        } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
7143          this.handles[ i ] = $( this.handles[ i ] );
7144          this._on( this.handles[ i ], { "mousedown": that._mouseDown });
7145        }
7146
7147        if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
7148
7149          axis = $(this.handles[i], this.element);
7150
7151          padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
7152
7153          padPos = [ "padding",
7154            /ne|nw|n/.test(i) ? "Top" :
7155            /se|sw|s/.test(i) ? "Bottom" :
7156            /^e$/.test(i) ? "Right" : "Left" ].join("");
7157
7158          target.css(padPos, padWrapper);
7159
7160          this._proportionallyResize();
7161        }
7162
7163        this._handles = this._handles.add( this.handles[ i ] );
7164      }
7165    };
7166
7167    // TODO: make renderAxis a prototype function
7168    this._renderAxis(this.element);
7169
7170    this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
7171    this._handles.disableSelection();
7172
7173    this._handles.mouseover(function() {
7174      if (!that.resizing) {
7175        if (this.className) {
7176          axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7177        }
7178        that.axis = axis && axis[1] ? axis[1] : "se";
7179      }
7180    });
vendor: 16,721 bytes, lines 7181-7783
7181
7182    if (o.autoHide) {
7183      this._handles.hide();
7184      $(this.element)
7185        .addClass("ui-resizable-autohide")
7186        .mouseenter(function() {
7187          if (o.disabled) {
7188            return;
7189          }
7190          $(this).removeClass("ui-resizable-autohide");
7191          that._handles.show();
7192        })
7193        .mouseleave(function() {
7194          if (o.disabled) {
7195            return;
7196          }
7197          if (!that.resizing) {
7198            $(this).addClass("ui-resizable-autohide");
7199            that._handles.hide();
7200          }
7201        });
7202    }
7203
7204    this._mouseInit();
7205  },
7206
7207  _destroy: function() {
7208
7209    this._mouseDestroy();
7210
7211    var wrapper,
7212      _destroy = function(exp) {
7213        $(exp)
7214          .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7215          .removeData("resizable")
7216          .removeData("ui-resizable")
7217          .unbind(".resizable")
7218          .find(".ui-resizable-handle")
7219            .remove();
7220      };
7221
7222    // TODO: Unwrap at same DOM position
7223    if (this.elementIsWrapper) {
7224      _destroy(this.element);
7225      wrapper = this.element;
7226      this.originalElement.css({
7227        position: wrapper.css("position"),
7228        width: wrapper.outerWidth(),
7229        height: wrapper.outerHeight(),
7230        top: wrapper.css("top"),
7231        left: wrapper.css("left")
7232      }).insertAfter( wrapper );
7233      wrapper.remove();
7234    }
7235
7236    this.originalElement.css("resize", this.originalResizeStyle);
7237    _destroy(this.originalElement);
7238
7239    return this;
7240  },
7241
7242  _mouseCapture: function(event) {
7243    var i, handle,
7244      capture = false;
7245
7246    for (i in this.handles) {
7247      handle = $(this.handles[i])[0];
7248      if (handle === event.target || $.contains(handle, event.target)) {
7249        capture = true;
7250      }
7251    }
7252
7253    return !this.options.disabled && capture;
7254  },
7255
7256  _mouseStart: function(event) {
7257
7258    var curleft, curtop, cursor,
7259      o = this.options,
7260      el = this.element;
7261
7262    this.resizing = true;
7263
7264    this._renderProxy();
7265
7266    curleft = this._num(this.helper.css("left"));
7267    curtop = this._num(this.helper.css("top"));
7268
7269    if (o.containment) {
7270      curleft += $(o.containment).scrollLeft() || 0;
7271      curtop += $(o.containment).scrollTop() || 0;
7272    }
7273
7274    this.offset = this.helper.offset();
7275    this.position = { left: curleft, top: curtop };
7276
7277    this.size = this._helper ? {
7278        width: this.helper.width(),
7279        height: this.helper.height()
7280      } : {
7281        width: el.width(),
7282        height: el.height()
7283      };
7284
7285    this.originalSize = this._helper ? {
7286        width: el.outerWidth(),
7287        height: el.outerHeight()
7288      } : {
7289        width: el.width(),
7290        height: el.height()
7291      };
7292
7293    this.sizeDiff = {
7294      width: el.outerWidth() - el.width(),
7295      height: el.outerHeight() - el.height()
7296    };
7297
7298    this.originalPosition = { left: curleft, top: curtop };
7299    this.originalMousePosition = { left: event.pageX, top: event.pageY };
7300
7301    this.aspectRatio = (typeof o.aspectRatio === "number") ?
7302      o.aspectRatio :
7303      ((this.originalSize.width / this.originalSize.height) || 1);
7304
7305    cursor = $(".ui-resizable-" + this.axis).css("cursor");
7306    $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7307
7308    el.addClass("ui-resizable-resizing");
7309    this._propagate("start", event);
7310    return true;
7311  },
7312
7313  _mouseDrag: function(event) {
7314
7315    var data, props,
7316      smp = this.originalMousePosition,
7317      a = this.axis,
7318      dx = (event.pageX - smp.left) || 0,
7319      dy = (event.pageY - smp.top) || 0,
7320      trigger = this._change[a];
7321
7322    this._updatePrevProperties();
7323
7324    if (!trigger) {
7325      return false;
7326    }
7327
7328    data = trigger.apply(this, [ event, dx, dy ]);
7329
7330    this._updateVirtualBoundaries(event.shiftKey);
7331    if (this._aspectRatio || event.shiftKey) {
7332      data = this._updateRatio(data, event);
7333    }
7334
7335    data = this._respectSize(data, event);
7336
7337    this._updateCache(data);
7338
7339    this._propagate("resize", event);
7340
7341    props = this._applyChanges();
7342
7343    if ( !this._helper && this._proportionallyResizeElements.length ) {
7344      this._proportionallyResize();
7345    }
7346
7347    if ( !$.isEmptyObject( props ) ) {
7348      this._updatePrevProperties();
7349      this._trigger( "resize", event, this.ui() );
7350      this._applyChanges();
7351    }
7352
7353    return false;
7354  },
7355
7356  _mouseStop: function(event) {
7357
7358    this.resizing = false;
7359    var pr, ista, soffseth, soffsetw, s, left, top,
7360      o = this.options, that = this;
7361
7362    if (this._helper) {
7363
7364      pr = this._proportionallyResizeElements;
7365      ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7366      soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7367      soffsetw = ista ? 0 : that.sizeDiff.width;
7368
7369      s = {
7370        width: (that.helper.width()  - soffsetw),
7371        height: (that.helper.height() - soffseth)
7372      };
7373      left = (parseInt(that.element.css("left"), 10) +
7374        (that.position.left - that.originalPosition.left)) || null;
7375      top = (parseInt(that.element.css("top"), 10) +
7376        (that.position.top - that.originalPosition.top)) || null;
7377
7378      if (!o.animate) {
7379        this.element.css($.extend(s, { top: top, left: left }));
7380      }
7381
7382      that.helper.height(that.size.height);
7383      that.helper.width(that.size.width);
7384
7385      if (this._helper && !o.animate) {
7386        this._proportionallyResize();
7387      }
7388    }
7389
7390    $("body").css("cursor", "auto");
7391
7392    this.element.removeClass("ui-resizable-resizing");
7393
7394    this._propagate("stop", event);
7395
7396    if (this._helper) {
7397      this.helper.remove();
7398    }
7399
7400    return false;
7401
7402  },
7403
7404  _updatePrevProperties: function() {
7405    this.prevPosition = {
7406      top: this.position.top,
7407      left: this.position.left
7408    };
7409    this.prevSize = {
7410      width: this.size.width,
7411      height: this.size.height
7412    };
7413  },
7414
7415  _applyChanges: function() {
7416    var props = {};
7417
7418    if ( this.position.top !== this.prevPosition.top ) {
7419      props.top = this.position.top + "px";
7420    }
7421    if ( this.position.left !== this.prevPosition.left ) {
7422      props.left = this.position.left + "px";
7423    }
7424    if ( this.size.width !== this.prevSize.width ) {
7425      props.width = this.size.width + "px";
7426    }
7427    if ( this.size.height !== this.prevSize.height ) {
7428      props.height = this.size.height + "px";
7429    }
7430
7431    this.helper.css( props );
7432
7433    return props;
7434  },
7435
7436  _updateVirtualBoundaries: function(forceAspectRatio) {
7437    var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7438      o = this.options;
7439
7440    b = {
7441      minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7442      maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7443      minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7444      maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7445    };
7446
7447    if (this._aspectRatio || forceAspectRatio) {
7448      pMinWidth = b.minHeight * this.aspectRatio;
7449      pMinHeight = b.minWidth / this.aspectRatio;
7450      pMaxWidth = b.maxHeight * this.aspectRatio;
7451      pMaxHeight = b.maxWidth / this.aspectRatio;
7452
7453      if (pMinWidth > b.minWidth) {
7454        b.minWidth = pMinWidth;
7455      }
7456      if (pMinHeight > b.minHeight) {
7457        b.minHeight = pMinHeight;
7458      }
7459      if (pMaxWidth < b.maxWidth) {
7460        b.maxWidth = pMaxWidth;
7461      }
7462      if (pMaxHeight < b.maxHeight) {
7463        b.maxHeight = pMaxHeight;
7464      }
7465    }
7466    this._vBoundaries = b;
7467  },
7468
7469  _updateCache: function(data) {
7470    this.offset = this.helper.offset();
7471    if (this._isNumber(data.left)) {
7472      this.position.left = data.left;
7473    }
7474    if (this._isNumber(data.top)) {
7475      this.position.top = data.top;
7476    }
7477    if (this._isNumber(data.height)) {
7478      this.size.height = data.height;
7479    }
7480    if (this._isNumber(data.width)) {
7481      this.size.width = data.width;
7482    }
7483  },
7484
7485  _updateRatio: function( data ) {
7486
7487    var cpos = this.position,
7488      csize = this.size,
7489      a = this.axis;
7490
7491    if (this._isNumber(data.height)) {
7492      data.width = (data.height * this.aspectRatio);
7493    } else if (this._isNumber(data.width)) {
7494      data.height = (data.width / this.aspectRatio);
7495    }
7496
7497    if (a === "sw") {
7498      data.left = cpos.left + (csize.width - data.width);
7499      data.top = null;
7500    }
7501    if (a === "nw") {
7502      data.top = cpos.top + (csize.height - data.height);
7503      data.left = cpos.left + (csize.width - data.width);
7504    }
7505
7506    return data;
7507  },
7508
7509  _respectSize: function( data ) {
7510
7511    var o = this._vBoundaries,
7512      a = this.axis,
7513      ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7514      ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7515      isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7516      isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7517      dw = this.originalPosition.left + this.originalSize.width,
7518      dh = this.position.top + this.size.height,
7519      cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7520    if (isminw) {
7521      data.width = o.minWidth;
7522    }
7523    if (isminh) {
7524      data.height = o.minHeight;
7525    }
7526    if (ismaxw) {
7527      data.width = o.maxWidth;
7528    }
7529    if (ismaxh) {
7530      data.height = o.maxHeight;
7531    }
7532
7533    if (isminw && cw) {
7534      data.left = dw - o.minWidth;
7535    }
7536    if (ismaxw && cw) {
7537      data.left = dw - o.maxWidth;
7538    }
7539    if (isminh && ch) {
7540      data.top = dh - o.minHeight;
7541    }
7542    if (ismaxh && ch) {
7543      data.top = dh - o.maxHeight;
7544    }
7545
7546    // Fixing jump error on top/left - bug #2330
7547    if (!data.width && !data.height && !data.left && data.top) {
7548      data.top = null;
7549    } else if (!data.width && !data.height && !data.top && data.left) {
7550      data.left = null;
7551    }
7552
7553    return data;
7554  },
7555
7556  _getPaddingPlusBorderDimensions: function( element ) {
7557    var i = 0,
7558      widths = [],
7559      borders = [
7560        element.css( "borderTopWidth" ),
7561        element.css( "borderRightWidth" ),
7562        element.css( "borderBottomWidth" ),
7563        element.css( "borderLeftWidth" )
7564      ],
7565      paddings = [
7566        element.css( "paddingTop" ),
7567        element.css( "paddingRight" ),
7568        element.css( "paddingBottom" ),
7569        element.css( "paddingLeft" )
7570      ];
7571
7572    for ( ; i < 4; i++ ) {
7573      widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7574      widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7575    }
7576
7577    return {
7578      height: widths[ 0 ] + widths[ 2 ],
7579      width: widths[ 1 ] + widths[ 3 ]
7580    };
7581  },
7582
7583  _proportionallyResize: function() {
7584
7585    if (!this._proportionallyResizeElements.length) {
7586      return;
7587    }
7588
7589    var prel,
7590      i = 0,
7591      element = this.helper || this.element;
7592
7593    for ( ; i < this._proportionallyResizeElements.length; i++) {
7594
7595      prel = this._proportionallyResizeElements[i];
7596
7597      // TODO: Seems like a bug to cache this.outerDimensions
7598      // considering that we are in a loop.
7599      if (!this.outerDimensions) {
7600        this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7601      }
7602
7603      prel.css({
7604        height: (element.height() - this.outerDimensions.height) || 0,
7605        width: (element.width() - this.outerDimensions.width) || 0
7606      });
7607
7608    }
7609
7610  },
7611
7612  _renderProxy: function() {
7613
7614    var el = this.element, o = this.options;
7615    this.elementOffset = el.offset();
7616
7617    if (this._helper) {
7618
7619      this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7620
7621      this.helper.addClass(this._helper).css({
7622        width: this.element.outerWidth() - 1,
7623        height: this.element.outerHeight() - 1,
7624        position: "absolute",
7625        left: this.elementOffset.left + "px",
7626        top: this.elementOffset.top + "px",
7627        zIndex: ++o.zIndex //TODO: Don't modify option
7628      });
7629
7630      this.helper
7631        .appendTo("body")
7632        .disableSelection();
7633
7634    } else {
7635      this.helper = this.element;
7636    }
7637
7638  },
7639
7640  _change: {
7641    e: function(event, dx) {
7642      return { width: this.originalSize.width + dx };
7643    },
7644    w: function(event, dx) {
7645      var cs = this.originalSize, sp = this.originalPosition;
7646      return { left: sp.left + dx, width: cs.width - dx };
7647    },
7648    n: function(event, dx, dy) {
7649      var cs = this.originalSize, sp = this.originalPosition;
7650      return { top: sp.top + dy, height: cs.height - dy };
7651    },
7652    s: function(event, dx, dy) {
7653      return { height: this.originalSize.height + dy };
7654    },
7655    se: function(event, dx, dy) {
7656      return $.extend(this._change.s.apply(this, arguments),
7657        this._change.e.apply(this, [ event, dx, dy ]));
7658    },
7659    sw: function(event, dx, dy) {
7660      return $.extend(this._change.s.apply(this, arguments),
7661        this._change.w.apply(this, [ event, dx, dy ]));
7662    },
7663    ne: function(event, dx, dy) {
7664      return $.extend(this._change.n.apply(this, arguments),
7665        this._change.e.apply(this, [ event, dx, dy ]));
7666    },
7667    nw: function(event, dx, dy) {
7668      return $.extend(this._change.n.apply(this, arguments),
7669        this._change.w.apply(this, [ event, dx, dy ]));
7670    }
7671  },
7672
7673  _propagate: function(n, event) {
7674    $.ui.plugin.call(this, n, [ event, this.ui() ]);
7675    (n !== "resize" && this._trigger(n, event, this.ui()));
7676  },
7677
7678  plugins: {},
7679
7680  ui: function() {
7681    return {
7682      originalElement: this.originalElement,
7683      element: this.element,
7684      helper: this.helper,
7685      position: this.position,
7686      size: this.size,
7687      originalSize: this.originalSize,
7688      originalPosition: this.originalPosition
7689    };
7690  }
7691
7692});
7693
7694/*
7695 * Resizable Extensions
7696 */
7697
7698$.ui.plugin.add("resizable", "animate", {
7699
7700  stop: function( event ) {
7701    var that = $(this).resizable( "instance" ),
7702      o = that.options,
7703      pr = that._proportionallyResizeElements,
7704      ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7705      soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7706      soffsetw = ista ? 0 : that.sizeDiff.width,
7707      style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7708      left = (parseInt(that.element.css("left"), 10) +
7709        (that.position.left - that.originalPosition.left)) || null,
7710      top = (parseInt(that.element.css("top"), 10) +
7711        (that.position.top - that.originalPosition.top)) || null;
7712
7713    that.element.animate(
7714      $.extend(style, top && left ? { top: top, left: left } : {}), {
7715        duration: o.animateDuration,
7716        easing: o.animateEasing,
7717        step: function() {
7718
7719          var data = {
7720            width: parseInt(that.element.css("width"), 10),
7721            height: parseInt(that.element.css("height"), 10),
7722            top: parseInt(that.element.css("top"), 10),
7723            left: parseInt(that.element.css("left"), 10)
7724          };
7725
7726          if (pr && pr.length) {
7727            $(pr[0]).css({ width: data.width, height: data.height });
7728          }
7729
7730          // propagating resize, and updating values for each animation step
7731          that._updateCache(data);
7732          that._propagate("resize", event);
7733
7734        }
7735      }
7736    );
7737  }
7738
7739});
7740
7741$.ui.plugin.add( "resizable", "containment", {
7742
7743  start: function() {
7744    var element, p, co, ch, cw, width, height,
7745      that = $( this ).resizable( "instance" ),
7746      o = that.options,
7747      el = that.element,
7748      oc = o.containment,
7749      ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7750
7751    if ( !ce ) {
7752      return;
7753    }
7754
7755    that.containerElement = $( ce );
7756
7757    if ( /document/.test( oc ) || oc === document ) {
7758      that.containerOffset = {
7759        left: 0,
7760        top: 0
7761      };
7762      that.containerPosition = {
7763        left: 0,
7764        top: 0
7765      };
7766
7767      that.parentData = {
7768        element: $( document ),
7769        left: 0,
7770        top: 0,
7771        width: $( document ).width(),
7772        height: $( document ).height() || document.body.parentNode.scrollHeight
7773      };
7774    } else {
7775      element = $( ce );
7776      p = [];
7777      $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7778        p[ i ] = that._num( element.css( "padding" + name ) );
7779      });
7780
7781      that.containerOffset = element.offset();
7782      that.containerPosition = element.position();
7783      that.containerSize = {
vendor: 9,045 bytes, lines 7784-8095
7784        height: ( element.innerHeight() - p[ 3 ] ),
7785        width: ( element.innerWidth() - p[ 1 ] )
7786      };
7787
7788      co = that.containerOffset;
7789      ch = that.containerSize.height;
7790      cw = that.containerSize.width;
7791      width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7792      height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7793
7794      that.parentData = {
7795        element: ce,
7796        left: co.left,
7797        top: co.top,
7798        width: width,
7799        height: height
7800      };
7801    }
7802  },
7803
7804  resize: function( event ) {
7805    var woset, hoset, isParent, isOffsetRelative,
7806      that = $( this ).resizable( "instance" ),
7807      o = that.options,
7808      co = that.containerOffset,
7809      cp = that.position,
7810      pRatio = that._aspectRatio || event.shiftKey,
7811      cop = {
7812        top: 0,
7813        left: 0
7814      },
7815      ce = that.containerElement,
7816      continueResize = true;
7817
7818    if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7819      cop = co;
7820    }
7821
7822    if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7823      that.size.width = that.size.width +
7824        ( that._helper ?
7825          ( that.position.left - co.left ) :
7826          ( that.position.left - cop.left ) );
7827
7828      if ( pRatio ) {
7829        that.size.height = that.size.width / that.aspectRatio;
7830        continueResize = false;
7831      }
7832      that.position.left = o.helper ? co.left : 0;
7833    }
7834
7835    if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7836      that.size.height = that.size.height +
7837        ( that._helper ?
7838          ( that.position.top - co.top ) :
7839          that.position.top );
7840
7841      if ( pRatio ) {
7842        that.size.width = that.size.height * that.aspectRatio;
7843        continueResize = false;
7844      }
7845      that.position.top = that._helper ? co.top : 0;
7846    }
7847
7848    isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7849    isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7850
7851    if ( isParent && isOffsetRelative ) {
7852      that.offset.left = that.parentData.left + that.position.left;
7853      that.offset.top = that.parentData.top + that.position.top;
7854    } else {
7855      that.offset.left = that.element.offset().left;
7856      that.offset.top = that.element.offset().top;
7857    }
7858
7859    woset = Math.abs( that.sizeDiff.width +
7860      (that._helper ?
7861        that.offset.left - cop.left :
7862        (that.offset.left - co.left)) );
7863
7864    hoset = Math.abs( that.sizeDiff.height +
7865      (that._helper ?
7866        that.offset.top - cop.top :
7867        (that.offset.top - co.top)) );
7868
7869    if ( woset + that.size.width >= that.parentData.width ) {
7870      that.size.width = that.parentData.width - woset;
7871      if ( pRatio ) {
7872        that.size.height = that.size.width / that.aspectRatio;
7873        continueResize = false;
7874      }
7875    }
7876
7877    if ( hoset + that.size.height >= that.parentData.height ) {
7878      that.size.height = that.parentData.height - hoset;
7879      if ( pRatio ) {
7880        that.size.width = that.size.height * that.aspectRatio;
7881        continueResize = false;
7882      }
7883    }
7884
7885    if ( !continueResize ) {
7886      that.position.left = that.prevPosition.left;
7887      that.position.top = that.prevPosition.top;
7888      that.size.width = that.prevSize.width;
7889      that.size.height = that.prevSize.height;
7890    }
7891  },
7892
7893  stop: function() {
7894    var that = $( this ).resizable( "instance" ),
7895      o = that.options,
7896      co = that.containerOffset,
7897      cop = that.containerPosition,
7898      ce = that.containerElement,
7899      helper = $( that.helper ),
7900      ho = helper.offset(),
7901      w = helper.outerWidth() - that.sizeDiff.width,
7902      h = helper.outerHeight() - that.sizeDiff.height;
7903
7904    if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7905      $( this ).css({
7906        left: ho.left - cop.left - co.left,
7907        width: w,
7908        height: h
7909      });
7910    }
7911
7912    if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7913      $( this ).css({
7914        left: ho.left - cop.left - co.left,
7915        width: w,
7916        height: h
7917      });
7918    }
7919  }
7920});
7921
7922$.ui.plugin.add("resizable", "alsoResize", {
7923
7924  start: function() {
7925    var that = $(this).resizable( "instance" ),
7926      o = that.options;
7927
7928    $(o.alsoResize).each(function() {
7929      var el = $(this);
7930      el.data("ui-resizable-alsoresize", {
7931        width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7932        left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7933      });
7934    });
7935  },
7936
7937  resize: function(event, ui) {
7938    var that = $(this).resizable( "instance" ),
7939      o = that.options,
7940      os = that.originalSize,
7941      op = that.originalPosition,
7942      delta = {
7943        height: (that.size.height - os.height) || 0,
7944        width: (that.size.width - os.width) || 0,
7945        top: (that.position.top - op.top) || 0,
7946        left: (that.position.left - op.left) || 0
7947      };
7948
7949      $(o.alsoResize).each(function() {
7950        var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7951          css = el.parents(ui.originalElement[0]).length ?
7952              [ "width", "height" ] :
7953              [ "width", "height", "top", "left" ];
7954
7955        $.each(css, function(i, prop) {
7956          var sum = (start[prop] || 0) + (delta[prop] || 0);
7957          if (sum && sum >= 0) {
7958            style[prop] = sum || null;
7959          }
7960        });
7961
7962        el.css(style);
7963      });
7964  },
7965
7966  stop: function() {
7967    $(this).removeData("resizable-alsoresize");
7968  }
7969});
7970
7971$.ui.plugin.add("resizable", "ghost", {
7972
7973  start: function() {
7974
7975    var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7976
7977    that.ghost = that.originalElement.clone();
7978    that.ghost
7979      .css({
7980        opacity: 0.25,
7981        display: "block",
7982        position: "relative",
7983        height: cs.height,
7984        width: cs.width,
7985        margin: 0,
7986        left: 0,
7987        top: 0
7988      })
7989      .addClass("ui-resizable-ghost")
7990      .addClass(typeof o.ghost === "string" ? o.ghost : "");
7991
7992    that.ghost.appendTo(that.helper);
7993
7994  },
7995
7996  resize: function() {
7997    var that = $(this).resizable( "instance" );
7998    if (that.ghost) {
7999      that.ghost.css({
8000        position: "relative",
8001        height: that.size.height,
8002        width: that.size.width
8003      });
8004    }
8005  },
8006
8007  stop: function() {
8008    var that = $(this).resizable( "instance" );
8009    if (that.ghost && that.helper) {
8010      that.helper.get(0).removeChild(that.ghost.get(0));
8011    }
8012  }
8013
8014});
8015
8016$.ui.plugin.add("resizable", "grid", {
8017
8018  resize: function() {
8019    var outerDimensions,
8020      that = $(this).resizable( "instance" ),
8021      o = that.options,
8022      cs = that.size,
8023      os = that.originalSize,
8024      op = that.originalPosition,
8025      a = that.axis,
8026      grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
8027      gridX = (grid[0] || 1),
8028      gridY = (grid[1] || 1),
8029      ox = Math.round((cs.width - os.width) / gridX) * gridX,
8030      oy = Math.round((cs.height - os.height) / gridY) * gridY,
8031      newWidth = os.width + ox,
8032      newHeight = os.height + oy,
8033      isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
8034      isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
8035      isMinWidth = o.minWidth && (o.minWidth > newWidth),
8036      isMinHeight = o.minHeight && (o.minHeight > newHeight);
8037
8038    o.grid = grid;
8039
8040    if (isMinWidth) {
8041      newWidth += gridX;
8042    }
8043    if (isMinHeight) {
8044      newHeight += gridY;
8045    }
8046    if (isMaxWidth) {
8047      newWidth -= gridX;
8048    }
8049    if (isMaxHeight) {
8050      newHeight -= gridY;
8051    }
8052
8053    if (/^(se|s|e)$/.test(a)) {
8054      that.size.width = newWidth;
8055      that.size.height = newHeight;
8056    } else if (/^(ne)$/.test(a)) {
8057      that.size.width = newWidth;
8058      that.size.height = newHeight;
8059      that.position.top = op.top - oy;
8060    } else if (/^(sw)$/.test(a)) {
8061      that.size.width = newWidth;
8062      that.size.height = newHeight;
8063      that.position.left = op.left - ox;
8064    } else {
8065      if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
8066        outerDimensions = that._getPaddingPlusBorderDimensions( this );
8067      }
8068
8069      if ( newHeight - gridY > 0 ) {
8070        that.size.height = newHeight;
8071        that.position.top = op.top - oy;
8072      } else {
8073        newHeight = gridY - outerDimensions.height;
8074        that.size.height = newHeight;
8075        that.position.top = op.top + os.height - newHeight;
8076      }
8077      if ( newWidth - gridX > 0 ) {
8078        that.size.width = newWidth;
8079        that.position.left = op.left - ox;
8080      } else {
8081        newWidth = gridX - outerDimensions.width;
8082        that.size.width = newWidth;
8083        that.position.left = op.left + os.width - newWidth;
8084      }
8085    }
8086  }
8087
8088});
8089
8090var resizable = $.ui.resizable;
8091
8092
8093/*!
8094 * jQuery UI Dialog 1.11.4
8095 * http://jqueryui.com
vendor: 28,919 bytes, lines 8096-9124
8096 *
8097 * Copyright jQuery Foundation and other contributors
8098 * Released under the MIT license.
8099 * http://jquery.org/license
8100 *
8101 * http://api.jqueryui.com/dialog/
8102 */
8103
8104
8105var dialog = $.widget( "ui.dialog", {
8106  version: "1.11.4",
8107  options: {
8108    appendTo: "body",
8109    autoOpen: true,
8110    buttons: [],
8111    closeOnEscape: true,
8112    closeText: "Close",
8113    dialogClass: "",
8114    draggable: true,
8115    hide: null,
8116    height: "auto",
8117    maxHeight: null,
8118    maxWidth: null,
8119    minHeight: 150,
8120    minWidth: 150,
8121    modal: false,
8122    position: {
8123      my: "center",
8124      at: "center",
8125      of: window,
8126      collision: "fit",
8127      // Ensure the titlebar is always visible
8128      using: function( pos ) {
8129        var topOffset = $( this ).css( pos ).offset().top;
8130        if ( topOffset < 0 ) {
8131          $( this ).css( "top", pos.top - topOffset );
8132        }
8133      }
8134    },
8135    resizable: true,
8136    show: null,
8137    title: null,
8138    width: 300,
8139
8140    // callbacks
8141    beforeClose: null,
8142    close: null,
8143    drag: null,
8144    dragStart: null,
8145    dragStop: null,
8146    focus: null,
8147    open: null,
8148    resize: null,
8149    resizeStart: null,
8150    resizeStop: null
8151  },
8152
8153  sizeRelatedOptions: {
8154    buttons: true,
8155    height: true,
8156    maxHeight: true,
8157    maxWidth: true,
8158    minHeight: true,
8159    minWidth: true,
8160    width: true
8161  },
8162
8163  resizableRelatedOptions: {
8164    maxHeight: true,
8165    maxWidth: true,
8166    minHeight: true,
8167    minWidth: true
8168  },
8169
8170  _create: function() {
8171    this.originalCss = {
8172      display: this.element[ 0 ].style.display,
8173      width: this.element[ 0 ].style.width,
8174      minHeight: this.element[ 0 ].style.minHeight,
8175      maxHeight: this.element[ 0 ].style.maxHeight,
8176      height: this.element[ 0 ].style.height
8177    };
8178    this.originalPosition = {
8179      parent: this.element.parent(),
8180      index: this.element.parent().children().index( this.element )
8181    };
8182    this.originalTitle = this.element.attr( "title" );
8183    this.options.title = this.options.title || this.originalTitle;
8184
8185    this._createWrapper();
8186
8187    this.element
8188      .show()
8189      .removeAttr( "title" )
8190      .addClass( "ui-dialog-content ui-widget-content" )
8191      .appendTo( this.uiDialog );
8192
8193    this._createTitlebar();
8194    this._createButtonPane();
8195
8196    if ( this.options.draggable && $.fn.draggable ) {
8197      this._makeDraggable();
8198    }
8199    if ( this.options.resizable && $.fn.resizable ) {
8200      this._makeResizable();
8201    }
8202
8203    this._isOpen = false;
8204
8205    this._trackFocus();
8206  },
8207
8208  _init: function() {
8209    if ( this.options.autoOpen ) {
8210      this.open();
8211    }
8212  },
8213
8214  _appendTo: function() {
8215    var element = this.options.appendTo;
8216    if ( element && (element.jquery || element.nodeType) ) {
8217      return $( element );
8218    }
8219    return this.document.find( element || "body" ).eq( 0 );
8220  },
8221
8222  _destroy: function() {
8223    var next,
8224      originalPosition = this.originalPosition;
8225
8226    this._untrackInstance();
8227    this._destroyOverlay();
8228
8229    this.element
8230      .removeUniqueId()
8231      .removeClass( "ui-dialog-content ui-widget-content" )
8232      .css( this.originalCss )
8233      // Without detaching first, the following becomes really slow
8234      .detach();
8235
8236    this.uiDialog.stop( true, true ).remove();
8237
8238    if ( this.originalTitle ) {
8239      this.element.attr( "title", this.originalTitle );
8240    }
8241
8242    next = originalPosition.parent.children().eq( originalPosition.index );
8243    // Don't try to place the dialog next to itself (#8613)
8244    if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8245      next.before( this.element );
8246    } else {
8247      originalPosition.parent.append( this.element );
8248    }
8249  },
8250
8251  widget: function() {
8252    return this.uiDialog;
8253  },
8254
8255  disable: $.noop,
8256  enable: $.noop,
8257
8258  close: function( event ) {
8259    var activeElement,
8260      that = this;
8261
8262    if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8263      return;
8264    }
8265
8266    this._isOpen = false;
8267    this._focusedElement = null;
8268    this._destroyOverlay();
8269    this._untrackInstance();
8270
8271    if ( !this.opener.filter( ":focusable" ).focus().length ) {
8272
8273      // support: IE9
8274      // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8275      try {
8276        activeElement = this.document[ 0 ].activeElement;
8277
8278        // Support: IE9, IE10
8279        // If the <body> is blurred, IE will switch windows, see #4520
8280        if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8281
8282          // Hiding a focused element doesn't trigger blur in WebKit
8283          // so in case we have nothing to focus on, explicitly blur the active element
8284          // https://bugs.webkit.org/show_bug.cgi?id=47182
8285          $( activeElement ).blur();
8286        }
8287      } catch ( error ) {}
8288    }
8289
8290    this._hide( this.uiDialog, this.options.hide, function() {
8291      that._trigger( "close", event );
8292    });
8293  },
8294
8295  isOpen: function() {
8296    return this._isOpen;
8297  },
8298
8299  moveToTop: function() {
8300    this._moveToTop();
8301  },
8302
8303  _moveToTop: function( event, silent ) {
8304    var moved = false,
8305      zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8306        return +$( this ).css( "z-index" );
8307      }).get(),
8308      zIndexMax = Math.max.apply( null, zIndices );
8309
8310    if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8311      this.uiDialog.css( "z-index", zIndexMax + 1 );
8312      moved = true;
8313    }
8314
8315    if ( moved && !silent ) {
8316      this._trigger( "focus", event );
8317    }
8318    return moved;
8319  },
8320
8321  open: function() {
8322    var that = this;
8323    if ( this._isOpen ) {
8324      if ( this._moveToTop() ) {
8325        this._focusTabbable();
8326      }
8327      return;
8328    }
8329
8330    this._isOpen = true;
8331    this.opener = $( this.document[ 0 ].activeElement );
8332
8333    this._size();
8334    this._position();
8335    this._createOverlay();
8336    this._moveToTop( null, true );
8337
8338    // Ensure the overlay is moved to the top with the dialog, but only when
8339    // opening. The overlay shouldn't move after the dialog is open so that
8340    // modeless dialogs opened after the modal dialog stack properly.
8341    if ( this.overlay ) {
8342      this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8343    }
8344
8345    this._show( this.uiDialog, this.options.show, function() {
8346      that._focusTabbable();
8347      that._trigger( "focus" );
8348    });
8349
8350    // Track the dialog immediately upon openening in case a focus event
8351    // somehow occurs outside of the dialog before an element inside the
8352    // dialog is focused (#10152)
8353    this._makeFocusTarget();
8354
8355    this._trigger( "open" );
8356  },
8357
8358  _focusTabbable: function() {
8359    // Set focus to the first match:
8360    // 1. An element that was focused previously
8361    // 2. First element inside the dialog matching [autofocus]
8362    // 3. Tabbable element inside the content element
8363    // 4. Tabbable element inside the buttonpane
8364    // 5. The close button
8365    // 6. The dialog itself
8366    var hasFocus = this._focusedElement;
8367    if ( !hasFocus ) {
8368      hasFocus = this.element.find( "[autofocus]" );
8369    }
8370    if ( !hasFocus.length ) {
8371      hasFocus = this.element.find( ":tabbable" );
8372    }
8373    if ( !hasFocus.length ) {
8374      hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8375    }
8376    if ( !hasFocus.length ) {
8377      hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8378    }
8379    if ( !hasFocus.length ) {
8380      hasFocus = this.uiDialog;
8381    }
8382    hasFocus.eq( 0 ).focus();
8383  },
8384
8385  _keepFocus: function( event ) {
8386    function checkFocus() {
8387      var activeElement = this.document[0].activeElement,
8388        isActive = this.uiDialog[0] === activeElement ||
8389          $.contains( this.uiDialog[0], activeElement );
8390      if ( !isActive ) {
8391        this._focusTabbable();
8392      }
8393    }
8394    event.preventDefault();
8395    checkFocus.call( this );
8396    // support: IE
8397    // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8398    // so we check again later
8399    this._delay( checkFocus );
8400  },
8401
8402  _createWrapper: function() {
8403    this.uiDialog = $("<div>")
8404      .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8405        this.options.dialogClass )
8406      .hide()
8407      .attr({
8408        // Setting tabIndex makes the div focusable
8409        tabIndex: -1,
8410        role: "dialog"
8411      })
8412      .appendTo( this._appendTo() );
8413
8414    this._on( this.uiDialog, {
8415      keydown: function( event ) {
8416        if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8417            event.keyCode === $.ui.keyCode.ESCAPE ) {
8418          event.preventDefault();
8419          this.close( event );
8420          return;
8421        }
8422
8423        // prevent tabbing out of dialogs
8424        if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8425          return;
8426        }
8427        var tabbables = this.uiDialog.find( ":tabbable" ),
8428          first = tabbables.filter( ":first" ),
8429          last = tabbables.filter( ":last" );
8430
8431        if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8432          this._delay(function() {
8433            first.focus();
8434          });
8435          event.preventDefault();
8436        } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8437          this._delay(function() {
8438            last.focus();
8439          });
8440          event.preventDefault();
8441        }
8442      },
8443      mousedown: function( event ) {
8444        if ( this._moveToTop( event ) ) {
8445          this._focusTabbable();
8446        }
8447      }
8448    });
8449
8450    // We assume that any existing aria-describedby attribute means
8451    // that the dialog content is marked up properly
8452    // otherwise we brute force the content as the description
8453    if ( !this.element.find( "[aria-describedby]" ).length ) {
8454      this.uiDialog.attr({
8455        "aria-describedby": this.element.uniqueId().attr( "id" )
8456      });
8457    }
8458  },
8459
8460  _createTitlebar: function() {
8461    var uiDialogTitle;
8462
8463    this.uiDialogTitlebar = $( "<div>" )
8464      .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8465      .prependTo( this.uiDialog );
8466    this._on( this.uiDialogTitlebar, {
8467      mousedown: function( event ) {
8468        // Don't prevent click on close button (#8838)
8469        // Focusing a dialog that is partially scrolled out of view
8470        // causes the browser to scroll it into view, preventing the click event
8471        if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8472          // Dialog isn't getting focus when dragging (#8063)
8473          this.uiDialog.focus();
8474        }
8475      }
8476    });
8477
8478    // support: IE
8479    // Use type="button" to prevent enter keypresses in textboxes from closing the
8480    // dialog in IE (#9312)
8481    this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8482      .button({
8483        label: this.options.closeText,
8484        icons: {
8485          primary: "ui-icon-closethick"
8486        },
8487        text: false
8488      })
8489      .addClass( "ui-dialog-titlebar-close" )
8490      .appendTo( this.uiDialogTitlebar );
8491    this._on( this.uiDialogTitlebarClose, {
8492      click: function( event ) {
8493        event.preventDefault();
8494        this.close( event );
8495      }
8496    });
8497
8498    uiDialogTitle = $( "<span>" )
8499      .uniqueId()
8500      .addClass( "ui-dialog-title" )
8501      .prependTo( this.uiDialogTitlebar );
8502    this._title( uiDialogTitle );
8503
8504    this.uiDialog.attr({
8505      "aria-labelledby": uiDialogTitle.attr( "id" )
8506    });
8507  },
8508
8509  _title: function( title ) {
8510    if ( !this.options.title ) {
8511      title.html( "&#160;" );
8512    }
8513    title.text( this.options.title );
8514  },
8515
8516  _createButtonPane: function() {
8517    this.uiDialogButtonPane = $( "<div>" )
8518      .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8519
8520    this.uiButtonSet = $( "<div>" )
8521      .addClass( "ui-dialog-buttonset" )
8522      .appendTo( this.uiDialogButtonPane );
8523
8524    this._createButtons();
8525  },
8526
8527  _createButtons: function() {
8528    var that = this,
8529      buttons = this.options.buttons;
8530
8531    // if we already have a button pane, remove it
8532    this.uiDialogButtonPane.remove();
8533    this.uiButtonSet.empty();
8534
8535    if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8536      this.uiDialog.removeClass( "ui-dialog-buttons" );
8537      return;
8538    }
8539
8540    $.each( buttons, function( name, props ) {
8541      var click, buttonOptions;
8542      props = $.isFunction( props ) ?
8543        { click: props, text: name } :
8544        props;
8545      // Default to a non-submitting button
8546      props = $.extend( { type: "button" }, props );
8547      // Change the context for the click callback to be the main element
8548      click = props.click;
8549      props.click = function() {
8550        click.apply( that.element[ 0 ], arguments );
8551      };
8552      buttonOptions = {
8553        icons: props.icons,
8554        text: props.showText
8555      };
8556      delete props.icons;
8557      delete props.showText;
8558      $( "<button></button>", props )
8559        .button( buttonOptions )
8560        .appendTo( that.uiButtonSet );
8561    });
8562    this.uiDialog.addClass( "ui-dialog-buttons" );
8563    this.uiDialogButtonPane.appendTo( this.uiDialog );
8564  },
8565
8566  _makeDraggable: function() {
8567    var that = this,
8568      options = this.options;
8569
8570    function filteredUi( ui ) {
8571      return {
8572        position: ui.position,
8573        offset: ui.offset
8574      };
8575    }
8576
8577    this.uiDialog.draggable({
8578      cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8579      handle: ".ui-dialog-titlebar",
8580      containment: "document",
8581      start: function( event, ui ) {
8582        $( this ).addClass( "ui-dialog-dragging" );
8583        that._blockFrames();
8584        that._trigger( "dragStart", event, filteredUi( ui ) );
8585      },
8586      drag: function( event, ui ) {
8587        that._trigger( "drag", event, filteredUi( ui ) );
8588      },
8589      stop: function( event, ui ) {
8590        var left = ui.offset.left - that.document.scrollLeft(),
8591          top = ui.offset.top - that.document.scrollTop();
8592
8593        options.position = {
8594          my: "left top",
8595          at: "left" + (left >= 0 ? "+" : "") + left + " " +
8596            "top" + (top >= 0 ? "+" : "") + top,
8597          of: that.window
8598        };
8599        $( this ).removeClass( "ui-dialog-dragging" );
8600        that._unblockFrames();
8601        that._trigger( "dragStop", event, filteredUi( ui ) );
8602      }
8603    });
8604  },
8605
8606  _makeResizable: function() {
8607    var that = this,
8608      options = this.options,
8609      handles = options.resizable,
8610      // .ui-resizable has position: relative defined in the stylesheet
8611      // but dialogs have to use absolute or fixed positioning
8612      position = this.uiDialog.css("position"),
8613      resizeHandles = typeof handles === "string" ?
8614        handles  :
8615        "n,e,s,w,se,sw,ne,nw";
8616
8617    function filteredUi( ui ) {
8618      return {
8619        originalPosition: ui.originalPosition,
8620        originalSize: ui.originalSize,
8621        position: ui.position,
8622        size: ui.size
8623      };
8624    }
8625
8626    this.uiDialog.resizable({
8627      cancel: ".ui-dialog-content",
8628      containment: "document",
8629      alsoResize: this.element,
8630      maxWidth: options.maxWidth,
8631      maxHeight: options.maxHeight,
8632      minWidth: options.minWidth,
8633      minHeight: this._minHeight(),
8634      handles: resizeHandles,
8635      start: function( event, ui ) {
8636        $( this ).addClass( "ui-dialog-resizing" );
8637        that._blockFrames();
8638        that._trigger( "resizeStart", event, filteredUi( ui ) );
8639      },
8640      resize: function( event, ui ) {
8641        that._trigger( "resize", event, filteredUi( ui ) );
8642      },
8643      stop: function( event, ui ) {
8644        var offset = that.uiDialog.offset(),
8645          left = offset.left - that.document.scrollLeft(),
8646          top = offset.top - that.document.scrollTop();
8647
8648        options.height = that.uiDialog.height();
8649        options.width = that.uiDialog.width();
8650        options.position = {
8651          my: "left top",
8652          at: "left" + (left >= 0 ? "+" : "") + left + " " +
8653            "top" + (top >= 0 ? "+" : "") + top,
8654          of: that.window
8655        };
8656        $( this ).removeClass( "ui-dialog-resizing" );
8657        that._unblockFrames();
8658        that._trigger( "resizeStop", event, filteredUi( ui ) );
8659      }
8660    })
8661    .css( "position", position );
8662  },
8663
8664  _trackFocus: function() {
8665    this._on( this.widget(), {
8666      focusin: function( event ) {
8667        this._makeFocusTarget();
8668        this._focusedElement = $( event.target );
8669      }
8670    });
8671  },
8672
8673  _makeFocusTarget: function() {
8674    this._untrackInstance();
8675    this._trackingInstances().unshift( this );
8676  },
8677
8678  _untrackInstance: function() {
8679    var instances = this._trackingInstances(),
8680      exists = $.inArray( this, instances );
8681    if ( exists !== -1 ) {
8682      instances.splice( exists, 1 );
8683    }
8684  },
8685
8686  _trackingInstances: function() {
8687    var instances = this.document.data( "ui-dialog-instances" );
8688    if ( !instances ) {
8689      instances = [];
8690      this.document.data( "ui-dialog-instances", instances );
8691    }
8692    return instances;
8693  },
8694
8695  _minHeight: function() {
8696    var options = this.options;
8697
8698    return options.height === "auto" ?
8699      options.minHeight :
8700      Math.min( options.minHeight, options.height );
8701  },
8702
8703  _position: function() {
8704    // Need to show the dialog to get the actual offset in the position plugin
8705    var isVisible = this.uiDialog.is( ":visible" );
8706    if ( !isVisible ) {
8707      this.uiDialog.show();
8708    }
8709    this.uiDialog.position( this.options.position );
8710    if ( !isVisible ) {
8711      this.uiDialog.hide();
8712    }
8713  },
8714
8715  _setOptions: function( options ) {
8716    var that = this,
8717      resize = false,
8718      resizableOptions = {};
8719
8720    $.each( options, function( key, value ) {
8721      that._setOption( key, value );
8722
8723      if ( key in that.sizeRelatedOptions ) {
8724        resize = true;
8725      }
8726      if ( key in that.resizableRelatedOptions ) {
8727        resizableOptions[ key ] = value;
8728      }
8729    });
8730
8731    if ( resize ) {
8732      this._size();
8733      this._position();
8734    }
8735    if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8736      this.uiDialog.resizable( "option", resizableOptions );
8737    }
8738  },
8739
8740  _setOption: function( key, value ) {
8741    var isDraggable, isResizable,
8742      uiDialog = this.uiDialog;
8743
8744    if ( key === "dialogClass" ) {
8745      uiDialog
8746        .removeClass( this.options.dialogClass )
8747        .addClass( value );
8748    }
8749
8750    if ( key === "disabled" ) {
8751      return;
8752    }
8753
8754    this._super( key, value );
8755
8756    if ( key === "appendTo" ) {
8757      this.uiDialog.appendTo( this._appendTo() );
8758    }
8759
8760    if ( key === "buttons" ) {
8761      this._createButtons();
8762    }
8763
8764    if ( key === "closeText" ) {
8765      this.uiDialogTitlebarClose.button({
8766        // Ensure that we always pass a string
8767        label: "" + value
8768      });
8769    }
8770
8771    if ( key === "draggable" ) {
8772      isDraggable = uiDialog.is( ":data(ui-draggable)" );
8773      if ( isDraggable && !value ) {
8774        uiDialog.draggable( "destroy" );
8775      }
8776
8777      if ( !isDraggable && value ) {
8778        this._makeDraggable();
8779      }
8780    }
8781
8782    if ( key === "position" ) {
8783      this._position();
8784    }
8785
8786    if ( key === "resizable" ) {
8787      // currently resizable, becoming non-resizable
8788      isResizable = uiDialog.is( ":data(ui-resizable)" );
8789      if ( isResizable && !value ) {
8790        uiDialog.resizable( "destroy" );
8791      }
8792
8793      // currently resizable, changing handles
8794      if ( isResizable && typeof value === "string" ) {
8795        uiDialog.resizable( "option", "handles", value );
8796      }
8797
8798      // currently non-resizable, becoming resizable
8799      if ( !isResizable && value !== false ) {
8800        this._makeResizable();
8801      }
8802    }
8803
8804    if ( key === "title" ) {
8805      this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8806    }
8807  },
8808
8809  _size: function() {
8810    // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8811    // divs will both have width and height set, so we need to reset them
8812    var nonContentHeight, minContentHeight, maxContentHeight,
8813      options = this.options;
8814
8815    // Reset content sizing
8816    this.element.show().css({
8817      width: "auto",
8818      minHeight: 0,
8819      maxHeight: "none",
8820      height: 0
8821    });
8822
8823    if ( options.minWidth > options.width ) {
8824      options.width = options.minWidth;
8825    }
8826
8827    // reset wrapper sizing
8828    // determine the height of all the non-content elements
8829    nonContentHeight = this.uiDialog.css({
8830        height: "auto",
8831        width: options.width
8832      })
8833      .outerHeight();
8834    minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8835    maxContentHeight = typeof options.maxHeight === "number" ?
8836      Math.max( 0, options.maxHeight - nonContentHeight ) :
8837      "none";
8838
8839    if ( options.height === "auto" ) {
8840      this.element.css({
8841        minHeight: minContentHeight,
8842        maxHeight: maxContentHeight,
8843        height: "auto"
8844      });
8845    } else {
8846      this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8847    }
8848
8849    if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8850      this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8851    }
8852  },
8853
8854  _blockFrames: function() {
8855    this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8856      var iframe = $( this );
8857
8858      return $( "<div>" )
8859        .css({
8860          position: "absolute",
8861          width: iframe.outerWidth(),
8862          height: iframe.outerHeight()
8863        })
8864        .appendTo( iframe.parent() )
8865        .offset( iframe.offset() )[0];
8866    });
8867  },
8868
8869  _unblockFrames: function() {
8870    if ( this.iframeBlocks ) {
8871      this.iframeBlocks.remove();
8872      delete this.iframeBlocks;
8873    }
8874  },
8875
8876  _allowInteraction: function( event ) {
8877    if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8878      return true;
8879    }
8880
8881    // TODO: Remove hack when datepicker implements
8882    // the .ui-front logic (#8989)
8883    return !!$( event.target ).closest( ".ui-datepicker" ).length;
8884  },
8885
8886  _createOverlay: function() {
8887    if ( !this.options.modal ) {
8888      return;
8889    }
8890
8891    // We use a delay in case the overlay is created from an
8892    // event that we're going to be cancelling (#2804)
8893    var isOpening = true;
8894    this._delay(function() {
8895      isOpening = false;
8896    });
8897
8898    if ( !this.document.data( "ui-dialog-overlays" ) ) {
8899
8900      // Prevent use of anchors and inputs
8901      // Using _on() for an event handler shared across many instances is
8902      // safe because the dialogs stack and must be closed in reverse order
8903      this._on( this.document, {
8904        focusin: function( event ) {
8905          if ( isOpening ) {
8906            return;
8907          }
8908
8909          if ( !this._allowInteraction( event ) ) {
8910            event.preventDefault();
8911            this._trackingInstances()[ 0 ]._focusTabbable();
8912          }
8913        }
8914      });
8915    }
8916
8917    this.overlay = $( "<div>" )
8918      .addClass( "ui-widget-overlay ui-front" )
8919      .appendTo( this._appendTo() );
8920    this._on( this.overlay, {
8921      mousedown: "_keepFocus"
8922    });
8923    this.document.data( "ui-dialog-overlays",
8924      (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8925  },
8926
8927  _destroyOverlay: function() {
8928    if ( !this.options.modal ) {
8929      return;
8930    }
8931
8932    if ( this.overlay ) {
8933      var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8934
8935      if ( !overlays ) {
8936        this.document
8937          .unbind( "focusin" )
8938          .removeData( "ui-dialog-overlays" );
8939      } else {
8940        this.document.data( "ui-dialog-overlays", overlays );
8941      }
8942
8943      this.overlay.remove();
8944      this.overlay = null;
8945    }
8946  }
8947});
8948
8949
8950/*!
8951 * jQuery UI Droppable 1.11.4
8952 * http://jqueryui.com
8953 *
8954 * Copyright jQuery Foundation and other contributors
8955 * Released under the MIT license.
8956 * http://jquery.org/license
8957 *
8958 * http://api.jqueryui.com/droppable/
8959 */
8960
8961
8962$.widget( "ui.droppable", {
8963  version: "1.11.4",
8964  widgetEventPrefix: "drop",
8965  options: {
8966    accept: "*",
8967    activeClass: false,
8968    addClasses: true,
8969    greedy: false,
8970    hoverClass: false,
8971    scope: "default",
8972    tolerance: "intersect",
8973
8974    // callbacks
8975    activate: null,
8976    deactivate: null,
8977    drop: null,
8978    out: null,
8979    over: null
8980  },
8981  _create: function() {
8982
8983    var proportions,
8984      o = this.options,
8985      accept = o.accept;
8986
8987    this.isover = false;
8988    this.isout = true;
8989
8990    this.accept = $.isFunction( accept ) ? accept : function( d ) {
8991      return d.is( accept );
8992    };
8993
8994    this.proportions = function( /* valueToWrite */ ) {
8995      if ( arguments.length ) {
8996        // Store the droppable's proportions
8997        proportions = arguments[ 0 ];
8998      } else {
8999        // Retrieve or derive the droppable's proportions
9000        return proportions ?
9001          proportions :
9002          proportions = {
9003            width: this.element[ 0 ].offsetWidth,
9004            height: this.element[ 0 ].offsetHeight
9005          };
9006      }
9007    };
9008
9009    this._addToManager( o.scope );
9010
9011    o.addClasses && this.element.addClass( "ui-droppable" );
9012
9013  },
9014
9015  _addToManager: function( scope ) {
9016    // Add the reference and positions to the manager
9017    $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
9018    $.ui.ddmanager.droppables[ scope ].push( this );
9019  },
9020
9021  _splice: function( drop ) {
9022    var i = 0;
9023    for ( ; i < drop.length; i++ ) {
9024      if ( drop[ i ] === this ) {
9025        drop.splice( i, 1 );
9026      }
9027    }
9028  },
9029
9030  _destroy: function() {
9031    var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9032
9033    this._splice( drop );
9034
9035    this.element.removeClass( "ui-droppable ui-droppable-disabled" );
9036  },
9037
9038  _setOption: function( key, value ) {
9039
9040    if ( key === "accept" ) {
9041      this.accept = $.isFunction( value ) ? value : function( d ) {
9042        return d.is( value );
9043      };
9044    } else if ( key === "scope" ) {
9045      var drop = $.ui.ddmanager.droppables[ this.options.scope ];
9046
9047      this._splice( drop );
9048      this._addToManager( value );
9049    }
9050
9051    this._super( key, value );
9052  },
9053
9054  _activate: function( event ) {
9055    var draggable = $.ui.ddmanager.current;
9056    if ( this.options.activeClass ) {
9057      this.element.addClass( this.options.activeClass );
9058    }
9059    if ( draggable ){
9060      this._trigger( "activate", event, this.ui( draggable ) );
9061    }
9062  },
9063
9064  _deactivate: function( event ) {
9065    var draggable = $.ui.ddmanager.current;
9066    if ( this.options.activeClass ) {
9067      this.element.removeClass( this.options.activeClass );
9068    }
9069    if ( draggable ){
9070      this._trigger( "deactivate", event, this.ui( draggable ) );
9071    }
9072  },
9073
9074  _over: function( event ) {
9075
9076    var draggable = $.ui.ddmanager.current;
9077
9078    // Bail if draggable and droppable are same element
9079    if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9080      return;
9081    }
9082
9083    if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9084      if ( this.options.hoverClass ) {
9085        this.element.addClass( this.options.hoverClass );
9086      }
9087      this._trigger( "over", event, this.ui( draggable ) );
9088    }
9089
9090  },
9091
9092  _out: function( event ) {
9093
9094    var draggable = $.ui.ddmanager.current;
9095
9096    // Bail if draggable and droppable are same element
9097    if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9098      return;
9099    }
9100
9101    if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9102      if ( this.options.hoverClass ) {
9103        this.element.removeClass( this.options.hoverClass );
9104      }
9105      this._trigger( "out", event, this.ui( draggable ) );
9106    }
9107
9108  },
9109
9110  _drop: function( event, custom ) {
9111
9112    var draggable = custom || $.ui.ddmanager.current,
9113      childrenIntersection = false;
9114
9115    // Bail if draggable and droppable are same element
9116    if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
9117      return false;
9118    }
9119
9120    this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
9121      var inst = $( this ).droppable( "instance" );
9122      if (
9123        inst.options.greedy &&
9124        !inst.options.disabled &&
vendor: 4,244 bytes, lines 9125-9245
9125        inst.options.scope === draggable.options.scope &&
9126        inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
9127        $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
9128      ) { childrenIntersection = true; return false; }
9129    });
9130    if ( childrenIntersection ) {
9131      return false;
9132    }
9133
9134    if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9135      if ( this.options.activeClass ) {
9136        this.element.removeClass( this.options.activeClass );
9137      }
9138      if ( this.options.hoverClass ) {
9139        this.element.removeClass( this.options.hoverClass );
9140      }
9141      this._trigger( "drop", event, this.ui( draggable ) );
9142      return this.element;
9143    }
9144
9145    return false;
9146
9147  },
9148
9149  ui: function( c ) {
9150    return {
9151      draggable: ( c.currentItem || c.element ),
9152      helper: c.helper,
9153      position: c.position,
9154      offset: c.positionAbs
9155    };
9156  }
9157
9158});
9159
9160$.ui.intersect = (function() {
9161  function isOverAxis( x, reference, size ) {
9162    return ( x >= reference ) && ( x < ( reference + size ) );
9163  }
9164
9165  return function( draggable, droppable, toleranceMode, event ) {
9166
9167    if ( !droppable.offset ) {
9168      return false;
9169    }
9170
9171    var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
9172      y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
9173      x2 = x1 + draggable.helperProportions.width,
9174      y2 = y1 + draggable.helperProportions.height,
9175      l = droppable.offset.left,
9176      t = droppable.offset.top,
9177      r = l + droppable.proportions().width,
9178      b = t + droppable.proportions().height;
9179
9180    switch ( toleranceMode ) {
9181    case "fit":
9182      return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9183    case "intersect":
9184      return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9185        x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9186        t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9187        y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9188    case "pointer":
9189      return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9190    case "touch":
9191      return (
9192        ( y1 >= t && y1 <= b ) || // Top edge touching
9193        ( y2 >= t && y2 <= b ) || // Bottom edge touching
9194        ( y1 < t && y2 > b ) // Surrounded vertically
9195      ) && (
9196        ( x1 >= l && x1 <= r ) || // Left edge touching
9197        ( x2 >= l && x2 <= r ) || // Right edge touching
9198        ( x1 < l && x2 > r ) // Surrounded horizontally
9199      );
9200    default:
9201      return false;
9202    }
9203  };
9204})();
9205
9206/*
9207  This manager tracks offsets of draggables and droppables
9208*/
9209$.ui.ddmanager = {
9210  current: null,
9211  droppables: { "default": [] },
9212  prepareOffsets: function( t, event ) {
9213
9214    var i, j,
9215      m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9216      type = event ? event.type : null, // workaround for #2317
9217      list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9218
9219    droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9220
9221      // No disabled and non-accepted
9222      if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9223        continue;
9224      }
9225
9226      // Filter out elements in the current dragged item
9227      for ( j = 0; j < list.length; j++ ) {
9228        if ( list[ j ] === m[ i ].element[ 0 ] ) {
9229          m[ i ].proportions().height = 0;
9230          continue droppablesLoop;
9231        }
9232      }
9233
9234      m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9235      if ( !m[ i ].visible ) {
9236        continue;
9237      }
9238
9239      // Activate the droppable if used directly from draggables
9240      if ( type === "mousedown" ) {
9241        m[ i ]._activate.call( m[ i ], event );
9242      }
9243
9244      m[ i ].offset = m[ i ].element.offset();
9245      m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
vendor: 80,591 bytes, lines 9246-12147
9246
9247    }
9248
9249  },
9250  drop: function( draggable, event ) {
9251
9252    var dropped = false;
9253    // Create a copy of the droppables in case the list changes during the drop (#9116)
9254    $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9255
9256      if ( !this.options ) {
9257        return;
9258      }
9259      if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9260        dropped = this._drop.call( this, event ) || dropped;
9261      }
9262
9263      if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9264        this.isout = true;
9265        this.isover = false;
9266        this._deactivate.call( this, event );
9267      }
9268
9269    });
9270    return dropped;
9271
9272  },
9273  dragStart: function( draggable, event ) {
9274    // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9275    draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9276      if ( !draggable.options.refreshPositions ) {
9277        $.ui.ddmanager.prepareOffsets( draggable, event );
9278      }
9279    });
9280  },
9281  drag: function( draggable, event ) {
9282
9283    // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9284    if ( draggable.options.refreshPositions ) {
9285      $.ui.ddmanager.prepareOffsets( draggable, event );
9286    }
9287
9288    // Run through all droppables and check their positions based on specific tolerance options
9289    $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9290
9291      if ( this.options.disabled || this.greedyChild || !this.visible ) {
9292        return;
9293      }
9294
9295      var parentInstance, scope, parent,
9296        intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9297        c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9298      if ( !c ) {
9299        return;
9300      }
9301
9302      if ( this.options.greedy ) {
9303        // find droppable parents with same scope
9304        scope = this.options.scope;
9305        parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9306          return $( this ).droppable( "instance" ).options.scope === scope;
9307        });
9308
9309        if ( parent.length ) {
9310          parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9311          parentInstance.greedyChild = ( c === "isover" );
9312        }
9313      }
9314
9315      // we just moved into a greedy child
9316      if ( parentInstance && c === "isover" ) {
9317        parentInstance.isover = false;
9318        parentInstance.isout = true;
9319        parentInstance._out.call( parentInstance, event );
9320      }
9321
9322      this[ c ] = true;
9323      this[c === "isout" ? "isover" : "isout"] = false;
9324      this[c === "isover" ? "_over" : "_out"].call( this, event );
9325
9326      // we just moved out of a greedy child
9327      if ( parentInstance && c === "isout" ) {
9328        parentInstance.isout = false;
9329        parentInstance.isover = true;
9330        parentInstance._over.call( parentInstance, event );
9331      }
9332    });
9333
9334  },
9335  dragStop: function( draggable, event ) {
9336    draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9337    // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9338    if ( !draggable.options.refreshPositions ) {
9339      $.ui.ddmanager.prepareOffsets( draggable, event );
9340    }
9341  }
9342};
9343
9344var droppable = $.ui.droppable;
9345
9346
9347/*!
9348 * jQuery UI Effects 1.11.4
9349 * http://jqueryui.com
9350 *
9351 * Copyright jQuery Foundation and other contributors
9352 * Released under the MIT license.
9353 * http://jquery.org/license
9354 *
9355 * http://api.jqueryui.com/category/effects-core/
9356 */
9357
9358
9359var dataSpace = "ui-effects-",
9360
9361  // Create a local jQuery because jQuery Color relies on it and the
9362  // global may not exist with AMD and a custom build (#10199)
9363  jQuery = $;
9364
9365$.effects = {
9366  effect: {}
9367};
9368
9369/*!
9370 * jQuery Color Animations v2.1.2
9371 * https://github.com/jquery/jquery-color
9372 *
9373 * Copyright 2014 jQuery Foundation and other contributors
9374 * Released under the MIT license.
9375 * http://jquery.org/license
9376 *
9377 * Date: Wed Jan 16 08:47:09 2013 -0600
9378 */
9379(function( jQuery, undefined ) {
9380
9381  var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9382
9383  // plusequals test for += 100 -= 100
9384  rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9385  // a set of RE's that can match strings and generate color tuples.
9386  stringParsers = [ {
9387      re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9388      parse: function( execResult ) {
9389        return [
9390          execResult[ 1 ],
9391          execResult[ 2 ],
9392          execResult[ 3 ],
9393          execResult[ 4 ]
9394        ];
9395      }
9396    }, {
9397      re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9398      parse: function( execResult ) {
9399        return [
9400          execResult[ 1 ] * 2.55,
9401          execResult[ 2 ] * 2.55,
9402          execResult[ 3 ] * 2.55,
9403          execResult[ 4 ]
9404        ];
9405      }
9406    }, {
9407      // this regex ignores A-F because it's compared against an already lowercased string
9408      re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9409      parse: function( execResult ) {
9410        return [
9411          parseInt( execResult[ 1 ], 16 ),
9412          parseInt( execResult[ 2 ], 16 ),
9413          parseInt( execResult[ 3 ], 16 )
9414        ];
9415      }
9416    }, {
9417      // this regex ignores A-F because it's compared against an already lowercased string
9418      re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9419      parse: function( execResult ) {
9420        return [
9421          parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9422          parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9423          parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9424        ];
9425      }
9426    }, {
9427      re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9428      space: "hsla",
9429      parse: function( execResult ) {
9430        return [
9431          execResult[ 1 ],
9432          execResult[ 2 ] / 100,
9433          execResult[ 3 ] / 100,
9434          execResult[ 4 ]
9435        ];
9436      }
9437    } ],
9438
9439  // jQuery.Color( )
9440  color = jQuery.Color = function( color, green, blue, alpha ) {
9441    return new jQuery.Color.fn.parse( color, green, blue, alpha );
9442  },
9443  spaces = {
9444    rgba: {
9445      props: {
9446        red: {
9447          idx: 0,
9448          type: "byte"
9449        },
9450        green: {
9451          idx: 1,
9452          type: "byte"
9453        },
9454        blue: {
9455          idx: 2,
9456          type: "byte"
9457        }
9458      }
9459    },
9460
9461    hsla: {
9462      props: {
9463        hue: {
9464          idx: 0,
9465          type: "degrees"
9466        },
9467        saturation: {
9468          idx: 1,
9469          type: "percent"
9470        },
9471        lightness: {
9472          idx: 2,
9473          type: "percent"
9474        }
9475      }
9476    }
9477  },
9478  propTypes = {
9479    "byte": {
9480      floor: true,
9481      max: 255
9482    },
9483    "percent": {
9484      max: 1
9485    },
9486    "degrees": {
9487      mod: 360,
9488      floor: true
9489    }
9490  },
9491  support = color.support = {},
9492
9493  // element for support tests
9494  supportElem = jQuery( "<p>" )[ 0 ],
9495
9496  // colors = jQuery.Color.names
9497  colors,
9498
9499  // local aliases of functions called often
9500  each = jQuery.each;
9501
9502// determine rgba support immediately
9503supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9504support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9505
9506// define cache name and alpha properties
9507// for rgba and hsla spaces
9508each( spaces, function( spaceName, space ) {
9509  space.cache = "_" + spaceName;
9510  space.props.alpha = {
9511    idx: 3,
9512    type: "percent",
9513    def: 1
9514  };
9515});
9516
9517function clamp( value, prop, allowEmpty ) {
9518  var type = propTypes[ prop.type ] || {};
9519
9520  if ( value == null ) {
9521    return (allowEmpty || !prop.def) ? null : prop.def;
9522  }
9523
9524  // ~~ is an short way of doing floor for positive numbers
9525  value = type.floor ? ~~value : parseFloat( value );
9526
9527  // IE will pass in empty strings as value for alpha,
9528  // which will hit this case
9529  if ( isNaN( value ) ) {
9530    return prop.def;
9531  }
9532
9533  if ( type.mod ) {
9534    // we add mod before modding to make sure that negatives values
9535    // get converted properly: -10 -> 350
9536    return (value + type.mod) % type.mod;
9537  }
9538
9539  // for now all property types without mod have min and max
9540  return 0 > value ? 0 : type.max < value ? type.max : value;
9541}
9542
9543function stringParse( string ) {
9544  var inst = color(),
9545    rgba = inst._rgba = [];
9546
9547  string = string.toLowerCase();
9548
9549  each( stringParsers, function( i, parser ) {
9550    var parsed,
9551      match = parser.re.exec( string ),
9552      values = match && parser.parse( match ),
9553      spaceName = parser.space || "rgba";
9554
9555    if ( values ) {
9556      parsed = inst[ spaceName ]( values );
9557
9558      // if this was an rgba parse the assignment might happen twice
9559      // oh well....
9560      inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9561      rgba = inst._rgba = parsed._rgba;
9562
9563      // exit each( stringParsers ) here because we matched
9564      return false;
9565    }
9566  });
9567
9568  // Found a stringParser that handled it
9569  if ( rgba.length ) {
9570
9571    // if this came from a parsed string, force "transparent" when alpha is 0
9572    // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9573    if ( rgba.join() === "0,0,0,0" ) {
9574      jQuery.extend( rgba, colors.transparent );
9575    }
9576    return inst;
9577  }
9578
9579  // named colors
9580  return colors[ string ];
9581}
9582
9583color.fn = jQuery.extend( color.prototype, {
9584  parse: function( red, green, blue, alpha ) {
9585    if ( red === undefined ) {
9586      this._rgba = [ null, null, null, null ];
9587      return this;
9588    }
9589    if ( red.jquery || red.nodeType ) {
9590      red = jQuery( red ).css( green );
9591      green = undefined;
9592    }
9593
9594    var inst = this,
9595      type = jQuery.type( red ),
9596      rgba = this._rgba = [];
9597
9598    // more than 1 argument specified - assume ( red, green, blue, alpha )
9599    if ( green !== undefined ) {
9600      red = [ red, green, blue, alpha ];
9601      type = "array";
9602    }
9603
9604    if ( type === "string" ) {
9605      return this.parse( stringParse( red ) || colors._default );
9606    }
9607
9608    if ( type === "array" ) {
9609      each( spaces.rgba.props, function( key, prop ) {
9610        rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9611      });
9612      return this;
9613    }
9614
9615    if ( type === "object" ) {
9616      if ( red instanceof color ) {
9617        each( spaces, function( spaceName, space ) {
9618          if ( red[ space.cache ] ) {
9619            inst[ space.cache ] = red[ space.cache ].slice();
9620          }
9621        });
9622      } else {
9623        each( spaces, function( spaceName, space ) {
9624          var cache = space.cache;
9625          each( space.props, function( key, prop ) {
9626
9627            // if the cache doesn't exist, and we know how to convert
9628            if ( !inst[ cache ] && space.to ) {
9629
9630              // if the value was null, we don't need to copy it
9631              // if the key was alpha, we don't need to copy it either
9632              if ( key === "alpha" || red[ key ] == null ) {
9633                return;
9634              }
9635              inst[ cache ] = space.to( inst._rgba );
9636            }
9637
9638            // this is the only case where we allow nulls for ALL properties.
9639            // call clamp with alwaysAllowEmpty
9640            inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9641          });
9642
9643          // everything defined but alpha?
9644          if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9645            // use the default of 1
9646            inst[ cache ][ 3 ] = 1;
9647            if ( space.from ) {
9648              inst._rgba = space.from( inst[ cache ] );
9649            }
9650          }
9651        });
9652      }
9653      return this;
9654    }
9655  },
9656  is: function( compare ) {
9657    var is = color( compare ),
9658      same = true,
9659      inst = this;
9660
9661    each( spaces, function( _, space ) {
9662      var localCache,
9663        isCache = is[ space.cache ];
9664      if (isCache) {
9665        localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9666        each( space.props, function( _, prop ) {
9667          if ( isCache[ prop.idx ] != null ) {
9668            same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9669            return same;
9670          }
9671        });
9672      }
9673      return same;
9674    });
9675    return same;
9676  },
9677  _space: function() {
9678    var used = [],
9679      inst = this;
9680    each( spaces, function( spaceName, space ) {
9681      if ( inst[ space.cache ] ) {
9682        used.push( spaceName );
9683      }
9684    });
9685    return used.pop();
9686  },
9687  transition: function( other, distance ) {
9688    var end = color( other ),
9689      spaceName = end._space(),
9690      space = spaces[ spaceName ],
9691      startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9692      start = startColor[ space.cache ] || space.to( startColor._rgba ),
9693      result = start.slice();
9694
9695    end = end[ space.cache ];
9696    each( space.props, function( key, prop ) {
9697      var index = prop.idx,
9698        startValue = start[ index ],
9699        endValue = end[ index ],
9700        type = propTypes[ prop.type ] || {};
9701
9702      // if null, don't override start value
9703      if ( endValue === null ) {
9704        return;
9705      }
9706      // if null - use end
9707      if ( startValue === null ) {
9708        result[ index ] = endValue;
9709      } else {
9710        if ( type.mod ) {
9711          if ( endValue - startValue > type.mod / 2 ) {
9712            startValue += type.mod;
9713          } else if ( startValue - endValue > type.mod / 2 ) {
9714            startValue -= type.mod;
9715          }
9716        }
9717        result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9718      }
9719    });
9720    return this[ spaceName ]( result );
9721  },
9722  blend: function( opaque ) {
9723    // if we are already opaque - return ourself
9724    if ( this._rgba[ 3 ] === 1 ) {
9725      return this;
9726    }
9727
9728    var rgb = this._rgba.slice(),
9729      a = rgb.pop(),
9730      blend = color( opaque )._rgba;
9731
9732    return color( jQuery.map( rgb, function( v, i ) {
9733      return ( 1 - a ) * blend[ i ] + a * v;
9734    }));
9735  },
9736  toRgbaString: function() {
9737    var prefix = "rgba(",
9738      rgba = jQuery.map( this._rgba, function( v, i ) {
9739        return v == null ? ( i > 2 ? 1 : 0 ) : v;
9740      });
9741
9742    if ( rgba[ 3 ] === 1 ) {
9743      rgba.pop();
9744      prefix = "rgb(";
9745    }
9746
9747    return prefix + rgba.join() + ")";
9748  },
9749  toHslaString: function() {
9750    var prefix = "hsla(",
9751      hsla = jQuery.map( this.hsla(), function( v, i ) {
9752        if ( v == null ) {
9753          v = i > 2 ? 1 : 0;
9754        }
9755
9756        // catch 1 and 2
9757        if ( i && i < 3 ) {
9758          v = Math.round( v * 100 ) + "%";
9759        }
9760        return v;
9761      });
9762
9763    if ( hsla[ 3 ] === 1 ) {
9764      hsla.pop();
9765      prefix = "hsl(";
9766    }
9767    return prefix + hsla.join() + ")";
9768  },
9769  toHexString: function( includeAlpha ) {
9770    var rgba = this._rgba.slice(),
9771      alpha = rgba.pop();
9772
9773    if ( includeAlpha ) {
9774      rgba.push( ~~( alpha * 255 ) );
9775    }
9776
9777    return "#" + jQuery.map( rgba, function( v ) {
9778
9779      // default to 0 when nulls exist
9780      v = ( v || 0 ).toString( 16 );
9781      return v.length === 1 ? "0" + v : v;
9782    }).join("");
9783  },
9784  toString: function() {
9785    return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9786  }
9787});
9788color.fn.parse.prototype = color.fn;
9789
9790// hsla conversions adapted from:
9791// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9792
9793function hue2rgb( p, q, h ) {
9794  h = ( h + 1 ) % 1;
9795  if ( h * 6 < 1 ) {
9796    return p + ( q - p ) * h * 6;
9797  }
9798  if ( h * 2 < 1) {
9799    return q;
9800  }
9801  if ( h * 3 < 2 ) {
9802    return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9803  }
9804  return p;
9805}
9806
9807spaces.hsla.to = function( rgba ) {
9808  if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9809    return [ null, null, null, rgba[ 3 ] ];
9810  }
9811  var r = rgba[ 0 ] / 255,
9812    g = rgba[ 1 ] / 255,
9813    b = rgba[ 2 ] / 255,
9814    a = rgba[ 3 ],
9815    max = Math.max( r, g, b ),
9816    min = Math.min( r, g, b ),
9817    diff = max - min,
9818    add = max + min,
9819    l = add * 0.5,
9820    h, s;
9821
9822  if ( min === max ) {
9823    h = 0;
9824  } else if ( r === max ) {
9825    h = ( 60 * ( g - b ) / diff ) + 360;
9826  } else if ( g === max ) {
9827    h = ( 60 * ( b - r ) / diff ) + 120;
9828  } else {
9829    h = ( 60 * ( r - g ) / diff ) + 240;
9830  }
9831
9832  // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9833  // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9834  if ( diff === 0 ) {
9835    s = 0;
9836  } else if ( l <= 0.5 ) {
9837    s = diff / add;
9838  } else {
9839    s = diff / ( 2 - add );
9840  }
9841  return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9842};
9843
9844spaces.hsla.from = function( hsla ) {
9845  if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9846    return [ null, null, null, hsla[ 3 ] ];
9847  }
9848  var h = hsla[ 0 ] / 360,
9849    s = hsla[ 1 ],
9850    l = hsla[ 2 ],
9851    a = hsla[ 3 ],
9852    q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9853    p = 2 * l - q;
9854
9855  return [
9856    Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9857    Math.round( hue2rgb( p, q, h ) * 255 ),
9858    Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9859    a
9860  ];
9861};
9862
9863each( spaces, function( spaceName, space ) {
9864  var props = space.props,
9865    cache = space.cache,
9866    to = space.to,
9867    from = space.from;
9868
9869  // makes rgba() and hsla()
9870  color.fn[ spaceName ] = function( value ) {
9871
9872    // generate a cache for this space if it doesn't exist
9873    if ( to && !this[ cache ] ) {
9874      this[ cache ] = to( this._rgba );
9875    }
9876    if ( value === undefined ) {
9877      return this[ cache ].slice();
9878    }
9879
9880    var ret,
9881      type = jQuery.type( value ),
9882      arr = ( type === "array" || type === "object" ) ? value : arguments,
9883      local = this[ cache ].slice();
9884
9885    each( props, function( key, prop ) {
9886      var val = arr[ type === "object" ? key : prop.idx ];
9887      if ( val == null ) {
9888        val = local[ prop.idx ];
9889      }
9890      local[ prop.idx ] = clamp( val, prop );
9891    });
9892
9893    if ( from ) {
9894      ret = color( from( local ) );
9895      ret[ cache ] = local;
9896      return ret;
9897    } else {
9898      return color( local );
9899    }
9900  };
9901
9902  // makes red() green() blue() alpha() hue() saturation() lightness()
9903  each( props, function( key, prop ) {
9904    // alpha is included in more than one space
9905    if ( color.fn[ key ] ) {
9906      return;
9907    }
9908    color.fn[ key ] = function( value ) {
9909      var vtype = jQuery.type( value ),
9910        fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9911        local = this[ fn ](),
9912        cur = local[ prop.idx ],
9913        match;
9914
9915      if ( vtype === "undefined" ) {
9916        return cur;
9917      }
9918
9919      if ( vtype === "function" ) {
9920        value = value.call( this, cur );
9921        vtype = jQuery.type( value );
9922      }
9923      if ( value == null && prop.empty ) {
9924        return this;
9925      }
9926      if ( vtype === "string" ) {
9927        match = rplusequals.exec( value );
9928        if ( match ) {
9929          value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9930        }
9931      }
9932      local[ prop.idx ] = value;
9933      return this[ fn ]( local );
9934    };
9935  });
9936});
9937
9938// add cssHook and .fx.step function for each named hook.
9939// accept a space separated string of properties
9940color.hook = function( hook ) {
9941  var hooks = hook.split( " " );
9942  each( hooks, function( i, hook ) {
9943    jQuery.cssHooks[ hook ] = {
9944      set: function( elem, value ) {
9945        var parsed, curElem,
9946          backgroundColor = "";
9947
9948        if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9949          value = color( parsed || value );
9950          if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9951            curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9952            while (
9953              (backgroundColor === "" || backgroundColor === "transparent") &&
9954              curElem && curElem.style
9955            ) {
9956              try {
9957                backgroundColor = jQuery.css( curElem, "backgroundColor" );
9958                curElem = curElem.parentNode;
9959              } catch ( e ) {
9960              }
9961            }
9962
9963            value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9964              backgroundColor :
9965              "_default" );
9966          }
9967
9968          value = value.toRgbaString();
9969        }
9970        try {
9971          elem.style[ hook ] = value;
9972        } catch ( e ) {
9973          // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9974        }
9975      }
9976    };
9977    jQuery.fx.step[ hook ] = function( fx ) {
9978      if ( !fx.colorInit ) {
9979        fx.start = color( fx.elem, hook );
9980        fx.end = color( fx.end );
9981        fx.colorInit = true;
9982      }
9983      jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9984    };
9985  });
9986
9987};
9988
9989color.hook( stepHooks );
9990
9991jQuery.cssHooks.borderColor = {
9992  expand: function( value ) {
9993    var expanded = {};
9994
9995    each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9996      expanded[ "border" + part + "Color" ] = value;
9997    });
9998    return expanded;
9999  }
10000};
10001
10002// Basic color names only.
10003// Usage of any of the other color names requires adding yourself or including
10004// jquery.color.svg-names.js.
10005colors = jQuery.Color.names = {
10006  // 4.1. Basic color keywords
10007  aqua: "#00ffff",
10008  black: "#000000",
10009  blue: "#0000ff",
10010  fuchsia: "#ff00ff",
10011  gray: "#808080",
10012  green: "#008000",
10013  lime: "#00ff00",
10014  maroon: "#800000",
10015  navy: "#000080",
10016  olive: "#808000",
10017  purple: "#800080",
10018  red: "#ff0000",
10019  silver: "#c0c0c0",
10020  teal: "#008080",
10021  white: "#ffffff",
10022  yellow: "#ffff00",
10023
10024  // 4.2.3. "transparent" color keyword
10025  transparent: [ null, null, null, 0 ],
10026
10027  _default: "#ffffff"
10028};
10029
10030})( jQuery );
10031
10032/******************************************************************************/
10033/****************************** CLASS ANIMATIONS ******************************/
10034/******************************************************************************/
10035(function() {
10036
10037var classAnimationActions = [ "add", "remove", "toggle" ],
10038  shorthandStyles = {
10039    border: 1,
10040    borderBottom: 1,
10041    borderColor: 1,
10042    borderLeft: 1,
10043    borderRight: 1,
10044    borderTop: 1,
10045    borderWidth: 1,
10046    margin: 1,
10047    padding: 1
10048  };
10049
10050$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
10051  $.fx.step[ prop ] = function( fx ) {
10052    if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
10053      jQuery.style( fx.elem, prop, fx.end );
10054      fx.setAttr = true;
10055    }
10056  };
10057});
10058
10059function getElementStyles( elem ) {
10060  var key, len,
10061    style = elem.ownerDocument.defaultView ?
10062      elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
10063      elem.currentStyle,
10064    styles = {};
10065
10066  if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
10067    len = style.length;
10068    while ( len-- ) {
10069      key = style[ len ];
10070      if ( typeof style[ key ] === "string" ) {
10071        styles[ $.camelCase( key ) ] = style[ key ];
10072      }
10073    }
10074  // support: Opera, IE <9
10075  } else {
10076    for ( key in style ) {
10077      if ( typeof style[ key ] === "string" ) {
10078        styles[ key ] = style[ key ];
10079      }
10080    }
10081  }
10082
10083  return styles;
10084}
10085
10086function styleDifference( oldStyle, newStyle ) {
10087  var diff = {},
10088    name, value;
10089
10090  for ( name in newStyle ) {
10091    value = newStyle[ name ];
10092    if ( oldStyle[ name ] !== value ) {
10093      if ( !shorthandStyles[ name ] ) {
10094        if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
10095          diff[ name ] = value;
10096        }
10097      }
10098    }
10099  }
10100
10101  return diff;
10102}
10103
10104// support: jQuery <1.8
10105if ( !$.fn.addBack ) {
10106  $.fn.addBack = function( selector ) {
10107    return this.add( selector == null ?
10108      this.prevObject : this.prevObject.filter( selector )
10109    );
10110  };
10111}
10112
10113$.effects.animateClass = function( value, duration, easing, callback ) {
10114  var o = $.speed( duration, easing, callback );
10115
10116  return this.queue( function() {
10117    var animated = $( this ),
10118      baseClass = animated.attr( "class" ) || "",
10119      applyClassChange,
10120      allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
10121
10122    // map the animated objects to store the original styles.
10123    allAnimations = allAnimations.map(function() {
10124      var el = $( this );
10125      return {
10126        el: el,
10127        start: getElementStyles( this )
10128      };
10129    });
10130
10131    // apply class change
10132    applyClassChange = function() {
10133      $.each( classAnimationActions, function(i, action) {
10134        if ( value[ action ] ) {
10135          animated[ action + "Class" ]( value[ action ] );
10136        }
10137      });
10138    };
10139    applyClassChange();
10140
10141    // map all animated objects again - calculate new styles and diff
10142    allAnimations = allAnimations.map(function() {
10143      this.end = getElementStyles( this.el[ 0 ] );
10144      this.diff = styleDifference( this.start, this.end );
10145      return this;
10146    });
10147
10148    // apply original class
10149    animated.attr( "class", baseClass );
10150
10151    // map all animated objects again - this time collecting a promise
10152    allAnimations = allAnimations.map(function() {
10153      var styleInfo = this,
10154        dfd = $.Deferred(),
10155        opts = $.extend({}, o, {
10156          queue: false,
10157          complete: function() {
10158            dfd.resolve( styleInfo );
10159          }
10160        });
10161
10162      this.el.animate( this.diff, opts );
10163      return dfd.promise();
10164    });
10165
10166    // once all animations have completed:
10167    $.when.apply( $, allAnimations.get() ).done(function() {
10168
10169      // set the final class
10170      applyClassChange();
10171
10172      // for each animated element,
10173      // clear all css properties that were animated
10174      $.each( arguments, function() {
10175        var el = this.el;
10176        $.each( this.diff, function(key) {
10177          el.css( key, "" );
10178        });
10179      });
10180
10181      // this is guarnteed to be there if you use jQuery.speed()
10182      // it also handles dequeuing the next anim...
10183      o.complete.call( animated[ 0 ] );
10184    });
10185  });
10186};
10187
10188$.fn.extend({
10189  addClass: (function( orig ) {
10190    return function( classNames, speed, easing, callback ) {
10191      return speed ?
10192        $.effects.animateClass.call( this,
10193          { add: classNames }, speed, easing, callback ) :
10194        orig.apply( this, arguments );
10195    };
10196  })( $.fn.addClass ),
10197
10198  removeClass: (function( orig ) {
10199    return function( classNames, speed, easing, callback ) {
10200      return arguments.length > 1 ?
10201        $.effects.animateClass.call( this,
10202          { remove: classNames }, speed, easing, callback ) :
10203        orig.apply( this, arguments );
10204    };
10205  })( $.fn.removeClass ),
10206
10207  toggleClass: (function( orig ) {
10208    return function( classNames, force, speed, easing, callback ) {
10209      if ( typeof force === "boolean" || force === undefined ) {
10210        if ( !speed ) {
10211          // without speed parameter
10212          return orig.apply( this, arguments );
10213        } else {
10214          return $.effects.animateClass.call( this,
10215            (force ? { add: classNames } : { remove: classNames }),
10216            speed, easing, callback );
10217        }
10218      } else {
10219        // without force parameter
10220        return $.effects.animateClass.call( this,
10221          { toggle: classNames }, force, speed, easing );
10222      }
10223    };
10224  })( $.fn.toggleClass ),
10225
10226  switchClass: function( remove, add, speed, easing, callback) {
10227    return $.effects.animateClass.call( this, {
10228      add: add,
10229      remove: remove
10230    }, speed, easing, callback );
10231  }
10232});
10233
10234})();
10235
10236/******************************************************************************/
10237/*********************************** EFFECTS **********************************/
10238/******************************************************************************/
10239
10240(function() {
10241
10242$.extend( $.effects, {
10243  version: "1.11.4",
10244
10245  // Saves a set of properties in a data storage
10246  save: function( element, set ) {
10247    for ( var i = 0; i < set.length; i++ ) {
10248      if ( set[ i ] !== null ) {
10249        element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10250      }
10251    }
10252  },
10253
10254  // Restores a set of previously saved properties from a data storage
10255  restore: function( element, set ) {
10256    var val, i;
10257    for ( i = 0; i < set.length; i++ ) {
10258      if ( set[ i ] !== null ) {
10259        val = element.data( dataSpace + set[ i ] );
10260        // support: jQuery 1.6.2
10261        // http://bugs.jquery.com/ticket/9917
10262        // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10263        // We can't differentiate between "" and 0 here, so we just assume
10264        // empty string since it's likely to be a more common value...
10265        if ( val === undefined ) {
10266          val = "";
10267        }
10268        element.css( set[ i ], val );
10269      }
10270    }
10271  },
10272
10273  setMode: function( el, mode ) {
10274    if (mode === "toggle") {
10275      mode = el.is( ":hidden" ) ? "show" : "hide";
10276    }
10277    return mode;
10278  },
10279
10280  // Translates a [top,left] array into a baseline value
10281  // this should be a little more flexible in the future to handle a string & hash
10282  getBaseline: function( origin, original ) {
10283    var y, x;
10284    switch ( origin[ 0 ] ) {
10285      case "top": y = 0; break;
10286      case "middle": y = 0.5; break;
10287      case "bottom": y = 1; break;
10288      default: y = origin[ 0 ] / original.height;
10289    }
10290    switch ( origin[ 1 ] ) {
10291      case "left": x = 0; break;
10292      case "center": x = 0.5; break;
10293      case "right": x = 1; break;
10294      default: x = origin[ 1 ] / original.width;
10295    }
10296    return {
10297      x: x,
10298      y: y
10299    };
10300  },
10301
10302  // Wraps the element around a wrapper that copies position properties
10303  createWrapper: function( element ) {
10304
10305    // if the element is already wrapped, return it
10306    if ( element.parent().is( ".ui-effects-wrapper" )) {
10307      return element.parent();
10308    }
10309
10310    // wrap the element
10311    var props = {
10312        width: element.outerWidth(true),
10313        height: element.outerHeight(true),
10314        "float": element.css( "float" )
10315      },
10316      wrapper = $( "<div></div>" )
10317        .addClass( "ui-effects-wrapper" )
10318        .css({
10319          fontSize: "100%",
10320          background: "transparent",
10321          border: "none",
10322          margin: 0,
10323          padding: 0
10324        }),
10325      // Store the size in case width/height are defined in % - Fixes #5245
10326      size = {
10327        width: element.width(),
10328        height: element.height()
10329      },
10330      active = document.activeElement;
10331
10332    // support: Firefox
10333    // Firefox incorrectly exposes anonymous content
10334    // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10335    try {
10336      active.id;
10337    } catch ( e ) {
10338      active = document.body;
10339    }
10340
10341    element.wrap( wrapper );
10342
10343    // Fixes #7595 - Elements lose focus when wrapped.
10344    if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10345      $( active ).focus();
10346    }
10347
10348    wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10349
10350    // transfer positioning properties to the wrapper
10351    if ( element.css( "position" ) === "static" ) {
10352      wrapper.css({ position: "relative" });
10353      element.css({ position: "relative" });
10354    } else {
10355      $.extend( props, {
10356        position: element.css( "position" ),
10357        zIndex: element.css( "z-index" )
10358      });
10359      $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10360        props[ pos ] = element.css( pos );
10361        if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10362          props[ pos ] = "auto";
10363        }
10364      });
10365      element.css({
10366        position: "relative",
10367        top: 0,
10368        left: 0,
10369        right: "auto",
10370        bottom: "auto"
10371      });
10372    }
10373    element.css(size);
10374
10375    return wrapper.css( props ).show();
10376  },
10377
10378  removeWrapper: function( element ) {
10379    var active = document.activeElement;
10380
10381    if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10382      element.parent().replaceWith( element );
10383
10384      // Fixes #7595 - Elements lose focus when wrapped.
10385      if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10386        $( active ).focus();
10387      }
10388    }
10389
10390    return element;
10391  },
10392
10393  setTransition: function( element, list, factor, value ) {
10394    value = value || {};
10395    $.each( list, function( i, x ) {
10396      var unit = element.cssUnit( x );
10397      if ( unit[ 0 ] > 0 ) {
10398        value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10399      }
10400    });
10401    return value;
10402  }
10403});
10404
10405// return an effect options object for the given parameters:
10406function _normalizeArguments( effect, options, speed, callback ) {
10407
10408  // allow passing all options as the first parameter
10409  if ( $.isPlainObject( effect ) ) {
10410    options = effect;
10411    effect = effect.effect;
10412  }
10413
10414  // convert to an object
10415  effect = { effect: effect };
10416
10417  // catch (effect, null, ...)
10418  if ( options == null ) {
10419    options = {};
10420  }
10421
10422  // catch (effect, callback)
10423  if ( $.isFunction( options ) ) {
10424    callback = options;
10425    speed = null;
10426    options = {};
10427  }
10428
10429  // catch (effect, speed, ?)
10430  if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10431    callback = speed;
10432    speed = options;
10433    options = {};
10434  }
10435
10436  // catch (effect, options, callback)
10437  if ( $.isFunction( speed ) ) {
10438    callback = speed;
10439    speed = null;
10440  }
10441
10442  // add options to effect
10443  if ( options ) {
10444    $.extend( effect, options );
10445  }
10446
10447  speed = speed || options.duration;
10448  effect.duration = $.fx.off ? 0 :
10449    typeof speed === "number" ? speed :
10450    speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10451    $.fx.speeds._default;
10452
10453  effect.complete = callback || options.complete;
10454
10455  return effect;
10456}
10457
10458function standardAnimationOption( option ) {
10459  // Valid standard speeds (nothing, number, named speed)
10460  if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10461    return true;
10462  }
10463
10464  // Invalid strings - treat as "normal" speed
10465  if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10466    return true;
10467  }
10468
10469  // Complete callback
10470  if ( $.isFunction( option ) ) {
10471    return true;
10472  }
10473
10474  // Options hash (but not naming an effect)
10475  if ( typeof option === "object" && !option.effect ) {
10476    return true;
10477  }
10478
10479  // Didn't match any standard API
10480  return false;
10481}
10482
10483$.fn.extend({
10484  effect: function( /* effect, options, speed, callback */ ) {
10485    var args = _normalizeArguments.apply( this, arguments ),
10486      mode = args.mode,
10487      queue = args.queue,
10488      effectMethod = $.effects.effect[ args.effect ];
10489
10490    if ( $.fx.off || !effectMethod ) {
10491      // delegate to the original method (e.g., .show()) if possible
10492      if ( mode ) {
10493        return this[ mode ]( args.duration, args.complete );
10494      } else {
10495        return this.each( function() {
10496          if ( args.complete ) {
10497            args.complete.call( this );
10498          }
10499        });
10500      }
10501    }
10502
10503    function run( next ) {
10504      var elem = $( this ),
10505        complete = args.complete,
10506        mode = args.mode;
10507
10508      function done() {
10509        if ( $.isFunction( complete ) ) {
10510          complete.call( elem[0] );
10511        }
10512        if ( $.isFunction( next ) ) {
10513          next();
10514        }
10515      }
10516
10517      // If the element already has the correct final state, delegate to
10518      // the core methods so the internal tracking of "olddisplay" works.
10519      if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10520        elem[ mode ]();
10521        done();
10522      } else {
10523        effectMethod.call( elem[0], args, done );
10524      }
10525    }
10526
10527    return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10528  },
10529
10530  show: (function( orig ) {
10531    return function( option ) {
10532      if ( standardAnimationOption( option ) ) {
10533        return orig.apply( this, arguments );
10534      } else {
10535        var args = _normalizeArguments.apply( this, arguments );
10536        args.mode = "show";
10537        return this.effect.call( this, args );
10538      }
10539    };
10540  })( $.fn.show ),
10541
10542  hide: (function( orig ) {
10543    return function( option ) {
10544      if ( standardAnimationOption( option ) ) {
10545        return orig.apply( this, arguments );
10546      } else {
10547        var args = _normalizeArguments.apply( this, arguments );
10548        args.mode = "hide";
10549        return this.effect.call( this, args );
10550      }
10551    };
10552  })( $.fn.hide ),
10553
10554  toggle: (function( orig ) {
10555    return function( option ) {
10556      if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10557        return orig.apply( this, arguments );
10558      } else {
10559        var args = _normalizeArguments.apply( this, arguments );
10560        args.mode = "toggle";
10561        return this.effect.call( this, args );
10562      }
10563    };
10564  })( $.fn.toggle ),
10565
10566  // helper functions
10567  cssUnit: function(key) {
10568    var style = this.css( key ),
10569      val = [];
10570
10571    $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10572      if ( style.indexOf( unit ) > 0 ) {
10573        val = [ parseFloat( style ), unit ];
10574      }
10575    });
10576    return val;
10577  }
10578});
10579
10580})();
10581
10582/******************************************************************************/
10583/*********************************** EASING ***********************************/
10584/******************************************************************************/
10585
10586(function() {
10587
10588// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10589
10590var baseEasings = {};
10591
10592$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10593  baseEasings[ name ] = function( p ) {
10594    return Math.pow( p, i + 2 );
10595  };
10596});
10597
10598$.extend( baseEasings, {
10599  Sine: function( p ) {
10600    return 1 - Math.cos( p * Math.PI / 2 );
10601  },
10602  Circ: function( p ) {
10603    return 1 - Math.sqrt( 1 - p * p );
10604  },
10605  Elastic: function( p ) {
10606    return p === 0 || p === 1 ? p :
10607      -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10608  },
10609  Back: function( p ) {
10610    return p * p * ( 3 * p - 2 );
10611  },
10612  Bounce: function( p ) {
10613    var pow2,
10614      bounce = 4;
10615
10616    while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10617    return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10618  }
10619});
10620
10621$.each( baseEasings, function( name, easeIn ) {
10622  $.easing[ "easeIn" + name ] = easeIn;
10623  $.easing[ "easeOut" + name ] = function( p ) {
10624    return 1 - easeIn( 1 - p );
10625  };
10626  $.easing[ "easeInOut" + name ] = function( p ) {
10627    return p < 0.5 ?
10628      easeIn( p * 2 ) / 2 :
10629      1 - easeIn( p * -2 + 2 ) / 2;
10630  };
10631});
10632
10633})();
10634
10635var effect = $.effects;
10636
10637
10638/*!
10639 * jQuery UI Effects Blind 1.11.4
10640 * http://jqueryui.com
10641 *
10642 * Copyright jQuery Foundation and other contributors
10643 * Released under the MIT license.
10644 * http://jquery.org/license
10645 *
10646 * http://api.jqueryui.com/blind-effect/
10647 */
10648
10649
10650var effectBlind = $.effects.effect.blind = function( o, done ) {
10651  // Create element
10652  var el = $( this ),
10653    rvertical = /up|down|vertical/,
10654    rpositivemotion = /up|left|vertical|horizontal/,
10655    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10656    mode = $.effects.setMode( el, o.mode || "hide" ),
10657    direction = o.direction || "up",
10658    vertical = rvertical.test( direction ),
10659    ref = vertical ? "height" : "width",
10660    ref2 = vertical ? "top" : "left",
10661    motion = rpositivemotion.test( direction ),
10662    animation = {},
10663    show = mode === "show",
10664    wrapper, distance, margin;
10665
10666  // if already wrapped, the wrapper's properties are my property. #6245
10667  if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10668    $.effects.save( el.parent(), props );
10669  } else {
10670    $.effects.save( el, props );
10671  }
10672  el.show();
10673  wrapper = $.effects.createWrapper( el ).css({
10674    overflow: "hidden"
10675  });
10676
10677  distance = wrapper[ ref ]();
10678  margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10679
10680  animation[ ref ] = show ? distance : 0;
10681  if ( !motion ) {
10682    el
10683      .css( vertical ? "bottom" : "right", 0 )
10684      .css( vertical ? "top" : "left", "auto" )
10685      .css({ position: "absolute" });
10686
10687    animation[ ref2 ] = show ? margin : distance + margin;
10688  }
10689
10690  // start at 0 if we are showing
10691  if ( show ) {
10692    wrapper.css( ref, 0 );
10693    if ( !motion ) {
10694      wrapper.css( ref2, margin + distance );
10695    }
10696  }
10697
10698  // Animate
10699  wrapper.animate( animation, {
10700    duration: o.duration,
10701    easing: o.easing,
10702    queue: false,
10703    complete: function() {
10704      if ( mode === "hide" ) {
10705        el.hide();
10706      }
10707      $.effects.restore( el, props );
10708      $.effects.removeWrapper( el );
10709      done();
10710    }
10711  });
10712};
10713
10714
10715/*!
10716 * jQuery UI Effects Bounce 1.11.4
10717 * http://jqueryui.com
10718 *
10719 * Copyright jQuery Foundation and other contributors
10720 * Released under the MIT license.
10721 * http://jquery.org/license
10722 *
10723 * http://api.jqueryui.com/bounce-effect/
10724 */
10725
10726
10727var effectBounce = $.effects.effect.bounce = function( o, done ) {
10728  var el = $( this ),
10729    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10730
10731    // defaults:
10732    mode = $.effects.setMode( el, o.mode || "effect" ),
10733    hide = mode === "hide",
10734    show = mode === "show",
10735    direction = o.direction || "up",
10736    distance = o.distance,
10737    times = o.times || 5,
10738
10739    // number of internal animations
10740    anims = times * 2 + ( show || hide ? 1 : 0 ),
10741    speed = o.duration / anims,
10742    easing = o.easing,
10743
10744    // utility:
10745    ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10746    motion = ( direction === "up" || direction === "left" ),
10747    i,
10748    upAnim,
10749    downAnim,
10750
10751    // we will need to re-assemble the queue to stack our animations in place
10752    queue = el.queue(),
10753    queuelen = queue.length;
10754
10755  // Avoid touching opacity to prevent clearType and PNG issues in IE
10756  if ( show || hide ) {
10757    props.push( "opacity" );
10758  }
10759
10760  $.effects.save( el, props );
10761  el.show();
10762  $.effects.createWrapper( el ); // Create Wrapper
10763
10764  // default distance for the BIGGEST bounce is the outer Distance / 3
10765  if ( !distance ) {
10766    distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10767  }
10768
10769  if ( show ) {
10770    downAnim = { opacity: 1 };
10771    downAnim[ ref ] = 0;
10772
10773    // if we are showing, force opacity 0 and set the initial position
10774    // then do the "first" animation
10775    el.css( "opacity", 0 )
10776      .css( ref, motion ? -distance * 2 : distance * 2 )
10777      .animate( downAnim, speed, easing );
10778  }
10779
10780  // start at the smallest distance if we are hiding
10781  if ( hide ) {
10782    distance = distance / Math.pow( 2, times - 1 );
10783  }
10784
10785  downAnim = {};
10786  downAnim[ ref ] = 0;
10787  // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10788  for ( i = 0; i < times; i++ ) {
10789    upAnim = {};
10790    upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10791
10792    el.animate( upAnim, speed, easing )
10793      .animate( downAnim, speed, easing );
10794
10795    distance = hide ? distance * 2 : distance / 2;
10796  }
10797
10798  // Last Bounce when Hiding
10799  if ( hide ) {
10800    upAnim = { opacity: 0 };
10801    upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10802
10803    el.animate( upAnim, speed, easing );
10804  }
10805
10806  el.queue(function() {
10807    if ( hide ) {
10808      el.hide();
10809    }
10810    $.effects.restore( el, props );
10811    $.effects.removeWrapper( el );
10812    done();
10813  });
10814
10815  // inject all the animations we just queued to be first in line (after "inprogress")
10816  if ( queuelen > 1) {
10817    queue.splice.apply( queue,
10818      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10819  }
10820  el.dequeue();
10821
10822};
10823
10824
10825/*!
10826 * jQuery UI Effects Clip 1.11.4
10827 * http://jqueryui.com
10828 *
10829 * Copyright jQuery Foundation and other contributors
10830 * Released under the MIT license.
10831 * http://jquery.org/license
10832 *
10833 * http://api.jqueryui.com/clip-effect/
10834 */
10835
10836
10837var effectClip = $.effects.effect.clip = function( o, done ) {
10838  // Create element
10839  var el = $( this ),
10840    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10841    mode = $.effects.setMode( el, o.mode || "hide" ),
10842    show = mode === "show",
10843    direction = o.direction || "vertical",
10844    vert = direction === "vertical",
10845    size = vert ? "height" : "width",
10846    position = vert ? "top" : "left",
10847    animation = {},
10848    wrapper, animate, distance;
10849
10850  // Save & Show
10851  $.effects.save( el, props );
10852  el.show();
10853
10854  // Create Wrapper
10855  wrapper = $.effects.createWrapper( el ).css({
10856    overflow: "hidden"
10857  });
10858  animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10859  distance = animate[ size ]();
10860
10861  // Shift
10862  if ( show ) {
10863    animate.css( size, 0 );
10864    animate.css( position, distance / 2 );
10865  }
10866
10867  // Create Animation Object:
10868  animation[ size ] = show ? distance : 0;
10869  animation[ position ] = show ? 0 : distance / 2;
10870
10871  // Animate
10872  animate.animate( animation, {
10873    queue: false,
10874    duration: o.duration,
10875    easing: o.easing,
10876    complete: function() {
10877      if ( !show ) {
10878        el.hide();
10879      }
10880      $.effects.restore( el, props );
10881      $.effects.removeWrapper( el );
10882      done();
10883    }
10884  });
10885
10886};
10887
10888
10889/*!
10890 * jQuery UI Effects Drop 1.11.4
10891 * http://jqueryui.com
10892 *
10893 * Copyright jQuery Foundation and other contributors
10894 * Released under the MIT license.
10895 * http://jquery.org/license
10896 *
10897 * http://api.jqueryui.com/drop-effect/
10898 */
10899
10900
10901var effectDrop = $.effects.effect.drop = function( o, done ) {
10902
10903  var el = $( this ),
10904    props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10905    mode = $.effects.setMode( el, o.mode || "hide" ),
10906    show = mode === "show",
10907    direction = o.direction || "left",
10908    ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10909    motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10910    animation = {
10911      opacity: show ? 1 : 0
10912    },
10913    distance;
10914
10915  // Adjust
10916  $.effects.save( el, props );
10917  el.show();
10918  $.effects.createWrapper( el );
10919
10920  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
10921
10922  if ( show ) {
10923    el
10924      .css( "opacity", 0 )
10925      .css( ref, motion === "pos" ? -distance : distance );
10926  }
10927
10928  // Animation
10929  animation[ ref ] = ( show ?
10930    ( motion === "pos" ? "+=" : "-=" ) :
10931    ( motion === "pos" ? "-=" : "+=" ) ) +
10932    distance;
10933
10934  // Animate
10935  el.animate( animation, {
10936    queue: false,
10937    duration: o.duration,
10938    easing: o.easing,
10939    complete: function() {
10940      if ( mode === "hide" ) {
10941        el.hide();
10942      }
10943      $.effects.restore( el, props );
10944      $.effects.removeWrapper( el );
10945      done();
10946    }
10947  });
10948};
10949
10950
10951/*!
10952 * jQuery UI Effects Explode 1.11.4
10953 * http://jqueryui.com
10954 *
10955 * Copyright jQuery Foundation and other contributors
10956 * Released under the MIT license.
10957 * http://jquery.org/license
10958 *
10959 * http://api.jqueryui.com/explode-effect/
10960 */
10961
10962
10963var effectExplode = $.effects.effect.explode = function( o, done ) {
10964
10965  var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10966    cells = rows,
10967    el = $( this ),
10968    mode = $.effects.setMode( el, o.mode || "hide" ),
10969    show = mode === "show",
10970
10971    // show and then visibility:hidden the element before calculating offset
10972    offset = el.show().css( "visibility", "hidden" ).offset(),
10973
10974    // width and height of a piece
10975    width = Math.ceil( el.outerWidth() / cells ),
10976    height = Math.ceil( el.outerHeight() / rows ),
10977    pieces = [],
10978
10979    // loop
10980    i, j, left, top, mx, my;
10981
10982  // children animate complete:
10983  function childComplete() {
10984    pieces.push( this );
10985    if ( pieces.length === rows * cells ) {
10986      animComplete();
10987    }
10988  }
10989
10990  // clone the element for each row and cell.
10991  for ( i = 0; i < rows ; i++ ) { // ===>
10992    top = offset.top + i * height;
10993    my = i - ( rows - 1 ) / 2 ;
10994
10995    for ( j = 0; j < cells ; j++ ) { // |||
10996      left = offset.left + j * width;
10997      mx = j - ( cells - 1 ) / 2 ;
10998
10999      // Create a clone of the now hidden main element that will be absolute positioned
11000      // within a wrapper div off the -left and -top equal to size of our pieces
11001      el
11002        .clone()
11003        .appendTo( "body" )
11004        .wrap( "<div></div>" )
11005        .css({
11006          position: "absolute",
11007          visibility: "visible",
11008          left: -j * width,
11009          top: -i * height
11010        })
11011
11012      // select the wrapper - make it overflow: hidden and absolute positioned based on
11013      // where the original was located +left and +top equal to the size of pieces
11014        .parent()
11015        .addClass( "ui-effects-explode" )
11016        .css({
11017          position: "absolute",
11018          overflow: "hidden",
11019          width: width,
11020          height: height,
11021          left: left + ( show ? mx * width : 0 ),
11022          top: top + ( show ? my * height : 0 ),
11023          opacity: show ? 0 : 1
11024        }).animate({
11025          left: left + ( show ? 0 : mx * width ),
11026          top: top + ( show ? 0 : my * height ),
11027          opacity: show ? 1 : 0
11028        }, o.duration || 500, o.easing, childComplete );
11029    }
11030  }
11031
11032  function animComplete() {
11033    el.css({
11034      visibility: "visible"
11035    });
11036    $( pieces ).remove();
11037    if ( !show ) {
11038      el.hide();
11039    }
11040    done();
11041  }
11042};
11043
11044
11045/*!
11046 * jQuery UI Effects Fade 1.11.4
11047 * http://jqueryui.com
11048 *
11049 * Copyright jQuery Foundation and other contributors
11050 * Released under the MIT license.
11051 * http://jquery.org/license
11052 *
11053 * http://api.jqueryui.com/fade-effect/
11054 */
11055
11056
11057var effectFade = $.effects.effect.fade = function( o, done ) {
11058  var el = $( this ),
11059    mode = $.effects.setMode( el, o.mode || "toggle" );
11060
11061  el.animate({
11062    opacity: mode
11063  }, {
11064    queue: false,
11065    duration: o.duration,
11066    easing: o.easing,
11067    complete: done
11068  });
11069};
11070
11071
11072/*!
11073 * jQuery UI Effects Fold 1.11.4
11074 * http://jqueryui.com
11075 *
11076 * Copyright jQuery Foundation and other contributors
11077 * Released under the MIT license.
11078 * http://jquery.org/license
11079 *
11080 * http://api.jqueryui.com/fold-effect/
11081 */
11082
11083
11084var effectFold = $.effects.effect.fold = function( o, done ) {
11085
11086  // Create element
11087  var el = $( this ),
11088    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11089    mode = $.effects.setMode( el, o.mode || "hide" ),
11090    show = mode === "show",
11091    hide = mode === "hide",
11092    size = o.size || 15,
11093    percent = /([0-9]+)%/.exec( size ),
11094    horizFirst = !!o.horizFirst,
11095    widthFirst = show !== horizFirst,
11096    ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
11097    duration = o.duration / 2,
11098    wrapper, distance,
11099    animation1 = {},
11100    animation2 = {};
11101
11102  $.effects.save( el, props );
11103  el.show();
11104
11105  // Create Wrapper
11106  wrapper = $.effects.createWrapper( el ).css({
11107    overflow: "hidden"
11108  });
11109  distance = widthFirst ?
11110    [ wrapper.width(), wrapper.height() ] :
11111    [ wrapper.height(), wrapper.width() ];
11112
11113  if ( percent ) {
11114    size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
11115  }
11116  if ( show ) {
11117    wrapper.css( horizFirst ? {
11118      height: 0,
11119      width: size
11120    } : {
11121      height: size,
11122      width: 0
11123    });
11124  }
11125
11126  // Animation
11127  animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
11128  animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
11129
11130  // Animate
11131  wrapper
11132    .animate( animation1, duration, o.easing )
11133    .animate( animation2, duration, o.easing, function() {
11134      if ( hide ) {
11135        el.hide();
11136      }
11137      $.effects.restore( el, props );
11138      $.effects.removeWrapper( el );
11139      done();
11140    });
11141
11142};
11143
11144
11145/*!
11146 * jQuery UI Effects Highlight 1.11.4
11147 * http://jqueryui.com
11148 *
11149 * Copyright jQuery Foundation and other contributors
11150 * Released under the MIT license.
11151 * http://jquery.org/license
11152 *
11153 * http://api.jqueryui.com/highlight-effect/
11154 */
11155
11156
11157var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11158  var elem = $( this ),
11159    props = [ "backgroundImage", "backgroundColor", "opacity" ],
11160    mode = $.effects.setMode( elem, o.mode || "show" ),
11161    animation = {
11162      backgroundColor: elem.css( "backgroundColor" )
11163    };
11164
11165  if (mode === "hide") {
11166    animation.opacity = 0;
11167  }
11168
11169  $.effects.save( elem, props );
11170
11171  elem
11172    .show()
11173    .css({
11174      backgroundImage: "none",
11175      backgroundColor: o.color || "#ffff99"
11176    })
11177    .animate( animation, {
11178      queue: false,
11179      duration: o.duration,
11180      easing: o.easing,
11181      complete: function() {
11182        if ( mode === "hide" ) {
11183          elem.hide();
11184        }
11185        $.effects.restore( elem, props );
11186        done();
11187      }
11188    });
11189};
11190
11191
11192/*!
11193 * jQuery UI Effects Size 1.11.4
11194 * http://jqueryui.com
11195 *
11196 * Copyright jQuery Foundation and other contributors
11197 * Released under the MIT license.
11198 * http://jquery.org/license
11199 *
11200 * http://api.jqueryui.com/size-effect/
11201 */
11202
11203
11204var effectSize = $.effects.effect.size = function( o, done ) {
11205
11206  // Create element
11207  var original, baseline, factor,
11208    el = $( this ),
11209    props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11210
11211    // Always restore
11212    props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11213
11214    // Copy for children
11215    props2 = [ "width", "height", "overflow" ],
11216    cProps = [ "fontSize" ],
11217    vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11218    hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11219
11220    // Set options
11221    mode = $.effects.setMode( el, o.mode || "effect" ),
11222    restore = o.restore || mode !== "effect",
11223    scale = o.scale || "both",
11224    origin = o.origin || [ "middle", "center" ],
11225    position = el.css( "position" ),
11226    props = restore ? props0 : props1,
11227    zero = {
11228      height: 0,
11229      width: 0,
11230      outerHeight: 0,
11231      outerWidth: 0
11232    };
11233
11234  if ( mode === "show" ) {
11235    el.show();
11236  }
11237  original = {
11238    height: el.height(),
11239    width: el.width(),
11240    outerHeight: el.outerHeight(),
11241    outerWidth: el.outerWidth()
11242  };
11243
11244  if ( o.mode === "toggle" && mode === "show" ) {
11245    el.from = o.to || zero;
11246    el.to = o.from || original;
11247  } else {
11248    el.from = o.from || ( mode === "show" ? zero : original );
11249    el.to = o.to || ( mode === "hide" ? zero : original );
11250  }
11251
11252  // Set scaling factor
11253  factor = {
11254    from: {
11255      y: el.from.height / original.height,
11256      x: el.from.width / original.width
11257    },
11258    to: {
11259      y: el.to.height / original.height,
11260      x: el.to.width / original.width
11261    }
11262  };
11263
11264  // Scale the css box
11265  if ( scale === "box" || scale === "both" ) {
11266
11267    // Vertical props scaling
11268    if ( factor.from.y !== factor.to.y ) {
11269      props = props.concat( vProps );
11270      el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11271      el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11272    }
11273
11274    // Horizontal props scaling
11275    if ( factor.from.x !== factor.to.x ) {
11276      props = props.concat( hProps );
11277      el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11278      el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11279    }
11280  }
11281
11282  // Scale the content
11283  if ( scale === "content" || scale === "both" ) {
11284
11285    // Vertical props scaling
11286    if ( factor.from.y !== factor.to.y ) {
11287      props = props.concat( cProps ).concat( props2 );
11288      el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11289      el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11290    }
11291  }
11292
11293  $.effects.save( el, props );
11294  el.show();
11295  $.effects.createWrapper( el );
11296  el.css( "overflow", "hidden" ).css( el.from );
11297
11298  // Adjust
11299  if (origin) { // Calculate baseline shifts
11300    baseline = $.effects.getBaseline( origin, original );
11301    el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11302    el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11303    el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11304    el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11305  }
11306  el.css( el.from ); // set top & left
11307
11308  // Animate
11309  if ( scale === "content" || scale === "both" ) { // Scale the children
11310
11311    // Add margins/font-size
11312    vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11313    hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11314    props2 = props0.concat(vProps).concat(hProps);
11315
11316    el.find( "*[width]" ).each( function() {
11317      var child = $( this ),
11318        c_original = {
11319          height: child.height(),
11320          width: child.width(),
11321          outerHeight: child.outerHeight(),
11322          outerWidth: child.outerWidth()
11323        };
11324      if (restore) {
11325        $.effects.save(child, props2);
11326      }
11327
11328      child.from = {
11329        height: c_original.height * factor.from.y,
11330        width: c_original.width * factor.from.x,
11331        outerHeight: c_original.outerHeight * factor.from.y,
11332        outerWidth: c_original.outerWidth * factor.from.x
11333      };
11334      child.to = {
11335        height: c_original.height * factor.to.y,
11336        width: c_original.width * factor.to.x,
11337        outerHeight: c_original.height * factor.to.y,
11338        outerWidth: c_original.width * factor.to.x
11339      };
11340
11341      // Vertical props scaling
11342      if ( factor.from.y !== factor.to.y ) {
11343        child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11344        child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11345      }
11346
11347      // Horizontal props scaling
11348      if ( factor.from.x !== factor.to.x ) {
11349        child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11350        child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11351      }
11352
11353      // Animate children
11354      child.css( child.from );
11355      child.animate( child.to, o.duration, o.easing, function() {
11356
11357        // Restore children
11358        if ( restore ) {
11359          $.effects.restore( child, props2 );
11360        }
11361      });
11362    });
11363  }
11364
11365  // Animate
11366  el.animate( el.to, {
11367    queue: false,
11368    duration: o.duration,
11369    easing: o.easing,
11370    complete: function() {
11371      if ( el.to.opacity === 0 ) {
11372        el.css( "opacity", el.from.opacity );
11373      }
11374      if ( mode === "hide" ) {
11375        el.hide();
11376      }
11377      $.effects.restore( el, props );
11378      if ( !restore ) {
11379
11380        // we need to calculate our new positioning based on the scaling
11381        if ( position === "static" ) {
11382          el.css({
11383            position: "relative",
11384            top: el.to.top,
11385            left: el.to.left
11386          });
11387        } else {
11388          $.each([ "top", "left" ], function( idx, pos ) {
11389            el.css( pos, function( _, str ) {
11390              var val = parseInt( str, 10 ),
11391                toRef = idx ? el.to.left : el.to.top;
11392
11393              // if original was "auto", recalculate the new value from wrapper
11394              if ( str === "auto" ) {
11395                return toRef + "px";
11396              }
11397
11398              return val + toRef + "px";
11399            });
11400          });
11401        }
11402      }
11403
11404      $.effects.removeWrapper( el );
11405      done();
11406    }
11407  });
11408
11409};
11410
11411
11412/*!
11413 * jQuery UI Effects Scale 1.11.4
11414 * http://jqueryui.com
11415 *
11416 * Copyright jQuery Foundation and other contributors
11417 * Released under the MIT license.
11418 * http://jquery.org/license
11419 *
11420 * http://api.jqueryui.com/scale-effect/
11421 */
11422
11423
11424var effectScale = $.effects.effect.scale = function( o, done ) {
11425
11426  // Create element
11427  var el = $( this ),
11428    options = $.extend( true, {}, o ),
11429    mode = $.effects.setMode( el, o.mode || "effect" ),
11430    percent = parseInt( o.percent, 10 ) ||
11431      ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11432    direction = o.direction || "both",
11433    origin = o.origin,
11434    original = {
11435      height: el.height(),
11436      width: el.width(),
11437      outerHeight: el.outerHeight(),
11438      outerWidth: el.outerWidth()
11439    },
11440    factor = {
11441      y: direction !== "horizontal" ? (percent / 100) : 1,
11442      x: direction !== "vertical" ? (percent / 100) : 1
11443    };
11444
11445  // We are going to pass this effect to the size effect:
11446  options.effect = "size";
11447  options.queue = false;
11448  options.complete = done;
11449
11450  // Set default origin and restore for show/hide
11451  if ( mode !== "effect" ) {
11452    options.origin = origin || [ "middle", "center" ];
11453    options.restore = true;
11454  }
11455
11456  options.from = o.from || ( mode === "show" ? {
11457    height: 0,
11458    width: 0,
11459    outerHeight: 0,
11460    outerWidth: 0
11461  } : original );
11462  options.to = {
11463    height: original.height * factor.y,
11464    width: original.width * factor.x,
11465    outerHeight: original.outerHeight * factor.y,
11466    outerWidth: original.outerWidth * factor.x
11467  };
11468
11469  // Fade option to support puff
11470  if ( options.fade ) {
11471    if ( mode === "show" ) {
11472      options.from.opacity = 0;
11473      options.to.opacity = 1;
11474    }
11475    if ( mode === "hide" ) {
11476      options.from.opacity = 1;
11477      options.to.opacity = 0;
11478    }
11479  }
11480
11481  // Animate
11482  el.effect( options );
11483
11484};
11485
11486
11487/*!
11488 * jQuery UI Effects Puff 1.11.4
11489 * http://jqueryui.com
11490 *
11491 * Copyright jQuery Foundation and other contributors
11492 * Released under the MIT license.
11493 * http://jquery.org/license
11494 *
11495 * http://api.jqueryui.com/puff-effect/
11496 */
11497
11498
11499var effectPuff = $.effects.effect.puff = function( o, done ) {
11500  var elem = $( this ),
11501    mode = $.effects.setMode( elem, o.mode || "hide" ),
11502    hide = mode === "hide",
11503    percent = parseInt( o.percent, 10 ) || 150,
11504    factor = percent / 100,
11505    original = {
11506      height: elem.height(),
11507      width: elem.width(),
11508      outerHeight: elem.outerHeight(),
11509      outerWidth: elem.outerWidth()
11510    };
11511
11512  $.extend( o, {
11513    effect: "scale",
11514    queue: false,
11515    fade: true,
11516    mode: mode,
11517    complete: done,
11518    percent: hide ? percent : 100,
11519    from: hide ?
11520      original :
11521      {
11522        height: original.height * factor,
11523        width: original.width * factor,
11524        outerHeight: original.outerHeight * factor,
11525        outerWidth: original.outerWidth * factor
11526      }
11527  });
11528
11529  elem.effect( o );
11530};
11531
11532
11533/*!
11534 * jQuery UI Effects Pulsate 1.11.4
11535 * http://jqueryui.com
11536 *
11537 * Copyright jQuery Foundation and other contributors
11538 * Released under the MIT license.
11539 * http://jquery.org/license
11540 *
11541 * http://api.jqueryui.com/pulsate-effect/
11542 */
11543
11544
11545var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11546  var elem = $( this ),
11547    mode = $.effects.setMode( elem, o.mode || "show" ),
11548    show = mode === "show",
11549    hide = mode === "hide",
11550    showhide = ( show || mode === "hide" ),
11551
11552    // showing or hiding leaves of the "last" animation
11553    anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11554    duration = o.duration / anims,
11555    animateTo = 0,
11556    queue = elem.queue(),
11557    queuelen = queue.length,
11558    i;
11559
11560  if ( show || !elem.is(":visible")) {
11561    elem.css( "opacity", 0 ).show();
11562    animateTo = 1;
11563  }
11564
11565  // anims - 1 opacity "toggles"
11566  for ( i = 1; i < anims; i++ ) {
11567    elem.animate({
11568      opacity: animateTo
11569    }, duration, o.easing );
11570    animateTo = 1 - animateTo;
11571  }
11572
11573  elem.animate({
11574    opacity: animateTo
11575  }, duration, o.easing);
11576
11577  elem.queue(function() {
11578    if ( hide ) {
11579      elem.hide();
11580    }
11581    done();
11582  });
11583
11584  // We just queued up "anims" animations, we need to put them next in the queue
11585  if ( queuelen > 1 ) {
11586    queue.splice.apply( queue,
11587      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11588  }
11589  elem.dequeue();
11590};
11591
11592
11593/*!
11594 * jQuery UI Effects Shake 1.11.4
11595 * http://jqueryui.com
11596 *
11597 * Copyright jQuery Foundation and other contributors
11598 * Released under the MIT license.
11599 * http://jquery.org/license
11600 *
11601 * http://api.jqueryui.com/shake-effect/
11602 */
11603
11604
11605var effectShake = $.effects.effect.shake = function( o, done ) {
11606
11607  var el = $( this ),
11608    props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11609    mode = $.effects.setMode( el, o.mode || "effect" ),
11610    direction = o.direction || "left",
11611    distance = o.distance || 20,
11612    times = o.times || 3,
11613    anims = times * 2 + 1,
11614    speed = Math.round( o.duration / anims ),
11615    ref = (direction === "up" || direction === "down") ? "top" : "left",
11616    positiveMotion = (direction === "up" || direction === "left"),
11617    animation = {},
11618    animation1 = {},
11619    animation2 = {},
11620    i,
11621
11622    // we will need to re-assemble the queue to stack our animations in place
11623    queue = el.queue(),
11624    queuelen = queue.length;
11625
11626  $.effects.save( el, props );
11627  el.show();
11628  $.effects.createWrapper( el );
11629
11630  // Animation
11631  animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11632  animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11633  animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11634
11635  // Animate
11636  el.animate( animation, speed, o.easing );
11637
11638  // Shakes
11639  for ( i = 1; i < times; i++ ) {
11640    el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11641  }
11642  el
11643    .animate( animation1, speed, o.easing )
11644    .animate( animation, speed / 2, o.easing )
11645    .queue(function() {
11646      if ( mode === "hide" ) {
11647        el.hide();
11648      }
11649      $.effects.restore( el, props );
11650      $.effects.removeWrapper( el );
11651      done();
11652    });
11653
11654  // inject all the animations we just queued to be first in line (after "inprogress")
11655  if ( queuelen > 1) {
11656    queue.splice.apply( queue,
11657      [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11658  }
11659  el.dequeue();
11660
11661};
11662
11663
11664/*!
11665 * jQuery UI Effects Slide 1.11.4
11666 * http://jqueryui.com
11667 *
11668 * Copyright jQuery Foundation and other contributors
11669 * Released under the MIT license.
11670 * http://jquery.org/license
11671 *
11672 * http://api.jqueryui.com/slide-effect/
11673 */
11674
11675
11676var effectSlide = $.effects.effect.slide = function( o, done ) {
11677
11678  // Create element
11679  var el = $( this ),
11680    props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11681    mode = $.effects.setMode( el, o.mode || "show" ),
11682    show = mode === "show",
11683    direction = o.direction || "left",
11684    ref = (direction === "up" || direction === "down") ? "top" : "left",
11685    positiveMotion = (direction === "up" || direction === "left"),
11686    distance,
11687    animation = {};
11688
11689  // Adjust
11690  $.effects.save( el, props );
11691  el.show();
11692  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11693
11694  $.effects.createWrapper( el ).css({
11695    overflow: "hidden"
11696  });
11697
11698  if ( show ) {
11699    el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11700  }
11701
11702  // Animation
11703  animation[ ref ] = ( show ?
11704    ( positiveMotion ? "+=" : "-=") :
11705    ( positiveMotion ? "-=" : "+=")) +
11706    distance;
11707
11708  // Animate
11709  el.animate( animation, {
11710    queue: false,
11711    duration: o.duration,
11712    easing: o.easing,
11713    complete: function() {
11714      if ( mode === "hide" ) {
11715        el.hide();
11716      }
11717      $.effects.restore( el, props );
11718      $.effects.removeWrapper( el );
11719      done();
11720    }
11721  });
11722};
11723
11724
11725/*!
11726 * jQuery UI Effects Transfer 1.11.4
11727 * http://jqueryui.com
11728 *
11729 * Copyright jQuery Foundation and other contributors
11730 * Released under the MIT license.
11731 * http://jquery.org/license
11732 *
11733 * http://api.jqueryui.com/transfer-effect/
11734 */
11735
11736
11737var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11738  var elem = $( this ),
11739    target = $( o.to ),
11740    targetFixed = target.css( "position" ) === "fixed",
11741    body = $("body"),
11742    fixTop = targetFixed ? body.scrollTop() : 0,
11743    fixLeft = targetFixed ? body.scrollLeft() : 0,
11744    endPosition = target.offset(),
11745    animation = {
11746      top: endPosition.top - fixTop,
11747      left: endPosition.left - fixLeft,
11748      height: target.innerHeight(),
11749      width: target.innerWidth()
11750    },
11751    startPosition = elem.offset(),
11752    transfer = $( "<div class='ui-effects-transfer'></div>" )
11753      .appendTo( document.body )
11754      .addClass( o.className )
11755      .css({
11756        top: startPosition.top - fixTop,
11757        left: startPosition.left - fixLeft,
11758        height: elem.innerHeight(),
11759        width: elem.innerWidth(),
11760        position: targetFixed ? "fixed" : "absolute"
11761      })
11762      .animate( animation, o.duration, o.easing, function() {
11763        transfer.remove();
11764        done();
11765      });
11766};
11767
11768
11769/*!
11770 * jQuery UI Progressbar 1.11.4
11771 * http://jqueryui.com
11772 *
11773 * Copyright jQuery Foundation and other contributors
11774 * Released under the MIT license.
11775 * http://jquery.org/license
11776 *
11777 * http://api.jqueryui.com/progressbar/
11778 */
11779
11780
11781var progressbar = $.widget( "ui.progressbar", {
11782  version: "1.11.4",
11783  options: {
11784    max: 100,
11785    value: 0,
11786
11787    change: null,
11788    complete: null
11789  },
11790
11791  min: 0,
11792
11793  _create: function() {
11794    // Constrain initial value
11795    this.oldValue = this.options.value = this._constrainedValue();
11796
11797    this.element
11798      .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11799      .attr({
11800        // Only set static values, aria-valuenow and aria-valuemax are
11801        // set inside _refreshValue()
11802        role: "progressbar",
11803        "aria-valuemin": this.min
11804      });
11805
11806    this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11807      .appendTo( this.element );
11808
11809    this._refreshValue();
11810  },
11811
11812  _destroy: function() {
11813    this.element
11814      .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11815      .removeAttr( "role" )
11816      .removeAttr( "aria-valuemin" )
11817      .removeAttr( "aria-valuemax" )
11818      .removeAttr( "aria-valuenow" );
11819
11820    this.valueDiv.remove();
11821  },
11822
11823  value: function( newValue ) {
11824    if ( newValue === undefined ) {
11825      return this.options.value;
11826    }
11827
11828    this.options.value = this._constrainedValue( newValue );
11829    this._refreshValue();
11830  },
11831
11832  _constrainedValue: function( newValue ) {
11833    if ( newValue === undefined ) {
11834      newValue = this.options.value;
11835    }
11836
11837    this.indeterminate = newValue === false;
11838
11839    // sanitize value
11840    if ( typeof newValue !== "number" ) {
11841      newValue = 0;
11842    }
11843
11844    return this.indeterminate ? false :
11845      Math.min( this.options.max, Math.max( this.min, newValue ) );
11846  },
11847
11848  _setOptions: function( options ) {
11849    // Ensure "value" option is set after other values (like max)
11850    var value = options.value;
11851    delete options.value;
11852
11853    this._super( options );
11854
11855    this.options.value = this._constrainedValue( value );
11856    this._refreshValue();
11857  },
11858
11859  _setOption: function( key, value ) {
11860    if ( key === "max" ) {
11861      // Don't allow a max less than min
11862      value = Math.max( this.min, value );
11863    }
11864    if ( key === "disabled" ) {
11865      this.element
11866        .toggleClass( "ui-state-disabled", !!value )
11867        .attr( "aria-disabled", value );
11868    }
11869    this._super( key, value );
11870  },
11871
11872  _percentage: function() {
11873    return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11874  },
11875
11876  _refreshValue: function() {
11877    var value = this.options.value,
11878      percentage = this._percentage();
11879
11880    this.valueDiv
11881      .toggle( this.indeterminate || value > this.min )
11882      .toggleClass( "ui-corner-right", value === this.options.max )
11883      .width( percentage.toFixed(0) + "%" );
11884
11885    this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11886
11887    if ( this.indeterminate ) {
11888      this.element.removeAttr( "aria-valuenow" );
11889      if ( !this.overlayDiv ) {
11890        this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11891      }
11892    } else {
11893      this.element.attr({
11894        "aria-valuemax": this.options.max,
11895        "aria-valuenow": value
11896      });
11897      if ( this.overlayDiv ) {
11898        this.overlayDiv.remove();
11899        this.overlayDiv = null;
11900      }
11901    }
11902
11903    if ( this.oldValue !== value ) {
11904      this.oldValue = value;
11905      this._trigger( "change" );
11906    }
11907    if ( value === this.options.max ) {
11908      this._trigger( "complete" );
11909    }
11910  }
11911});
11912
11913
11914/*!
11915 * jQuery UI Selectable 1.11.4
11916 * http://jqueryui.com
11917 *
11918 * Copyright jQuery Foundation and other contributors
11919 * Released under the MIT license.
11920 * http://jquery.org/license
11921 *
11922 * http://api.jqueryui.com/selectable/
11923 */
11924
11925
11926var selectable = $.widget("ui.selectable", $.ui.mouse, {
11927  version: "1.11.4",
11928  options: {
11929    appendTo: "body",
11930    autoRefresh: true,
11931    distance: 0,
11932    filter: "*",
11933    tolerance: "touch",
11934
11935    // callbacks
11936    selected: null,
11937    selecting: null,
11938    start: null,
11939    stop: null,
11940    unselected: null,
11941    unselecting: null
11942  },
11943  _create: function() {
11944    var selectees,
11945      that = this;
11946
11947    this.element.addClass("ui-selectable");
11948
11949    this.dragged = false;
11950
11951    // cache selectee children based on filter
11952    this.refresh = function() {
11953      selectees = $(that.options.filter, that.element[0]);
11954      selectees.addClass("ui-selectee");
11955      selectees.each(function() {
11956        var $this = $(this),
11957          pos = $this.offset();
11958        $.data(this, "selectable-item", {
11959          element: this,
11960          $element: $this,
11961          left: pos.left,
11962          top: pos.top,
11963          right: pos.left + $this.outerWidth(),
11964          bottom: pos.top + $this.outerHeight(),
11965          startselected: false,
11966          selected: $this.hasClass("ui-selected"),
11967          selecting: $this.hasClass("ui-selecting"),
11968          unselecting: $this.hasClass("ui-unselecting")
11969        });
11970      });
11971    };
11972    this.refresh();
11973
11974    this.selectees = selectees.addClass("ui-selectee");
11975
11976    this._mouseInit();
11977
11978    this.helper = $("<div class='ui-selectable-helper'></div>");
11979  },
11980
11981  _destroy: function() {
11982    this.selectees
11983      .removeClass("ui-selectee")
11984      .removeData("selectable-item");
11985    this.element
11986      .removeClass("ui-selectable ui-selectable-disabled");
11987    this._mouseDestroy();
11988  },
11989
11990  _mouseStart: function(event) {
11991    var that = this,
11992      options = this.options;
11993
11994    this.opos = [ event.pageX, event.pageY ];
11995
11996    if (this.options.disabled) {
11997      return;
11998    }
11999
12000    this.selectees = $(options.filter, this.element[0]);
12001
12002    this._trigger("start", event);
12003
12004    $(options.appendTo).append(this.helper);
12005    // position helper (lasso)
12006    this.helper.css({
12007      "left": event.pageX,
12008      "top": event.pageY,
12009      "width": 0,
12010      "height": 0
12011    });
12012
12013    if (options.autoRefresh) {
12014      this.refresh();
12015    }
12016
12017    this.selectees.filter(".ui-selected").each(function() {
12018      var selectee = $.data(this, "selectable-item");
12019      selectee.startselected = true;
12020      if (!event.metaKey && !event.ctrlKey) {
12021        selectee.$element.removeClass("ui-selected");
12022        selectee.selected = false;
12023        selectee.$element.addClass("ui-unselecting");
12024        selectee.unselecting = true;
12025        // selectable UNSELECTING callback
12026        that._trigger("unselecting", event, {
12027          unselecting: selectee.element
12028        });
12029      }
12030    });
12031
12032    $(event.target).parents().addBack().each(function() {
12033      var doSelect,
12034        selectee = $.data(this, "selectable-item");
12035      if (selectee) {
12036        doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
12037        selectee.$element
12038          .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12039          .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12040        selectee.unselecting = !doSelect;
12041        selectee.selecting = doSelect;
12042        selectee.selected = doSelect;
12043        // selectable (UN)SELECTING callback
12044        if (doSelect) {
12045          that._trigger("selecting", event, {
12046            selecting: selectee.element
12047          });
12048        } else {
12049          that._trigger("unselecting", event, {
12050            unselecting: selectee.element
12051          });
12052        }
12053        return false;
12054      }
12055    });
12056
12057  },
12058
12059  _mouseDrag: function(event) {
12060
12061    this.dragged = true;
12062
12063    if (this.options.disabled) {
12064      return;
12065    }
12066
12067    var tmp,
12068      that = this,
12069      options = this.options,
12070      x1 = this.opos[0],
12071      y1 = this.opos[1],
12072      x2 = event.pageX,
12073      y2 = event.pageY;
12074
12075    if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
12076    if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
12077    this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
12078
12079    this.selectees.each(function() {
12080      var selectee = $.data(this, "selectable-item"),
12081        hit = false;
12082
12083      //prevent helper from being selected if appendTo: selectable
12084      if (!selectee || selectee.element === that.element[0]) {
12085        return;
12086      }
12087
12088      if (options.tolerance === "touch") {
12089        hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12090      } else if (options.tolerance === "fit") {
12091        hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12092      }
12093
12094      if (hit) {
12095        // SELECT
12096        if (selectee.selected) {
12097          selectee.$element.removeClass("ui-selected");
12098          selectee.selected = false;
12099        }
12100        if (selectee.unselecting) {
12101          selectee.$element.removeClass("ui-unselecting");
12102          selectee.unselecting = false;
12103        }
12104        if (!selectee.selecting) {
12105          selectee.$element.addClass("ui-selecting");
12106          selectee.selecting = true;
12107          // selectable SELECTING callback
12108          that._trigger("selecting", event, {
12109            selecting: selectee.element
12110          });
12111        }
12112      } else {
12113        // UNSELECT
12114        if (selectee.selecting) {
12115          if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
12116            selectee.$element.removeClass("ui-selecting");
12117            selectee.selecting = false;
12118            selectee.$element.addClass("ui-selected");
12119            selectee.selected = true;
12120          } else {
12121            selectee.$element.removeClass("ui-selecting");
12122            selectee.selecting = false;
12123            if (selectee.startselected) {
12124              selectee.$element.addClass("ui-unselecting");
12125              selectee.unselecting = true;
12126            }
12127            // selectable UNSELECTING callback
12128            that._trigger("unselecting", event, {
12129              unselecting: selectee.element
12130            });
12131          }
12132        }
12133        if (selectee.selected) {
12134          if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12135            selectee.$element.removeClass("ui-selected");
12136            selectee.selected = false;
12137
12138            selectee.$element.addClass("ui-unselecting");
12139            selectee.unselecting = true;
12140            // selectable UNSELECTING callback
12141            that._trigger("unselecting", event, {
12142              unselecting: selectee.element
12143            });
12144          }
12145        }
12146      }
12147    });
vendor: 10,876 bytes, lines 12148-12577
12148
12149    return false;
12150  },
12151
12152  _mouseStop: function(event) {
12153    var that = this;
12154
12155    this.dragged = false;
12156
12157    $(".ui-unselecting", this.element[0]).each(function() {
12158      var selectee = $.data(this, "selectable-item");
12159      selectee.$element.removeClass("ui-unselecting");
12160      selectee.unselecting = false;
12161      selectee.startselected = false;
12162      that._trigger("unselected", event, {
12163        unselected: selectee.element
12164      });
12165    });
12166    $(".ui-selecting", this.element[0]).each(function() {
12167      var selectee = $.data(this, "selectable-item");
12168      selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12169      selectee.selecting = false;
12170      selectee.selected = true;
12171      selectee.startselected = true;
12172      that._trigger("selected", event, {
12173        selected: selectee.element
12174      });
12175    });
12176    this._trigger("stop", event);
12177
12178    this.helper.remove();
12179
12180    return false;
12181  }
12182
12183});
12184
12185
12186/*!
12187 * jQuery UI Selectmenu 1.11.4
12188 * http://jqueryui.com
12189 *
12190 * Copyright jQuery Foundation and other contributors
12191 * Released under the MIT license.
12192 * http://jquery.org/license
12193 *
12194 * http://api.jqueryui.com/selectmenu
12195 */
12196
12197
12198var selectmenu = $.widget( "ui.selectmenu", {
12199  version: "1.11.4",
12200  defaultElement: "<select>",
12201  options: {
12202    appendTo: null,
12203    disabled: null,
12204    icons: {
12205      button: "ui-icon-triangle-1-s"
12206    },
12207    position: {
12208      my: "left top",
12209      at: "left bottom",
12210      collision: "none"
12211    },
12212    width: null,
12213
12214    // callbacks
12215    change: null,
12216    close: null,
12217    focus: null,
12218    open: null,
12219    select: null
12220  },
12221
12222  _create: function() {
12223    var selectmenuId = this.element.uniqueId().attr( "id" );
12224    this.ids = {
12225      element: selectmenuId,
12226      button: selectmenuId + "-button",
12227      menu: selectmenuId + "-menu"
12228    };
12229
12230    this._drawButton();
12231    this._drawMenu();
12232
12233    if ( this.options.disabled ) {
12234      this.disable();
12235    }
12236  },
12237
12238  _drawButton: function() {
12239    var that = this;
12240
12241    // Associate existing label with the new button
12242    this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12243    this._on( this.label, {
12244      click: function( event ) {
12245        this.button.focus();
12246        event.preventDefault();
12247      }
12248    });
12249
12250    // Hide original select element
12251    this.element.hide();
12252
12253    // Create button
12254    this.button = $( "<span>", {
12255      "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12256      tabindex: this.options.disabled ? -1 : 0,
12257      id: this.ids.button,
12258      role: "combobox",
12259      "aria-expanded": "false",
12260      "aria-autocomplete": "list",
12261      "aria-owns": this.ids.menu,
12262      "aria-haspopup": "true"
12263    })
12264      .insertAfter( this.element );
12265
12266    $( "<span>", {
12267      "class": "ui-icon " + this.options.icons.button
12268    })
12269      .prependTo( this.button );
12270
12271    this.buttonText = $( "<span>", {
12272      "class": "ui-selectmenu-text"
12273    })
12274      .appendTo( this.button );
12275
12276    this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12277    this._resizeButton();
12278
12279    this._on( this.button, this._buttonEvents );
12280    this.button.one( "focusin", function() {
12281
12282      // Delay rendering the menu items until the button receives focus.
12283      // The menu may have already been rendered via a programmatic open.
12284      if ( !that.menuItems ) {
12285        that._refreshMenu();
12286      }
12287    });
12288    this._hoverable( this.button );
12289    this._focusable( this.button );
12290  },
12291
12292  _drawMenu: function() {
12293    var that = this;
12294
12295    // Create menu
12296    this.menu = $( "<ul>", {
12297      "aria-hidden": "true",
12298      "aria-labelledby": this.ids.button,
12299      id: this.ids.menu
12300    });
12301
12302    // Wrap menu
12303    this.menuWrap = $( "<div>", {
12304      "class": "ui-selectmenu-menu ui-front"
12305    })
12306      .append( this.menu )
12307      .appendTo( this._appendTo() );
12308
12309    // Initialize menu widget
12310    this.menuInstance = this.menu
12311      .menu({
12312        role: "listbox",
12313        select: function( event, ui ) {
12314          event.preventDefault();
12315
12316          // support: IE8
12317          // If the item was selected via a click, the text selection
12318          // will be destroyed in IE
12319          that._setSelection();
12320
12321          that._select( ui.item.data( "ui-selectmenu-item" ), event );
12322        },
12323        focus: function( event, ui ) {
12324          var item = ui.item.data( "ui-selectmenu-item" );
12325
12326          // Prevent inital focus from firing and check if its a newly focused item
12327          if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12328            that._trigger( "focus", event, { item: item } );
12329            if ( !that.isOpen ) {
12330              that._select( item, event );
12331            }
12332          }
12333          that.focusIndex = item.index;
12334
12335          that.button.attr( "aria-activedescendant",
12336            that.menuItems.eq( item.index ).attr( "id" ) );
12337        }
12338      })
12339      .menu( "instance" );
12340
12341    // Adjust menu styles to dropdown
12342    this.menu
12343      .addClass( "ui-corner-bottom" )
12344      .removeClass( "ui-corner-all" );
12345
12346    // Don't close the menu on mouseleave
12347    this.menuInstance._off( this.menu, "mouseleave" );
12348
12349    // Cancel the menu's collapseAll on document click
12350    this.menuInstance._closeOnDocumentClick = function() {
12351      return false;
12352    };
12353
12354    // Selects often contain empty items, but never contain dividers
12355    this.menuInstance._isDivider = function() {
12356      return false;
12357    };
12358  },
12359
12360  refresh: function() {
12361    this._refreshMenu();
12362    this._setText( this.buttonText, this._getSelectedItem().text() );
12363    if ( !this.options.width ) {
12364      this._resizeButton();
12365    }
12366  },
12367
12368  _refreshMenu: function() {
12369    this.menu.empty();
12370
12371    var item,
12372      options = this.element.find( "option" );
12373
12374    if ( !options.length ) {
12375      return;
12376    }
12377
12378    this._parseOptions( options );
12379    this._renderMenu( this.menu, this.items );
12380
12381    this.menuInstance.refresh();
12382    this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12383
12384    item = this._getSelectedItem();
12385
12386    // Update the menu to have the correct item focused
12387    this.menuInstance.focus( null, item );
12388    this._setAria( item.data( "ui-selectmenu-item" ) );
12389
12390    // Set disabled state
12391    this._setOption( "disabled", this.element.prop( "disabled" ) );
12392  },
12393
12394  open: function( event ) {
12395    if ( this.options.disabled ) {
12396      return;
12397    }
12398
12399    // If this is the first time the menu is being opened, render the items
12400    if ( !this.menuItems ) {
12401      this._refreshMenu();
12402    } else {
12403
12404      // Menu clears focus on close, reset focus to selected item
12405      this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12406      this.menuInstance.focus( null, this._getSelectedItem() );
12407    }
12408
12409    this.isOpen = true;
12410    this._toggleAttr();
12411    this._resizeMenu();
12412    this._position();
12413
12414    this._on( this.document, this._documentClick );
12415
12416    this._trigger( "open", event );
12417  },
12418
12419  _position: function() {
12420    this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12421  },
12422
12423  close: function( event ) {
12424    if ( !this.isOpen ) {
12425      return;
12426    }
12427
12428    this.isOpen = false;
12429    this._toggleAttr();
12430
12431    this.range = null;
12432    this._off( this.document );
12433
12434    this._trigger( "close", event );
12435  },
12436
12437  widget: function() {
12438    return this.button;
12439  },
12440
12441  menuWidget: function() {
12442    return this.menu;
12443  },
12444
12445  _renderMenu: function( ul, items ) {
12446    var that = this,
12447      currentOptgroup = "";
12448
12449    $.each( items, function( index, item ) {
12450      if ( item.optgroup !== currentOptgroup ) {
12451        $( "<li>", {
12452          "class": "ui-selectmenu-optgroup ui-menu-divider" +
12453            ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12454              " ui-state-disabled" :
12455              "" ),
12456          text: item.optgroup
12457        })
12458          .appendTo( ul );
12459
12460        currentOptgroup = item.optgroup;
12461      }
12462
12463      that._renderItemData( ul, item );
12464    });
12465  },
12466
12467  _renderItemData: function( ul, item ) {
12468    return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12469  },
12470
12471  _renderItem: function( ul, item ) {
12472    var li = $( "<li>" );
12473
12474    if ( item.disabled ) {
12475      li.addClass( "ui-state-disabled" );
12476    }
12477    this._setText( li, item.label );
12478
12479    return li.appendTo( ul );
12480  },
12481
12482  _setText: function( element, value ) {
12483    if ( value ) {
12484      element.text( value );
12485    } else {
12486      element.html( "&#160;" );
12487    }
12488  },
12489
12490  _move: function( direction, event ) {
12491    var item, next,
12492      filter = ".ui-menu-item";
12493
12494    if ( this.isOpen ) {
12495      item = this.menuItems.eq( this.focusIndex );
12496    } else {
12497      item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12498      filter += ":not(.ui-state-disabled)";
12499    }
12500
12501    if ( direction === "first" || direction === "last" ) {
12502      next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12503    } else {
12504      next = item[ direction + "All" ]( filter ).eq( 0 );
12505    }
12506
12507    if ( next.length ) {
12508      this.menuInstance.focus( event, next );
12509    }
12510  },
12511
12512  _getSelectedItem: function() {
12513    return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12514  },
12515
12516  _toggle: function( event ) {
12517    this[ this.isOpen ? "close" : "open" ]( event );
12518  },
12519
12520  _setSelection: function() {
12521    var selection;
12522
12523    if ( !this.range ) {
12524      return;
12525    }
12526
12527    if ( window.getSelection ) {
12528      selection = window.getSelection();
12529      selection.removeAllRanges();
12530      selection.addRange( this.range );
12531
12532    // support: IE8
12533    } else {
12534      this.range.select();
12535    }
12536
12537    // support: IE
12538    // Setting the text selection kills the button focus in IE, but
12539    // restoring the focus doesn't kill the selection.
12540    this.button.focus();
12541  },
12542
12543  _documentClick: {
12544    mousedown: function( event ) {
12545      if ( !this.isOpen ) {
12546        return;
12547      }
12548
12549      if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12550        this.close( event );
12551      }
12552    }
12553  },
12554
12555  _buttonEvents: {
12556
12557    // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12558    mousedown: function() {
12559      var selection;
12560
12561      if ( window.getSelection ) {
12562        selection = window.getSelection();
12563        if ( selection.rangeCount ) {
12564          this.range = selection.getRangeAt( 0 );
12565        }
12566
12567      // support: IE8
12568      } else {
12569        this.range = document.selection.createRange();
12570      }
12571    },
12572
12573    click: function( event ) {
12574      this._setSelection();
12575      this._toggle( event );
12576    },
12577
vendor: 14,322 bytes, lines 12578-13094
12578    keydown: function( event ) {
12579      var preventDefault = true;
12580      switch ( event.keyCode ) {
12581        case $.ui.keyCode.TAB:
12582        case $.ui.keyCode.ESCAPE:
12583          this.close( event );
12584          preventDefault = false;
12585          break;
12586        case $.ui.keyCode.ENTER:
12587          if ( this.isOpen ) {
12588            this._selectFocusedItem( event );
12589          }
12590          break;
12591        case $.ui.keyCode.UP:
12592          if ( event.altKey ) {
12593            this._toggle( event );
12594          } else {
12595            this._move( "prev", event );
12596          }
12597          break;
12598        case $.ui.keyCode.DOWN:
12599          if ( event.altKey ) {
12600            this._toggle( event );
12601          } else {
12602            this._move( "next", event );
12603          }
12604          break;
12605        case $.ui.keyCode.SPACE:
12606          if ( this.isOpen ) {
12607            this._selectFocusedItem( event );
12608          } else {
12609            this._toggle( event );
12610          }
12611          break;
12612        case $.ui.keyCode.LEFT:
12613          this._move( "prev", event );
12614          break;
12615        case $.ui.keyCode.RIGHT:
12616          this._move( "next", event );
12617          break;
12618        case $.ui.keyCode.HOME:
12619        case $.ui.keyCode.PAGE_UP:
12620          this._move( "first", event );
12621          break;
12622        case $.ui.keyCode.END:
12623        case $.ui.keyCode.PAGE_DOWN:
12624          this._move( "last", event );
12625          break;
12626        default:
12627          this.menu.trigger( event );
12628          preventDefault = false;
12629      }
12630
12631      if ( preventDefault ) {
12632        event.preventDefault();
12633      }
12634    }
12635  },
12636
12637  _selectFocusedItem: function( event ) {
12638    var item = this.menuItems.eq( this.focusIndex );
12639    if ( !item.hasClass( "ui-state-disabled" ) ) {
12640      this._select( item.data( "ui-selectmenu-item" ), event );
12641    }
12642  },
12643
12644  _select: function( item, event ) {
12645    var oldIndex = this.element[ 0 ].selectedIndex;
12646
12647    // Change native select element
12648    this.element[ 0 ].selectedIndex = item.index;
12649    this._setText( this.buttonText, item.label );
12650    this._setAria( item );
12651    this._trigger( "select", event, { item: item } );
12652
12653    if ( item.index !== oldIndex ) {
12654      this._trigger( "change", event, { item: item } );
12655    }
12656
12657    this.close( event );
12658  },
12659
12660  _setAria: function( item ) {
12661    var id = this.menuItems.eq( item.index ).attr( "id" );
12662
12663    this.button.attr({
12664      "aria-labelledby": id,
12665      "aria-activedescendant": id
12666    });
12667    this.menu.attr( "aria-activedescendant", id );
12668  },
12669
12670  _setOption: function( key, value ) {
12671    if ( key === "icons" ) {
12672      this.button.find( "span.ui-icon" )
12673        .removeClass( this.options.icons.button )
12674        .addClass( value.button );
12675    }
12676
12677    this._super( key, value );
12678
12679    if ( key === "appendTo" ) {
12680      this.menuWrap.appendTo( this._appendTo() );
12681    }
12682
12683    if ( key === "disabled" ) {
12684      this.menuInstance.option( "disabled", value );
12685      this.button
12686        .toggleClass( "ui-state-disabled", value )
12687        .attr( "aria-disabled", value );
12688
12689      this.element.prop( "disabled", value );
12690      if ( value ) {
12691        this.button.attr( "tabindex", -1 );
12692        this.close();
12693      } else {
12694        this.button.attr( "tabindex", 0 );
12695      }
12696    }
12697
12698    if ( key === "width" ) {
12699      this._resizeButton();
12700    }
12701  },
12702
12703  _appendTo: function() {
12704    var element = this.options.appendTo;
12705
12706    if ( element ) {
12707      element = element.jquery || element.nodeType ?
12708        $( element ) :
12709        this.document.find( element ).eq( 0 );
12710    }
12711
12712    if ( !element || !element[ 0 ] ) {
12713      element = this.element.closest( ".ui-front" );
12714    }
12715
12716    if ( !element.length ) {
12717      element = this.document[ 0 ].body;
12718    }
12719
12720    return element;
12721  },
12722
12723  _toggleAttr: function() {
12724    this.button
12725      .toggleClass( "ui-corner-top", this.isOpen )
12726      .toggleClass( "ui-corner-all", !this.isOpen )
12727      .attr( "aria-expanded", this.isOpen );
12728    this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12729    this.menu.attr( "aria-hidden", !this.isOpen );
12730  },
12731
12732  _resizeButton: function() {
12733    var width = this.options.width;
12734
12735    if ( !width ) {
12736      width = this.element.show().outerWidth();
12737      this.element.hide();
12738    }
12739
12740    this.button.outerWidth( width );
12741  },
12742
12743  _resizeMenu: function() {
12744    this.menu.outerWidth( Math.max(
12745      this.button.outerWidth(),
12746
12747      // support: IE10
12748      // IE10 wraps long text (possibly a rounding bug)
12749      // so we add 1px to avoid the wrapping
12750      this.menu.width( "" ).outerWidth() + 1
12751    ) );
12752  },
12753
12754  _getCreateOptions: function() {
12755    return { disabled: this.element.prop( "disabled" ) };
12756  },
12757
12758  _parseOptions: function( options ) {
12759    var data = [];
12760    options.each(function( index, item ) {
12761      var option = $( item ),
12762        optgroup = option.parent( "optgroup" );
12763      data.push({
12764        element: option,
12765        index: index,
12766        value: option.val(),
12767        label: option.text(),
12768        optgroup: optgroup.attr( "label" ) || "",
12769        disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12770      });
12771    });
12772    this.items = data;
12773  },
12774
12775  _destroy: function() {
12776    this.menuWrap.remove();
12777    this.button.remove();
12778    this.element.show();
12779    this.element.removeUniqueId();
12780    this.label.attr( "for", this.ids.element );
12781  }
12782});
12783
12784
12785/*!
12786 * jQuery UI Slider 1.11.4
12787 * http://jqueryui.com
12788 *
12789 * Copyright jQuery Foundation and other contributors
12790 * Released under the MIT license.
12791 * http://jquery.org/license
12792 *
12793 * http://api.jqueryui.com/slider/
12794 */
12795
12796
12797var slider = $.widget( "ui.slider", $.ui.mouse, {
12798  version: "1.11.4",
12799  widgetEventPrefix: "slide",
12800
12801  options: {
12802    animate: false,
12803    distance: 0,
12804    max: 100,
12805    min: 0,
12806    orientation: "horizontal",
12807    range: false,
12808    step: 1,
12809    value: 0,
12810    values: null,
12811
12812    // callbacks
12813    change: null,
12814    slide: null,
12815    start: null,
12816    stop: null
12817  },
12818
12819  // number of pages in a slider
12820  // (how many times can you page up/down to go through the whole range)
12821  numPages: 5,
12822
12823  _create: function() {
12824    this._keySliding = false;
12825    this._mouseSliding = false;
12826    this._animateOff = true;
12827    this._handleIndex = null;
12828    this._detectOrientation();
12829    this._mouseInit();
12830    this._calculateNewMax();
12831
12832    this.element
12833      .addClass( "ui-slider" +
12834        " ui-slider-" + this.orientation +
12835        " ui-widget" +
12836        " ui-widget-content" +
12837        " ui-corner-all");
12838
12839    this._refresh();
12840    this._setOption( "disabled", this.options.disabled );
12841
12842    this._animateOff = false;
12843  },
12844
12845  _refresh: function() {
12846    this._createRange();
12847    this._createHandles();
12848    this._setupEvents();
12849    this._refreshValue();
12850  },
12851
12852  _createHandles: function() {
12853    var i, handleCount,
12854      options = this.options,
12855      existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12856      handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12857      handles = [];
12858
12859    handleCount = ( options.values && options.values.length ) || 1;
12860
12861    if ( existingHandles.length > handleCount ) {
12862      existingHandles.slice( handleCount ).remove();
12863      existingHandles = existingHandles.slice( 0, handleCount );
12864    }
12865
12866    for ( i = existingHandles.length; i < handleCount; i++ ) {
12867      handles.push( handle );
12868    }
12869
12870    this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12871
12872    this.handle = this.handles.eq( 0 );
12873
12874    this.handles.each(function( i ) {
12875      $( this ).data( "ui-slider-handle-index", i );
12876    });
12877  },
12878
12879  _createRange: function() {
12880    var options = this.options,
12881      classes = "";
12882
12883    if ( options.range ) {
12884      if ( options.range === true ) {
12885        if ( !options.values ) {
12886          options.values = [ this._valueMin(), this._valueMin() ];
12887        } else if ( options.values.length && options.values.length !== 2 ) {
12888          options.values = [ options.values[0], options.values[0] ];
12889        } else if ( $.isArray( options.values ) ) {
12890          options.values = options.values.slice(0);
12891        }
12892      }
12893
12894      if ( !this.range || !this.range.length ) {
12895        this.range = $( "<div></div>" )
12896          .appendTo( this.element );
12897
12898        classes = "ui-slider-range" +
12899        // note: this isn't the most fittingly semantic framework class for this element,
12900        // but worked best visually with a variety of themes
12901        " ui-widget-header ui-corner-all";
12902      } else {
12903        this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12904          // Handle range switching from true to min/max
12905          .css({
12906            "left": "",
12907            "bottom": ""
12908          });
12909      }
12910
12911      this.range.addClass( classes +
12912        ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12913    } else {
12914      if ( this.range ) {
12915        this.range.remove();
12916      }
12917      this.range = null;
12918    }
12919  },
12920
12921  _setupEvents: function() {
12922    this._off( this.handles );
12923    this._on( this.handles, this._handleEvents );
12924    this._hoverable( this.handles );
12925    this._focusable( this.handles );
12926  },
12927
12928  _destroy: function() {
12929    this.handles.remove();
12930    if ( this.range ) {
12931      this.range.remove();
12932    }
12933
12934    this.element
12935      .removeClass( "ui-slider" +
12936        " ui-slider-horizontal" +
12937        " ui-slider-vertical" +
12938        " ui-widget" +
12939        " ui-widget-content" +
12940        " ui-corner-all" );
12941
12942    this._mouseDestroy();
12943  },
12944
12945  _mouseCapture: function( event ) {
12946    var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12947      that = this,
12948      o = this.options;
12949
12950    if ( o.disabled ) {
12951      return false;
12952    }
12953
12954    this.elementSize = {
12955      width: this.element.outerWidth(),
12956      height: this.element.outerHeight()
12957    };
12958    this.elementOffset = this.element.offset();
12959
12960    position = { x: event.pageX, y: event.pageY };
12961    normValue = this._normValueFromMouse( position );
12962    distance = this._valueMax() - this._valueMin() + 1;
12963    this.handles.each(function( i ) {
12964      var thisDistance = Math.abs( normValue - that.values(i) );
12965      if (( distance > thisDistance ) ||
12966        ( distance === thisDistance &&
12967          (i === that._lastChangedValue || that.values(i) === o.min ))) {
12968        distance = thisDistance;
12969        closestHandle = $( this );
12970        index = i;
12971      }
12972    });
12973
12974    allowed = this._start( event, index );
12975    if ( allowed === false ) {
12976      return false;
12977    }
12978    this._mouseSliding = true;
12979
12980    this._handleIndex = index;
12981
12982    closestHandle
12983      .addClass( "ui-state-active" )
12984      .focus();
12985
12986    offset = closestHandle.offset();
12987    mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12988    this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12989      left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12990      top: event.pageY - offset.top -
12991        ( closestHandle.height() / 2 ) -
12992        ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12993        ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12994        ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12995    };
12996
12997    if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12998      this._slide( event, index, normValue );
12999    }
13000    this._animateOff = true;
13001    return true;
13002  },
13003
13004  _mouseStart: function() {
13005    return true;
13006  },
13007
13008  _mouseDrag: function( event ) {
13009    var position = { x: event.pageX, y: event.pageY },
13010      normValue = this._normValueFromMouse( position );
13011
13012    this._slide( event, this._handleIndex, normValue );
13013
13014    return false;
13015  },
13016
13017  _mouseStop: function( event ) {
13018    this.handles.removeClass( "ui-state-active" );
13019    this._mouseSliding = false;
13020
13021    this._stop( event, this._handleIndex );
13022    this._change( event, this._handleIndex );
13023
13024    this._handleIndex = null;
13025    this._clickOffset = null;
13026    this._animateOff = false;
13027
13028    return false;
13029  },
13030
13031  _detectOrientation: function() {
13032    this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
13033  },
13034
13035  _normValueFromMouse: function( position ) {
13036    var pixelTotal,
13037      pixelMouse,
13038      percentMouse,
13039      valueTotal,
13040      valueMouse;
13041
13042    if ( this.orientation === "horizontal" ) {
13043      pixelTotal = this.elementSize.width;
13044      pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
13045    } else {
13046      pixelTotal = this.elementSize.height;
13047      pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
13048    }
13049
13050    percentMouse = ( pixelMouse / pixelTotal );
13051    if ( percentMouse > 1 ) {
13052      percentMouse = 1;
13053    }
13054    if ( percentMouse < 0 ) {
13055      percentMouse = 0;
13056    }
13057    if ( this.orientation === "vertical" ) {
13058      percentMouse = 1 - percentMouse;
13059    }
13060
13061    valueTotal = this._valueMax() - this._valueMin();
13062    valueMouse = this._valueMin() + percentMouse * valueTotal;
13063
13064    return this._trimAlignValue( valueMouse );
13065  },
13066
13067  _start: function( event, index ) {
13068    var uiHash = {
13069      handle: this.handles[ index ],
13070      value: this.value()
13071    };
13072    if ( this.options.values && this.options.values.length ) {
13073      uiHash.value = this.values( index );
13074      uiHash.values = this.values();
13075    }
13076    return this._trigger( "start", event, uiHash );
13077  },
13078
13079  _slide: function( event, index, newVal ) {
13080    var otherVal,
13081      newValues,
13082      allowed;
13083
13084    if ( this.options.values && this.options.values.length ) {
13085      otherVal = this.values( index ? 0 : 1 );
13086
13087      if ( ( this.options.values.length === 2 && this.options.range === true ) &&
13088          ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
13089        ) {
13090        newVal = otherVal;
13091      }
13092
13093      if ( newVal !== this.values( index ) ) {
13094        newValues = this.values();
vendor: 14,082 bytes, lines 13095-13555
13095        newValues[ index ] = newVal;
13096        // A slide can be canceled by returning false from the slide callback
13097        allowed = this._trigger( "slide", event, {
13098          handle: this.handles[ index ],
13099          value: newVal,
13100          values: newValues
13101        } );
13102        otherVal = this.values( index ? 0 : 1 );
13103        if ( allowed !== false ) {
13104          this.values( index, newVal );
13105        }
13106      }
13107    } else {
13108      if ( newVal !== this.value() ) {
13109        // A slide can be canceled by returning false from the slide callback
13110        allowed = this._trigger( "slide", event, {
13111          handle: this.handles[ index ],
13112          value: newVal
13113        } );
13114        if ( allowed !== false ) {
13115          this.value( newVal );
13116        }
13117      }
13118    }
13119  },
13120
13121  _stop: function( event, index ) {
13122    var uiHash = {
13123      handle: this.handles[ index ],
13124      value: this.value()
13125    };
13126    if ( this.options.values && this.options.values.length ) {
13127      uiHash.value = this.values( index );
13128      uiHash.values = this.values();
13129    }
13130
13131    this._trigger( "stop", event, uiHash );
13132  },
13133
13134  _change: function( event, index ) {
13135    if ( !this._keySliding && !this._mouseSliding ) {
13136      var uiHash = {
13137        handle: this.handles[ index ],
13138        value: this.value()
13139      };
13140      if ( this.options.values && this.options.values.length ) {
13141        uiHash.value = this.values( index );
13142        uiHash.values = this.values();
13143      }
13144
13145      //store the last changed value index for reference when handles overlap
13146      this._lastChangedValue = index;
13147
13148      this._trigger( "change", event, uiHash );
13149    }
13150  },
13151
13152  value: function( newValue ) {
13153    if ( arguments.length ) {
13154      this.options.value = this._trimAlignValue( newValue );
13155      this._refreshValue();
13156      this._change( null, 0 );
13157      return;
13158    }
13159
13160    return this._value();
13161  },
13162
13163  values: function( index, newValue ) {
13164    var vals,
13165      newValues,
13166      i;
13167
13168    if ( arguments.length > 1 ) {
13169      this.options.values[ index ] = this._trimAlignValue( newValue );
13170      this._refreshValue();
13171      this._change( null, index );
13172      return;
13173    }
13174
13175    if ( arguments.length ) {
13176      if ( $.isArray( arguments[ 0 ] ) ) {
13177        vals = this.options.values;
13178        newValues = arguments[ 0 ];
13179        for ( i = 0; i < vals.length; i += 1 ) {
13180          vals[ i ] = this._trimAlignValue( newValues[ i ] );
13181          this._change( null, i );
13182        }
13183        this._refreshValue();
13184      } else {
13185        if ( this.options.values && this.options.values.length ) {
13186          return this._values( index );
13187        } else {
13188          return this.value();
13189        }
13190      }
13191    } else {
13192      return this._values();
13193    }
13194  },
13195
13196  _setOption: function( key, value ) {
13197    var i,
13198      valsLength = 0;
13199
13200    if ( key === "range" && this.options.range === true ) {
13201      if ( value === "min" ) {
13202        this.options.value = this._values( 0 );
13203        this.options.values = null;
13204      } else if ( value === "max" ) {
13205        this.options.value = this._values( this.options.values.length - 1 );
13206        this.options.values = null;
13207      }
13208    }
13209
13210    if ( $.isArray( this.options.values ) ) {
13211      valsLength = this.options.values.length;
13212    }
13213
13214    if ( key === "disabled" ) {
13215      this.element.toggleClass( "ui-state-disabled", !!value );
13216    }
13217
13218    this._super( key, value );
13219
13220    switch ( key ) {
13221      case "orientation":
13222        this._detectOrientation();
13223        this.element
13224          .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13225          .addClass( "ui-slider-" + this.orientation );
13226        this._refreshValue();
13227
13228        // Reset positioning from previous orientation
13229        this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13230        break;
13231      case "value":
13232        this._animateOff = true;
13233        this._refreshValue();
13234        this._change( null, 0 );
13235        this._animateOff = false;
13236        break;
13237      case "values":
13238        this._animateOff = true;
13239        this._refreshValue();
13240        for ( i = 0; i < valsLength; i += 1 ) {
13241          this._change( null, i );
13242        }
13243        this._animateOff = false;
13244        break;
13245      case "step":
13246      case "min":
13247      case "max":
13248        this._animateOff = true;
13249        this._calculateNewMax();
13250        this._refreshValue();
13251        this._animateOff = false;
13252        break;
13253      case "range":
13254        this._animateOff = true;
13255        this._refresh();
13256        this._animateOff = false;
13257        break;
13258    }
13259  },
13260
13261  //internal value getter
13262  // _value() returns value trimmed by min and max, aligned by step
13263  _value: function() {
13264    var val = this.options.value;
13265    val = this._trimAlignValue( val );
13266
13267    return val;
13268  },
13269
13270  //internal values getter
13271  // _values() returns array of values trimmed by min and max, aligned by step
13272  // _values( index ) returns single value trimmed by min and max, aligned by step
13273  _values: function( index ) {
13274    var val,
13275      vals,
13276      i;
13277
13278    if ( arguments.length ) {
13279      val = this.options.values[ index ];
13280      val = this._trimAlignValue( val );
13281
13282      return val;
13283    } else if ( this.options.values && this.options.values.length ) {
13284      // .slice() creates a copy of the array
13285      // this copy gets trimmed by min and max and then returned
13286      vals = this.options.values.slice();
13287      for ( i = 0; i < vals.length; i += 1) {
13288        vals[ i ] = this._trimAlignValue( vals[ i ] );
13289      }
13290
13291      return vals;
13292    } else {
13293      return [];
13294    }
13295  },
13296
13297  // returns the step-aligned value that val is closest to, between (inclusive) min and max
13298  _trimAlignValue: function( val ) {
13299    if ( val <= this._valueMin() ) {
13300      return this._valueMin();
13301    }
13302    if ( val >= this._valueMax() ) {
13303      return this._valueMax();
13304    }
13305    var step = ( this.options.step > 0 ) ? this.options.step : 1,
13306      valModStep = (val - this._valueMin()) % step,
13307      alignValue = val - valModStep;
13308
13309    if ( Math.abs(valModStep) * 2 >= step ) {
13310      alignValue += ( valModStep > 0 ) ? step : ( -step );
13311    }
13312
13313    // Since JavaScript has problems with large floats, round
13314    // the final value to 5 digits after the decimal point (see #4124)
13315    return parseFloat( alignValue.toFixed(5) );
13316  },
13317
13318  _calculateNewMax: function() {
13319    var max = this.options.max,
13320      min = this._valueMin(),
13321      step = this.options.step,
13322      aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
13323    max = aboveMin + min;
13324    this.max = parseFloat( max.toFixed( this._precision() ) );
13325  },
13326
13327  _precision: function() {
13328    var precision = this._precisionOf( this.options.step );
13329    if ( this.options.min !== null ) {
13330      precision = Math.max( precision, this._precisionOf( this.options.min ) );
13331    }
13332    return precision;
13333  },
13334
13335  _precisionOf: function( num ) {
13336    var str = num.toString(),
13337      decimal = str.indexOf( "." );
13338    return decimal === -1 ? 0 : str.length - decimal - 1;
13339  },
13340
13341  _valueMin: function() {
13342    return this.options.min;
13343  },
13344
13345  _valueMax: function() {
13346    return this.max;
13347  },
13348
13349  _refreshValue: function() {
13350    var lastValPercent, valPercent, value, valueMin, valueMax,
13351      oRange = this.options.range,
13352      o = this.options,
13353      that = this,
13354      animate = ( !this._animateOff ) ? o.animate : false,
13355      _set = {};
13356
13357    if ( this.options.values && this.options.values.length ) {
13358      this.handles.each(function( i ) {
13359        valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13360        _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13361        $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13362        if ( that.options.range === true ) {
13363          if ( that.orientation === "horizontal" ) {
13364            if ( i === 0 ) {
13365              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13366            }
13367            if ( i === 1 ) {
13368              that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13369            }
13370          } else {
13371            if ( i === 0 ) {
13372              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13373            }
13374            if ( i === 1 ) {
13375              that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13376            }
13377          }
13378        }
13379        lastValPercent = valPercent;
13380      });
13381    } else {
13382      value = this.value();
13383      valueMin = this._valueMin();
13384      valueMax = this._valueMax();
13385      valPercent = ( valueMax !== valueMin ) ?
13386          ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13387          0;
13388      _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13389      this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13390
13391      if ( oRange === "min" && this.orientation === "horizontal" ) {
13392        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13393      }
13394      if ( oRange === "max" && this.orientation === "horizontal" ) {
13395        this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13396      }
13397      if ( oRange === "min" && this.orientation === "vertical" ) {
13398        this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13399      }
13400      if ( oRange === "max" && this.orientation === "vertical" ) {
13401        this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13402      }
13403    }
13404  },
13405
13406  _handleEvents: {
13407    keydown: function( event ) {
13408      var allowed, curVal, newVal, step,
13409        index = $( event.target ).data( "ui-slider-handle-index" );
13410
13411      switch ( event.keyCode ) {
13412        case $.ui.keyCode.HOME:
13413        case $.ui.keyCode.END:
13414        case $.ui.keyCode.PAGE_UP:
13415        case $.ui.keyCode.PAGE_DOWN:
13416        case $.ui.keyCode.UP:
13417        case $.ui.keyCode.RIGHT:
13418        case $.ui.keyCode.DOWN:
13419        case $.ui.keyCode.LEFT:
13420          event.preventDefault();
13421          if ( !this._keySliding ) {
13422            this._keySliding = true;
13423            $( event.target ).addClass( "ui-state-active" );
13424            allowed = this._start( event, index );
13425            if ( allowed === false ) {
13426              return;
13427            }
13428          }
13429          break;
13430      }
13431
13432      step = this.options.step;
13433      if ( this.options.values && this.options.values.length ) {
13434        curVal = newVal = this.values( index );
13435      } else {
13436        curVal = newVal = this.value();
13437      }
13438
13439      switch ( event.keyCode ) {
13440        case $.ui.keyCode.HOME:
13441          newVal = this._valueMin();
13442          break;
13443        case $.ui.keyCode.END:
13444          newVal = this._valueMax();
13445          break;
13446        case $.ui.keyCode.PAGE_UP:
13447          newVal = this._trimAlignValue(
13448            curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13449          );
13450          break;
13451        case $.ui.keyCode.PAGE_DOWN:
13452          newVal = this._trimAlignValue(
13453            curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13454          break;
13455        case $.ui.keyCode.UP:
13456        case $.ui.keyCode.RIGHT:
13457          if ( curVal === this._valueMax() ) {
13458            return;
13459          }
13460          newVal = this._trimAlignValue( curVal + step );
13461          break;
13462        case $.ui.keyCode.DOWN:
13463        case $.ui.keyCode.LEFT:
13464          if ( curVal === this._valueMin() ) {
13465            return;
13466          }
13467          newVal = this._trimAlignValue( curVal - step );
13468          break;
13469      }
13470
13471      this._slide( event, index, newVal );
13472    },
13473    keyup: function( event ) {
13474      var index = $( event.target ).data( "ui-slider-handle-index" );
13475
13476      if ( this._keySliding ) {
13477        this._keySliding = false;
13478        this._stop( event, index );
13479        this._change( event, index );
13480        $( event.target ).removeClass( "ui-state-active" );
13481      }
13482    }
13483  }
13484});
13485
13486
13487/*!
13488 * jQuery UI Sortable 1.11.4
13489 * http://jqueryui.com
13490 *
13491 * Copyright jQuery Foundation and other contributors
13492 * Released under the MIT license.
13493 * http://jquery.org/license
13494 *
13495 * http://api.jqueryui.com/sortable/
13496 */
13497
13498
13499var sortable = $.widget("ui.sortable", $.ui.mouse, {
13500  version: "1.11.4",
13501  widgetEventPrefix: "sort",
13502  ready: false,
13503  options: {
13504    appendTo: "parent",
13505    axis: false,
13506    connectWith: false,
13507    containment: false,
13508    cursor: "auto",
13509    cursorAt: false,
13510    dropOnEmpty: true,
13511    forcePlaceholderSize: false,
13512    forceHelperSize: false,
13513    grid: false,
13514    handle: false,
13515    helper: "original",
13516    items: "> *",
13517    opacity: false,
13518    placeholder: false,
13519    revert: false,
13520    scroll: true,
13521    scrollSensitivity: 20,
13522    scrollSpeed: 20,
13523    scope: "default",
13524    tolerance: "intersect",
13525    zIndex: 1000,
13526
13527    // callbacks
13528    activate: null,
13529    beforeStop: null,
13530    change: null,
13531    deactivate: null,
13532    out: null,
13533    over: null,
13534    receive: null,
13535    remove: null,
13536    sort: null,
13537    start: null,
13538    stop: null,
13539    update: null
13540  },
13541
13542  _isOverAxis: function( x, reference, size ) {
13543    return ( x >= reference ) && ( x < ( reference + size ) );
13544  },
13545
13546  _isFloating: function( item ) {
13547    return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13548  },
13549
13550  _create: function() {
13551    this.containerCache = {};
13552    this.element.addClass("ui-sortable");
13553
13554    //Get the items
13555    this.refresh();
vendor: 4,318 bytes, lines 13556-13702
13556
13557    //Let's determine the parent's offset
13558    this.offset = this.element.offset();
13559
13560    //Initialize mouse events for interaction
13561    this._mouseInit();
13562
13563    this._setHandleClassName();
13564
13565    //We're ready to go
13566    this.ready = true;
13567
13568  },
13569
13570  _setOption: function( key, value ) {
13571    this._super( key, value );
13572
13573    if ( key === "handle" ) {
13574      this._setHandleClassName();
13575    }
13576  },
13577
13578  _setHandleClassName: function() {
13579    this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13580    $.each( this.items, function() {
13581      ( this.instance.options.handle ?
13582        this.item.find( this.instance.options.handle ) : this.item )
13583        .addClass( "ui-sortable-handle" );
13584    });
13585  },
13586
13587  _destroy: function() {
13588    this.element
13589      .removeClass( "ui-sortable ui-sortable-disabled" )
13590      .find( ".ui-sortable-handle" )
13591        .removeClass( "ui-sortable-handle" );
13592    this._mouseDestroy();
13593
13594    for ( var i = this.items.length - 1; i >= 0; i-- ) {
13595      this.items[i].item.removeData(this.widgetName + "-item");
13596    }
13597
13598    return this;
13599  },
13600
13601  _mouseCapture: function(event, overrideHandle) {
13602    var currentItem = null,
13603      validHandle = false,
13604      that = this;
13605
13606    if (this.reverting) {
13607      return false;
13608    }
13609
13610    if(this.options.disabled || this.options.type === "static") {
13611      return false;
13612    }
13613
13614    //We have to refresh the items data once first
13615    this._refreshItems(event);
13616
13617    //Find out if the clicked node (or one of its parents) is a actual item in this.items
13618    $(event.target).parents().each(function() {
13619      if($.data(this, that.widgetName + "-item") === that) {
13620        currentItem = $(this);
13621        return false;
13622      }
13623    });
13624    if($.data(event.target, that.widgetName + "-item") === that) {
13625      currentItem = $(event.target);
13626    }
13627
13628    if(!currentItem) {
13629      return false;
13630    }
13631    if(this.options.handle && !overrideHandle) {
13632      $(this.options.handle, currentItem).find("*").addBack().each(function() {
13633        if(this === event.target) {
13634          validHandle = true;
13635        }
13636      });
13637      if(!validHandle) {
13638        return false;
13639      }
13640    }
13641
13642    this.currentItem = currentItem;
13643    this._removeCurrentsFromItems();
13644    return true;
13645
13646  },
13647
13648  _mouseStart: function(event, overrideHandle, noActivation) {
13649
13650    var i, body,
13651      o = this.options;
13652
13653    this.currentContainer = this;
13654
13655    //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13656    this.refreshPositions();
13657
13658    //Create and append the visible helper
13659    this.helper = this._createHelper(event);
13660
13661    //Cache the helper size
13662    this._cacheHelperProportions();
13663
13664    /*
13665     * - Position generation -
13666     * This block generates everything position related - it's the core of draggables.
13667     */
13668
13669    //Cache the margins of the original element
13670    this._cacheMargins();
13671
13672    //Get the next scrolling parent
13673    this.scrollParent = this.helper.scrollParent();
13674
13675    //The element's absolute position on the page minus margins
13676    this.offset = this.currentItem.offset();
13677    this.offset = {
13678      top: this.offset.top - this.margins.top,
13679      left: this.offset.left - this.margins.left
13680    };
13681
13682    $.extend(this.offset, {
13683      click: { //Where the click happened, relative to the element
13684        left: event.pageX - this.offset.left,
13685        top: event.pageY - this.offset.top
13686      },
13687      parent: this._getParentOffset(),
13688      relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13689    });
13690
13691    // Only after we got the offset, we can change the helper's position to absolute
13692    // TODO: Still need to figure out a way to make relative sorting possible
13693    this.helper.css("position", "absolute");
13694    this.cssPosition = this.helper.css("position");
13695
13696    //Generate the original position
13697    this.originalPosition = this._generatePosition(event);
13698    this.originalPageX = event.pageX;
13699    this.originalPageY = event.pageY;
13700
13701    //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13702    (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
vendor: 36,980 bytes, lines 13703-14658
13703
13704    //Cache the former DOM position
13705    this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13706
13707    //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
13708    if(this.helper[0] !== this.currentItem[0]) {
13709      this.currentItem.hide();
13710    }
13711
13712    //Create the placeholder
13713    this._createPlaceholder();
13714
13715    //Set a containment if given in the options
13716    if(o.containment) {
13717      this._setContainment();
13718    }
13719
13720    if( o.cursor && o.cursor !== "auto" ) { // cursor option
13721      body = this.document.find( "body" );
13722
13723      // support: IE
13724      this.storedCursor = body.css( "cursor" );
13725      body.css( "cursor", o.cursor );
13726
13727      this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13728    }
13729
13730    if(o.opacity) { // opacity option
13731      if (this.helper.css("opacity")) {
13732        this._storedOpacity = this.helper.css("opacity");
13733      }
13734      this.helper.css("opacity", o.opacity);
13735    }
13736
13737    if(o.zIndex) { // zIndex option
13738      if (this.helper.css("zIndex")) {
13739        this._storedZIndex = this.helper.css("zIndex");
13740      }
13741      this.helper.css("zIndex", o.zIndex);
13742    }
13743
13744    //Prepare scrolling
13745    if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13746      this.overflowOffset = this.scrollParent.offset();
13747    }
13748
13749    //Call callbacks
13750    this._trigger("start", event, this._uiHash());
13751
13752    //Recache the helper size
13753    if(!this._preserveHelperProportions) {
13754      this._cacheHelperProportions();
13755    }
13756
13757
13758    //Post "activate" events to possible containers
13759    if( !noActivation ) {
13760      for ( i = this.containers.length - 1; i >= 0; i-- ) {
13761        this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13762      }
13763    }
13764
13765    //Prepare possible droppables
13766    if($.ui.ddmanager) {
13767      $.ui.ddmanager.current = this;
13768    }
13769
13770    if ($.ui.ddmanager && !o.dropBehaviour) {
13771      $.ui.ddmanager.prepareOffsets(this, event);
13772    }
13773
13774    this.dragging = true;
13775
13776    this.helper.addClass("ui-sortable-helper");
13777    this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13778    return true;
13779
13780  },
13781
13782  _mouseDrag: function(event) {
13783    var i, item, itemElement, intersection,
13784      o = this.options,
13785      scrolled = false;
13786
13787    //Compute the helpers position
13788    this.position = this._generatePosition(event);
13789    this.positionAbs = this._convertPositionTo("absolute");
13790
13791    if (!this.lastPositionAbs) {
13792      this.lastPositionAbs = this.positionAbs;
13793    }
13794
13795    //Do scrolling
13796    if(this.options.scroll) {
13797      if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
13798
13799        if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13800          this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13801        } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13802          this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13803        }
13804
13805        if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13806          this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13807        } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13808          this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13809        }
13810
13811      } else {
13812
13813        if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
13814          scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
13815        } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
13816          scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
13817        }
13818
13819        if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
13820          scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
13821        } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
13822          scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
13823        }
13824
13825      }
13826
13827      if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13828        $.ui.ddmanager.prepareOffsets(this, event);
13829      }
13830    }
13831
13832    //Regenerate the absolute position used for position checks
13833    this.positionAbs = this._convertPositionTo("absolute");
13834
13835    //Set the helper position
13836    if(!this.options.axis || this.options.axis !== "y") {
13837      this.helper[0].style.left = this.position.left+"px";
13838    }
13839    if(!this.options.axis || this.options.axis !== "x") {
13840      this.helper[0].style.top = this.position.top+"px";
13841    }
13842
13843    //Rearrange
13844    for (i = this.items.length - 1; i >= 0; i--) {
13845
13846      //Cache variables and intersection, continue if no intersection
13847      item = this.items[i];
13848      itemElement = item.item[0];
13849      intersection = this._intersectsWithPointer(item);
13850      if (!intersection) {
13851        continue;
13852      }
13853
13854      // Only put the placeholder inside the current Container, skip all
13855      // items from other containers. This works because when moving
13856      // an item from one container to another the
13857      // currentContainer is switched before the placeholder is moved.
13858      //
13859      // Without this, moving items in "sub-sortables" can cause
13860      // the placeholder to jitter between the outer and inner container.
13861      if (item.instance !== this.currentContainer) {
13862        continue;
13863      }
13864
13865      // cannot intersect with itself
13866      // no useless actions that have been done before
13867      // no action if the item moved is the parent of the item checked
13868      if (itemElement !== this.currentItem[0] &&
13869        this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13870        !$.contains(this.placeholder[0], itemElement) &&
13871        (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13872      ) {
13873
13874        this.direction = intersection === 1 ? "down" : "up";
13875
13876        if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13877          this._rearrange(event, item);
13878        } else {
13879          break;
13880        }
13881
13882        this._trigger("change", event, this._uiHash());
13883        break;
13884      }
13885    }
13886
13887    //Post events to containers
13888    this._contactContainers(event);
13889
13890    //Interconnect with droppables
13891    if($.ui.ddmanager) {
13892      $.ui.ddmanager.drag(this, event);
13893    }
13894
13895    //Call callbacks
13896    this._trigger("sort", event, this._uiHash());
13897
13898    this.lastPositionAbs = this.positionAbs;
13899    return false;
13900
13901  },
13902
13903  _mouseStop: function(event, noPropagation) {
13904
13905    if(!event) {
13906      return;
13907    }
13908
13909    //If we are using droppables, inform the manager about the drop
13910    if ($.ui.ddmanager && !this.options.dropBehaviour) {
13911      $.ui.ddmanager.drop(this, event);
13912    }
13913
13914    if(this.options.revert) {
13915      var that = this,
13916        cur = this.placeholder.offset(),
13917        axis = this.options.axis,
13918        animation = {};
13919
13920      if ( !axis || axis === "x" ) {
13921        animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
13922      }
13923      if ( !axis || axis === "y" ) {
13924        animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
13925      }
13926      this.reverting = true;
13927      $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13928        that._clear(event);
13929      });
13930    } else {
13931      this._clear(event, noPropagation);
13932    }
13933
13934    return false;
13935
13936  },
13937
13938  cancel: function() {
13939
13940    if(this.dragging) {
13941
13942      this._mouseUp({ target: null });
13943
13944      if(this.options.helper === "original") {
13945        this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13946      } else {
13947        this.currentItem.show();
13948      }
13949
13950      //Post deactivating events to containers
13951      for (var i = this.containers.length - 1; i >= 0; i--){
13952        this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13953        if(this.containers[i].containerCache.over) {
13954          this.containers[i]._trigger("out", null, this._uiHash(this));
13955          this.containers[i].containerCache.over = 0;
13956        }
13957      }
13958
13959    }
13960
13961    if (this.placeholder) {
13962      //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13963      if(this.placeholder[0].parentNode) {
13964        this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13965      }
13966      if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13967        this.helper.remove();
13968      }
13969
13970      $.extend(this, {
13971        helper: null,
13972        dragging: false,
13973        reverting: false,
13974        _noFinalSort: null
13975      });
13976
13977      if(this.domPosition.prev) {
13978        $(this.domPosition.prev).after(this.currentItem);
13979      } else {
13980        $(this.domPosition.parent).prepend(this.currentItem);
13981      }
13982    }
13983
13984    return this;
13985
13986  },
13987
13988  serialize: function(o) {
13989
13990    var items = this._getItemsAsjQuery(o && o.connected),
13991      str = [];
13992    o = o || {};
13993
13994    $(items).each(function() {
13995      var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13996      if (res) {
13997        str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13998      }
13999    });
14000
14001    if(!str.length && o.key) {
14002      str.push(o.key + "=");
14003    }
14004
14005    return str.join("&");
14006
14007  },
14008
14009  toArray: function(o) {
14010
14011    var items = this._getItemsAsjQuery(o && o.connected),
14012      ret = [];
14013
14014    o = o || {};
14015
14016    items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
14017    return ret;
14018
14019  },
14020
14021  /* Be careful with the following core functions */
14022  _intersectsWith: function(item) {
14023
14024    var x1 = this.positionAbs.left,
14025      x2 = x1 + this.helperProportions.width,
14026      y1 = this.positionAbs.top,
14027      y2 = y1 + this.helperProportions.height,
14028      l = item.left,
14029      r = l + item.width,
14030      t = item.top,
14031      b = t + item.height,
14032      dyClick = this.offset.click.top,
14033      dxClick = this.offset.click.left,
14034      isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
14035      isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
14036      isOverElement = isOverElementHeight && isOverElementWidth;
14037
14038    if ( this.options.tolerance === "pointer" ||
14039      this.options.forcePointerForContainers ||
14040      (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
14041    ) {
14042      return isOverElement;
14043    } else {
14044
14045      return (l < x1 + (this.helperProportions.width / 2) && // Right Half
14046        x2 - (this.helperProportions.width / 2) < r && // Left Half
14047        t < y1 + (this.helperProportions.height / 2) && // Bottom Half
14048        y2 - (this.helperProportions.height / 2) < b ); // Top Half
14049
14050    }
14051  },
14052
14053  _intersectsWithPointer: function(item) {
14054
14055    var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
14056      isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
14057      isOverElement = isOverElementHeight && isOverElementWidth,
14058      verticalDirection = this._getDragVerticalDirection(),
14059      horizontalDirection = this._getDragHorizontalDirection();
14060
14061    if (!isOverElement) {
14062      return false;
14063    }
14064
14065    return this.floating ?
14066      ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
14067      : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
14068
14069  },
14070
14071  _intersectsWithSides: function(item) {
14072
14073    var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
14074      isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
14075      verticalDirection = this._getDragVerticalDirection(),
14076      horizontalDirection = this._getDragHorizontalDirection();
14077
14078    if (this.floating && horizontalDirection) {
14079      return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
14080    } else {
14081      return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
14082    }
14083
14084  },
14085
14086  _getDragVerticalDirection: function() {
14087    var delta = this.positionAbs.top - this.lastPositionAbs.top;
14088    return delta !== 0 && (delta > 0 ? "down" : "up");
14089  },
14090
14091  _getDragHorizontalDirection: function() {
14092    var delta = this.positionAbs.left - this.lastPositionAbs.left;
14093    return delta !== 0 && (delta > 0 ? "right" : "left");
14094  },
14095
14096  refresh: function(event) {
14097    this._refreshItems(event);
14098    this._setHandleClassName();
14099    this.refreshPositions();
14100    return this;
14101  },
14102
14103  _connectWith: function() {
14104    var options = this.options;
14105    return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
14106  },
14107
14108  _getItemsAsjQuery: function(connected) {
14109
14110    var i, j, cur, inst,
14111      items = [],
14112      queries = [],
14113      connectWith = this._connectWith();
14114
14115    if(connectWith && connected) {
14116      for (i = connectWith.length - 1; i >= 0; i--){
14117        cur = $(connectWith[i], this.document[0]);
14118        for ( j = cur.length - 1; j >= 0; j--){
14119          inst = $.data(cur[j], this.widgetFullName);
14120          if(inst && inst !== this && !inst.options.disabled) {
14121            queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
14122          }
14123        }
14124      }
14125    }
14126
14127    queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
14128
14129    function addItems() {
14130      items.push( this );
14131    }
14132    for (i = queries.length - 1; i >= 0; i--){
14133      queries[i][0].each( addItems );
14134    }
14135
14136    return $(items);
14137
14138  },
14139
14140  _removeCurrentsFromItems: function() {
14141
14142    var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
14143
14144    this.items = $.grep(this.items, function (item) {
14145      for (var j=0; j < list.length; j++) {
14146        if(list[j] === item.item[0]) {
14147          return false;
14148        }
14149      }
14150      return true;
14151    });
14152
14153  },
14154
14155  _refreshItems: function(event) {
14156
14157    this.items = [];
14158    this.containers = [this];
14159
14160    var i, j, cur, inst, targetData, _queries, item, queriesLength,
14161      items = this.items,
14162      queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
14163      connectWith = this._connectWith();
14164
14165    if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
14166      for (i = connectWith.length - 1; i >= 0; i--){
14167        cur = $(connectWith[i], this.document[0]);
14168        for (j = cur.length - 1; j >= 0; j--){
14169          inst = $.data(cur[j], this.widgetFullName);
14170          if(inst && inst !== this && !inst.options.disabled) {
14171            queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
14172            this.containers.push(inst);
14173          }
14174        }
14175      }
14176    }
14177
14178    for (i = queries.length - 1; i >= 0; i--) {
14179      targetData = queries[i][1];
14180      _queries = queries[i][0];
14181
14182      for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
14183        item = $(_queries[j]);
14184
14185        item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
14186
14187        items.push({
14188          item: item,
14189          instance: targetData,
14190          width: 0, height: 0,
14191          left: 0, top: 0
14192        });
14193      }
14194    }
14195
14196  },
14197
14198  refreshPositions: function(fast) {
14199
14200    // Determine whether items are being displayed horizontally
14201    this.floating = this.items.length ?
14202      this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
14203      false;
14204
14205    //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14206    if(this.offsetParent && this.helper) {
14207      this.offset.parent = this._getParentOffset();
14208    }
14209
14210    var i, item, t, p;
14211
14212    for (i = this.items.length - 1; i >= 0; i--){
14213      item = this.items[i];
14214
14215      //We ignore calculating positions of all connected containers when we're not over them
14216      if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14217        continue;
14218      }
14219
14220      t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14221
14222      if (!fast) {
14223        item.width = t.outerWidth();
14224        item.height = t.outerHeight();
14225      }
14226
14227      p = t.offset();
14228      item.left = p.left;
14229      item.top = p.top;
14230    }
14231
14232    if(this.options.custom && this.options.custom.refreshContainers) {
14233      this.options.custom.refreshContainers.call(this);
14234    } else {
14235      for (i = this.containers.length - 1; i >= 0; i--){
14236        p = this.containers[i].element.offset();
14237        this.containers[i].containerCache.left = p.left;
14238        this.containers[i].containerCache.top = p.top;
14239        this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14240        this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14241      }
14242    }
14243
14244    return this;
14245  },
14246
14247  _createPlaceholder: function(that) {
14248    that = that || this;
14249    var className,
14250      o = that.options;
14251
14252    if(!o.placeholder || o.placeholder.constructor === String) {
14253      className = o.placeholder;
14254      o.placeholder = {
14255        element: function() {
14256
14257          var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14258            element = $( "<" + nodeName + ">", that.document[0] )
14259              .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14260              .removeClass("ui-sortable-helper");
14261
14262          if ( nodeName === "tbody" ) {
14263            that._createTrPlaceholder(
14264              that.currentItem.find( "tr" ).eq( 0 ),
14265              $( "<tr>", that.document[ 0 ] ).appendTo( element )
14266            );
14267          } else if ( nodeName === "tr" ) {
14268            that._createTrPlaceholder( that.currentItem, element );
14269          } else if ( nodeName === "img" ) {
14270            element.attr( "src", that.currentItem.attr( "src" ) );
14271          }
14272
14273          if ( !className ) {
14274            element.css( "visibility", "hidden" );
14275          }
14276
14277          return element;
14278        },
14279        update: function(container, p) {
14280
14281          // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14282          // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14283          if(className && !o.forcePlaceholderSize) {
14284            return;
14285          }
14286
14287          //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
14288          if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14289          if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14290        }
14291      };
14292    }
14293
14294    //Create the placeholder
14295    that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14296
14297    //Append it after the actual current item
14298    that.currentItem.after(that.placeholder);
14299
14300    //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14301    o.placeholder.update(that, that.placeholder);
14302
14303  },
14304
14305  _createTrPlaceholder: function( sourceTr, targetTr ) {
14306    var that = this;
14307
14308    sourceTr.children().each(function() {
14309      $( "<td>&#160;</td>", that.document[ 0 ] )
14310        .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14311        .appendTo( targetTr );
14312    });
14313  },
14314
14315  _contactContainers: function(event) {
14316    var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14317      innermostContainer = null,
14318      innermostIndex = null;
14319
14320    // get innermost container that intersects with item
14321    for (i = this.containers.length - 1; i >= 0; i--) {
14322
14323      // never consider a container that's located within the item itself
14324      if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14325        continue;
14326      }
14327
14328      if(this._intersectsWith(this.containers[i].containerCache)) {
14329
14330        // if we've already found a container and it's more "inner" than this, then continue
14331        if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14332          continue;
14333        }
14334
14335        innermostContainer = this.containers[i];
14336        innermostIndex = i;
14337
14338      } else {
14339        // container doesn't intersect. trigger "out" event if necessary
14340        if(this.containers[i].containerCache.over) {
14341          this.containers[i]._trigger("out", event, this._uiHash(this));
14342          this.containers[i].containerCache.over = 0;
14343        }
14344      }
14345
14346    }
14347
14348    // if no intersecting containers found, return
14349    if(!innermostContainer) {
14350      return;
14351    }
14352
14353    // move the item into the container if it's not there already
14354    if(this.containers.length === 1) {
14355      if (!this.containers[innermostIndex].containerCache.over) {
14356        this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14357        this.containers[innermostIndex].containerCache.over = 1;
14358      }
14359    } else {
14360
14361      //When entering a new container, we will find the item with the least distance and append our item near it
14362      dist = 10000;
14363      itemWithLeastDistance = null;
14364      floating = innermostContainer.floating || this._isFloating(this.currentItem);
14365      posProperty = floating ? "left" : "top";
14366      sizeProperty = floating ? "width" : "height";
14367      axis = floating ? "clientX" : "clientY";
14368
14369      for (j = this.items.length - 1; j >= 0; j--) {
14370        if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14371          continue;
14372        }
14373        if(this.items[j].item[0] === this.currentItem[0]) {
14374          continue;
14375        }
14376
14377        cur = this.items[j].item.offset()[posProperty];
14378        nearBottom = false;
14379        if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14380          nearBottom = true;
14381        }
14382
14383        if ( Math.abs( event[ axis ] - cur ) < dist ) {
14384          dist = Math.abs( event[ axis ] - cur );
14385          itemWithLeastDistance = this.items[ j ];
14386          this.direction = nearBottom ? "up": "down";
14387        }
14388      }
14389
14390      //Check if dropOnEmpty is enabled
14391      if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14392        return;
14393      }
14394
14395      if(this.currentContainer === this.containers[innermostIndex]) {
14396        if ( !this.currentContainer.containerCache.over ) {
14397          this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
14398          this.currentContainer.containerCache.over = 1;
14399        }
14400        return;
14401      }
14402
14403      itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14404      this._trigger("change", event, this._uiHash());
14405      this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14406      this.currentContainer = this.containers[innermostIndex];
14407
14408      //Update the placeholder
14409      this.options.placeholder.update(this.currentContainer, this.placeholder);
14410
14411      this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14412      this.containers[innermostIndex].containerCache.over = 1;
14413    }
14414
14415
14416  },
14417
14418  _createHelper: function(event) {
14419
14420    var o = this.options,
14421      helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14422
14423    //Add the helper to the DOM if that didn't happen already
14424    if(!helper.parents("body").length) {
14425      $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14426    }
14427
14428    if(helper[0] === this.currentItem[0]) {
14429      this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
14430    }
14431
14432    if(!helper[0].style.width || o.forceHelperSize) {
14433      helper.width(this.currentItem.width());
14434    }
14435    if(!helper[0].style.height || o.forceHelperSize) {
14436      helper.height(this.currentItem.height());
14437    }
14438
14439    return helper;
14440
14441  },
14442
14443  _adjustOffsetFromHelper: function(obj) {
14444    if (typeof obj === "string") {
14445      obj = obj.split(" ");
14446    }
14447    if ($.isArray(obj)) {
14448      obj = {left: +obj[0], top: +obj[1] || 0};
14449    }
14450    if ("left" in obj) {
14451      this.offset.click.left = obj.left + this.margins.left;
14452    }
14453    if ("right" in obj) {
14454      this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14455    }
14456    if ("top" in obj) {
14457      this.offset.click.top = obj.top + this.margins.top;
14458    }
14459    if ("bottom" in obj) {
14460      this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14461    }
14462  },
14463
14464  _getParentOffset: function() {
14465
14466
14467    //Get the offsetParent and cache its position
14468    this.offsetParent = this.helper.offsetParent();
14469    var po = this.offsetParent.offset();
14470
14471    // This is a special case where we need to modify a offset calculated on start, since the following happened:
14472    // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14473    // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14474    //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14475    if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14476      po.left += this.scrollParent.scrollLeft();
14477      po.top += this.scrollParent.scrollTop();
14478    }
14479
14480    // This needs to be actually done for all browsers, since pageX/pageY includes this information
14481    // with an ugly IE fix
14482    if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14483      po = { top: 0, left: 0 };
14484    }
14485
14486    return {
14487      top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14488      left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14489    };
14490
14491  },
14492
14493  _getRelativeOffset: function() {
14494
14495    if(this.cssPosition === "relative") {
14496      var p = this.currentItem.position();
14497      return {
14498        top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14499        left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14500      };
14501    } else {
14502      return { top: 0, left: 0 };
14503    }
14504
14505  },
14506
14507  _cacheMargins: function() {
14508    this.margins = {
14509      left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14510      top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14511    };
14512  },
14513
14514  _cacheHelperProportions: function() {
14515    this.helperProportions = {
14516      width: this.helper.outerWidth(),
14517      height: this.helper.outerHeight()
14518    };
14519  },
14520
14521  _setContainment: function() {
14522
14523    var ce, co, over,
14524      o = this.options;
14525    if(o.containment === "parent") {
14526      o.containment = this.helper[0].parentNode;
14527    }
14528    if(o.containment === "document" || o.containment === "window") {
14529      this.containment = [
14530        0 - this.offset.relative.left - this.offset.parent.left,
14531        0 - this.offset.relative.top - this.offset.parent.top,
14532        o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
14533        (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14534      ];
14535    }
14536
14537    if(!(/^(document|window|parent)$/).test(o.containment)) {
14538      ce = $(o.containment)[0];
14539      co = $(o.containment).offset();
14540      over = ($(ce).css("overflow") !== "hidden");
14541
14542      this.containment = [
14543        co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14544        co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14545        co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
14546        co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
14547      ];
14548    }
14549
14550  },
14551
14552  _convertPositionTo: function(d, pos) {
14553
14554    if(!pos) {
14555      pos = this.position;
14556    }
14557    var mod = d === "absolute" ? 1 : -1,
14558      scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14559      scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14560
14561    return {
14562      top: (
14563        pos.top  +                                // The absolute mouse position
14564        this.offset.relative.top * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
14565        this.offset.parent.top * mod -                      // The offsetParent's offset without borders (offset + border)
14566        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14567      ),
14568      left: (
14569        pos.left +                                // The absolute mouse position
14570        this.offset.relative.left * mod +                    // Only for relative positioned nodes: Relative offset from element to offset parent
14571        this.offset.parent.left * mod  -                    // The offsetParent's offset without borders (offset + border)
14572        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14573      )
14574    };
14575
14576  },
14577
14578  _generatePosition: function(event) {
14579
14580    var top, left,
14581      o = this.options,
14582      pageX = event.pageX,
14583      pageY = event.pageY,
14584      scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14585
14586    // This is another very weird special case that only happens for relative elements:
14587    // 1. If the css position is relative
14588    // 2. and the scroll parent is the document or similar to the offset parent
14589    // we have to refresh the relative offset during the scroll so there are no jumps
14590    if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
14591      this.offset.relative = this._getRelativeOffset();
14592    }
14593
14594    /*
14595     * - Position constraining -
14596     * Constrain the position to a mix of grid, containment.
14597     */
14598
14599    if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14600
14601      if(this.containment) {
14602        if(event.pageX - this.offset.click.left < this.containment[0]) {
14603          pageX = this.containment[0] + this.offset.click.left;
14604        }
14605        if(event.pageY - this.offset.click.top < this.containment[1]) {
14606          pageY = this.containment[1] + this.offset.click.top;
14607        }
14608        if(event.pageX - this.offset.click.left > this.containment[2]) {
14609          pageX = this.containment[2] + this.offset.click.left;
14610        }
14611        if(event.pageY - this.offset.click.top > this.containment[3]) {
14612          pageY = this.containment[3] + this.offset.click.top;
14613        }
14614      }
14615
14616      if(o.grid) {
14617        top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14618        pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
14619
14620        left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14621        pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
14622      }
14623
14624    }
14625
14626    return {
14627      top: (
14628        pageY -                                // The absolute mouse position
14629        this.offset.click.top -                          // Click offset (relative to the element)
14630        this.offset.relative.top  -                      // Only for relative positioned nodes: Relative offset from element to offset parent
14631        this.offset.parent.top +                        // The offsetParent's offset without borders (offset + border)
14632        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14633      ),
14634      left: (
14635        pageX -                                // The absolute mouse position
14636        this.offset.click.left -                        // Click offset (relative to the element)
14637        this.offset.relative.left  -                      // Only for relative positioned nodes: Relative offset from element to offset parent
14638        this.offset.parent.left +                        // The offsetParent's offset without borders (offset + border)
14639        ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14640      )
14641    };
14642
14643  },
14644
14645  _rearrange: function(event, i, a, hardRefresh) {
14646
14647    a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
14648
14649    //Various things done here to improve the performance:
14650    // 1. we create a setTimeout, that calls refreshPositions
14651    // 2. on the instance, we have a counter variable, that get's higher after every append
14652    // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14653    // 4. this lets only the last addition to the timeout stack through
14654    this.counter = this.counter ? ++this.counter : 1;
14655    var counter = this.counter;
14656
14657    this._delay(function() {
14658      if(counter === this.counter) {
vendor: 4,563 bytes, lines 14659-14787
14659        this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14660      }
14661    });
14662
14663  },
14664
14665  _clear: function(event, noPropagation) {
14666
14667    this.reverting = false;
14668    // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14669    // everything else normalized again
14670    var i,
14671      delayedTriggers = [];
14672
14673    // We first have to update the dom position of the actual currentItem
14674    // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14675    if(!this._noFinalSort && this.currentItem.parent().length) {
14676      this.placeholder.before(this.currentItem);
14677    }
14678    this._noFinalSort = null;
14679
14680    if(this.helper[0] === this.currentItem[0]) {
14681      for(i in this._storedCSS) {
14682        if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14683          this._storedCSS[i] = "";
14684        }
14685      }
14686      this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14687    } else {
14688      this.currentItem.show();
14689    }
14690
14691    if(this.fromOutside && !noPropagation) {
14692      delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14693    }
14694    if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14695      delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14696    }
14697
14698    // Check if the items Container has Changed and trigger appropriate
14699    // events.
14700    if (this !== this.currentContainer) {
14701      if(!noPropagation) {
14702        delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14703        delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14704        delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14705      }
14706    }
14707
14708
14709    //Post events to containers
14710    function delayEvent( type, instance, container ) {
14711      return function( event ) {
14712        container._trigger( type, event, instance._uiHash( instance ) );
14713      };
14714    }
14715    for (i = this.containers.length - 1; i >= 0; i--){
14716      if (!noPropagation) {
14717        delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14718      }
14719      if(this.containers[i].containerCache.over) {
14720        delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14721        this.containers[i].containerCache.over = 0;
14722      }
14723    }
14724
14725    //Do what was originally in plugins
14726    if ( this.storedCursor ) {
14727      this.document.find( "body" ).css( "cursor", this.storedCursor );
14728      this.storedStylesheet.remove();
14729    }
14730    if(this._storedOpacity) {
14731      this.helper.css("opacity", this._storedOpacity);
14732    }
14733    if(this._storedZIndex) {
14734      this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14735    }
14736
14737    this.dragging = false;
14738
14739    if(!noPropagation) {
14740      this._trigger("beforeStop", event, this._uiHash());
14741    }
14742
14743    //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14744    this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14745
14746    if ( !this.cancelHelperRemoval ) {
14747      if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
14748        this.helper.remove();
14749      }
14750      this.helper = null;
14751    }
14752
14753    if(!noPropagation) {
14754      for (i=0; i < delayedTriggers.length; i++) {
14755        delayedTriggers[i].call(this, event);
14756      } //Trigger all delayed events
14757      this._trigger("stop", event, this._uiHash());
14758    }
14759
14760    this.fromOutside = false;
14761    return !this.cancelHelperRemoval;
14762
14763  },
14764
14765  _trigger: function() {
14766    if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14767      this.cancel();
14768    }
14769  },
14770
14771  _uiHash: function(_inst) {
14772    var inst = _inst || this;
14773    return {
14774      helper: inst.helper,
14775      placeholder: inst.placeholder || $([]),
14776      position: inst.position,
14777      originalPosition: inst.originalPosition,
14778      offset: inst.positionAbs,
14779      item: inst.currentItem,
14780      sender: _inst ? _inst.element : null
14781    };
14782  }
14783
14784});
14785
14786
14787/*!
vendor: 15,122 bytes, lines 14788-15329
14788 * jQuery UI Spinner 1.11.4
14789 * http://jqueryui.com
14790 *
14791 * Copyright jQuery Foundation and other contributors
14792 * Released under the MIT license.
14793 * http://jquery.org/license
14794 *
14795 * http://api.jqueryui.com/spinner/
14796 */
14797
14798
14799function spinner_modifier( fn ) {
14800  return function() {
14801    var previous = this.element.val();
14802    fn.apply( this, arguments );
14803    this._refresh();
14804    if ( previous !== this.element.val() ) {
14805      this._trigger( "change" );
14806    }
14807  };
14808}
14809
14810var spinner = $.widget( "ui.spinner", {
14811  version: "1.11.4",
14812  defaultElement: "<input>",
14813  widgetEventPrefix: "spin",
14814  options: {
14815    culture: null,
14816    icons: {
14817      down: "ui-icon-triangle-1-s",
14818      up: "ui-icon-triangle-1-n"
14819    },
14820    incremental: true,
14821    max: null,
14822    min: null,
14823    numberFormat: null,
14824    page: 10,
14825    step: 1,
14826
14827    change: null,
14828    spin: null,
14829    start: null,
14830    stop: null
14831  },
14832
14833  _create: function() {
14834    // handle string values that need to be parsed
14835    this._setOption( "max", this.options.max );
14836    this._setOption( "min", this.options.min );
14837    this._setOption( "step", this.options.step );
14838
14839    // Only format if there is a value, prevents the field from being marked
14840    // as invalid in Firefox, see #9573.
14841    if ( this.value() !== "" ) {
14842      // Format the value, but don't constrain.
14843      this._value( this.element.val(), true );
14844    }
14845
14846    this._draw();
14847    this._on( this._events );
14848    this._refresh();
14849
14850    // turning off autocomplete prevents the browser from remembering the
14851    // value when navigating through history, so we re-enable autocomplete
14852    // if the page is unloaded before the widget is destroyed. #7790
14853    this._on( this.window, {
14854      beforeunload: function() {
14855        this.element.removeAttr( "autocomplete" );
14856      }
14857    });
14858  },
14859
14860  _getCreateOptions: function() {
14861    var options = {},
14862      element = this.element;
14863
14864    $.each( [ "min", "max", "step" ], function( i, option ) {
14865      var value = element.attr( option );
14866      if ( value !== undefined && value.length ) {
14867        options[ option ] = value;
14868      }
14869    });
14870
14871    return options;
14872  },
14873
14874  _events: {
14875    keydown: function( event ) {
14876      if ( this._start( event ) && this._keydown( event ) ) {
14877        event.preventDefault();
14878      }
14879    },
14880    keyup: "_stop",
14881    focus: function() {
14882      this.previous = this.element.val();
14883    },
14884    blur: function( event ) {
14885      if ( this.cancelBlur ) {
14886        delete this.cancelBlur;
14887        return;
14888      }
14889
14890      this._stop();
14891      this._refresh();
14892      if ( this.previous !== this.element.val() ) {
14893        this._trigger( "change", event );
14894      }
14895    },
14896    mousewheel: function( event, delta ) {
14897      if ( !delta ) {
14898        return;
14899      }
14900      if ( !this.spinning && !this._start( event ) ) {
14901        return false;
14902      }
14903
14904      this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14905      clearTimeout( this.mousewheelTimer );
14906      this.mousewheelTimer = this._delay(function() {
14907        if ( this.spinning ) {
14908          this._stop( event );
14909        }
14910      }, 100 );
14911      event.preventDefault();
14912    },
14913    "mousedown .ui-spinner-button": function( event ) {
14914      var previous;
14915
14916      // We never want the buttons to have focus; whenever the user is
14917      // interacting with the spinner, the focus should be on the input.
14918      // If the input is focused then this.previous is properly set from
14919      // when the input first received focus. If the input is not focused
14920      // then we need to set this.previous based on the value before spinning.
14921      previous = this.element[0] === this.document[0].activeElement ?
14922        this.previous : this.element.val();
14923      function checkFocus() {
14924        var isActive = this.element[0] === this.document[0].activeElement;
14925        if ( !isActive ) {
14926          this.element.focus();
14927          this.previous = previous;
14928          // support: IE
14929          // IE sets focus asynchronously, so we need to check if focus
14930          // moved off of the input because the user clicked on the button.
14931          this._delay(function() {
14932            this.previous = previous;
14933          });
14934        }
14935      }
14936
14937      // ensure focus is on (or stays on) the text field
14938      event.preventDefault();
14939      checkFocus.call( this );
14940
14941      // support: IE
14942      // IE doesn't prevent moving focus even with event.preventDefault()
14943      // so we set a flag to know when we should ignore the blur event
14944      // and check (again) if focus moved off of the input.
14945      this.cancelBlur = true;
14946      this._delay(function() {
14947        delete this.cancelBlur;
14948        checkFocus.call( this );
14949      });
14950
14951      if ( this._start( event ) === false ) {
14952        return;
14953      }
14954
14955      this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14956    },
14957    "mouseup .ui-spinner-button": "_stop",
14958    "mouseenter .ui-spinner-button": function( event ) {
14959      // button will add ui-state-active if mouse was down while mouseleave and kept down
14960      if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14961        return;
14962      }
14963
14964      if ( this._start( event ) === false ) {
14965        return false;
14966      }
14967      this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14968    },
14969    // TODO: do we really want to consider this a stop?
14970    // shouldn't we just stop the repeater and wait until mouseup before
14971    // we trigger the stop event?
14972    "mouseleave .ui-spinner-button": "_stop"
14973  },
14974
14975  _draw: function() {
14976    var uiSpinner = this.uiSpinner = this.element
14977      .addClass( "ui-spinner-input" )
14978      .attr( "autocomplete", "off" )
14979      .wrap( this._uiSpinnerHtml() )
14980      .parent()
14981        // add buttons
14982        .append( this._buttonHtml() );
14983
14984    this.element.attr( "role", "spinbutton" );
14985
14986    // button bindings
14987    this.buttons = uiSpinner.find( ".ui-spinner-button" )
14988      .attr( "tabIndex", -1 )
14989      .button()
14990      .removeClass( "ui-corner-all" );
14991
14992    // IE 6 doesn't understand height: 50% for the buttons
14993    // unless the wrapper has an explicit height
14994    if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14995        uiSpinner.height() > 0 ) {
14996      uiSpinner.height( uiSpinner.height() );
14997    }
14998
14999    // disable spinner if element was already disabled
15000    if ( this.options.disabled ) {
15001      this.disable();
15002    }
15003  },
15004
15005  _keydown: function( event ) {
15006    var options = this.options,
15007      keyCode = $.ui.keyCode;
15008
15009    switch ( event.keyCode ) {
15010    case keyCode.UP:
15011      this._repeat( null, 1, event );
15012      return true;
15013    case keyCode.DOWN:
15014      this._repeat( null, -1, event );
15015      return true;
15016    case keyCode.PAGE_UP:
15017      this._repeat( null, options.page, event );
15018      return true;
15019    case keyCode.PAGE_DOWN:
15020      this._repeat( null, -options.page, event );
15021      return true;
15022    }
15023
15024    return false;
15025  },
15026
15027  _uiSpinnerHtml: function() {
15028    return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
15029  },
15030
15031  _buttonHtml: function() {
15032    return "" +
15033      "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
15034        "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
15035      "</a>" +
15036      "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
15037        "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
15038      "</a>";
15039  },
15040
15041  _start: function( event ) {
15042    if ( !this.spinning && this._trigger( "start", event ) === false ) {
15043      return false;
15044    }
15045
15046    if ( !this.counter ) {
15047      this.counter = 1;
15048    }
15049    this.spinning = true;
15050    return true;
15051  },
15052
15053  _repeat: function( i, steps, event ) {
15054    i = i || 500;
15055
15056    clearTimeout( this.timer );
15057    this.timer = this._delay(function() {
15058      this._repeat( 40, steps, event );
15059    }, i );
15060
15061    this._spin( steps * this.options.step, event );
15062  },
15063
15064  _spin: function( step, event ) {
15065    var value = this.value() || 0;
15066
15067    if ( !this.counter ) {
15068      this.counter = 1;
15069    }
15070
15071    value = this._adjustValue( value + step * this._increment( this.counter ) );
15072
15073    if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
15074      this._value( value );
15075      this.counter++;
15076    }
15077  },
15078
15079  _increment: function( i ) {
15080    var incremental = this.options.incremental;
15081
15082    if ( incremental ) {
15083      return $.isFunction( incremental ) ?
15084        incremental( i ) :
15085        Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
15086    }
15087
15088    return 1;
15089  },
15090
15091  _precision: function() {
15092    var precision = this._precisionOf( this.options.step );
15093    if ( this.options.min !== null ) {
15094      precision = Math.max( precision, this._precisionOf( this.options.min ) );
15095    }
15096    return precision;
15097  },
15098
15099  _precisionOf: function( num ) {
15100    var str = num.toString(),
15101      decimal = str.indexOf( "." );
15102    return decimal === -1 ? 0 : str.length - decimal - 1;
15103  },
15104
15105  _adjustValue: function( value ) {
15106    var base, aboveMin,
15107      options = this.options;
15108
15109    // make sure we're at a valid step
15110    // - find out where we are relative to the base (min or 0)
15111    base = options.min !== null ? options.min : 0;
15112    aboveMin = value - base;
15113    // - round to the nearest step
15114    aboveMin = Math.round(aboveMin / options.step) * options.step;
15115    // - rounding is based on 0, so adjust back to our base
15116    value = base + aboveMin;
15117
15118    // fix precision from bad JS floating point math
15119    value = parseFloat( value.toFixed( this._precision() ) );
15120
15121    // clamp the value
15122    if ( options.max !== null && value > options.max) {
15123      return options.max;
15124    }
15125    if ( options.min !== null && value < options.min ) {
15126      return options.min;
15127    }
15128
15129    return value;
15130  },
15131
15132  _stop: function( event ) {
15133    if ( !this.spinning ) {
15134      return;
15135    }
15136
15137    clearTimeout( this.timer );
15138    clearTimeout( this.mousewheelTimer );
15139    this.counter = 0;
15140    this.spinning = false;
15141    this._trigger( "stop", event );
15142  },
15143
15144  _setOption: function( key, value ) {
15145    if ( key === "culture" || key === "numberFormat" ) {
15146      var prevValue = this._parse( this.element.val() );
15147      this.options[ key ] = value;
15148      this.element.val( this._format( prevValue ) );
15149      return;
15150    }
15151
15152    if ( key === "max" || key === "min" || key === "step" ) {
15153      if ( typeof value === "string" ) {
15154        value = this._parse( value );
15155      }
15156    }
15157    if ( key === "icons" ) {
15158      this.buttons.first().find( ".ui-icon" )
15159        .removeClass( this.options.icons.up )
15160        .addClass( value.up );
15161      this.buttons.last().find( ".ui-icon" )
15162        .removeClass( this.options.icons.down )
15163        .addClass( value.down );
15164    }
15165
15166    this._super( key, value );
15167
15168    if ( key === "disabled" ) {
15169      this.widget().toggleClass( "ui-state-disabled", !!value );
15170      this.element.prop( "disabled", !!value );
15171      this.buttons.button( value ? "disable" : "enable" );
15172    }
15173  },
15174
15175  _setOptions: spinner_modifier(function( options ) {
15176    this._super( options );
15177  }),
15178
15179  _parse: function( val ) {
15180    if ( typeof val === "string" && val !== "" ) {
15181      val = window.Globalize && this.options.numberFormat ?
15182        Globalize.parseFloat( val, 10, this.options.culture ) : +val;
15183    }
15184    return val === "" || isNaN( val ) ? null : val;
15185  },
15186
15187  _format: function( value ) {
15188    if ( value === "" ) {
15189      return "";
15190    }
15191    return window.Globalize && this.options.numberFormat ?
15192      Globalize.format( value, this.options.numberFormat, this.options.culture ) :
15193      value;
15194  },
15195
15196  _refresh: function() {
15197    this.element.attr({
15198      "aria-valuemin": this.options.min,
15199      "aria-valuemax": this.options.max,
15200      // TODO: what should we do with values that can't be parsed?
15201      "aria-valuenow": this._parse( this.element.val() )
15202    });
15203  },
15204
15205  isValid: function() {
15206    var value = this.value();
15207
15208    // null is invalid
15209    if ( value === null ) {
15210      return false;
15211    }
15212
15213    // if value gets adjusted, it's invalid
15214    return value === this._adjustValue( value );
15215  },
15216
15217  // update the value without triggering change
15218  _value: function( value, allowAny ) {
15219    var parsed;
15220    if ( value !== "" ) {
15221      parsed = this._parse( value );
15222      if ( parsed !== null ) {
15223        if ( !allowAny ) {
15224          parsed = this._adjustValue( parsed );
15225        }
15226        value = this._format( parsed );
15227      }
15228    }
15229    this.element.val( value );
15230    this._refresh();
15231  },
15232
15233  _destroy: function() {
15234    this.element
15235      .removeClass( "ui-spinner-input" )
15236      .prop( "disabled", false )
15237      .removeAttr( "autocomplete" )
15238      .removeAttr( "role" )
15239      .removeAttr( "aria-valuemin" )
15240      .removeAttr( "aria-valuemax" )
15241      .removeAttr( "aria-valuenow" );
15242    this.uiSpinner.replaceWith( this.element );
15243  },
15244
15245  stepUp: spinner_modifier(function( steps ) {
15246    this._stepUp( steps );
15247  }),
15248  _stepUp: function( steps ) {
15249    if ( this._start() ) {
15250      this._spin( (steps || 1) * this.options.step );
15251      this._stop();
15252    }
15253  },
15254
15255  stepDown: spinner_modifier(function( steps ) {
15256    this._stepDown( steps );
15257  }),
15258  _stepDown: function( steps ) {
15259    if ( this._start() ) {
15260      this._spin( (steps || 1) * -this.options.step );
15261      this._stop();
15262    }
15263  },
15264
15265  pageUp: spinner_modifier(function( pages ) {
15266    this._stepUp( (pages || 1) * this.options.page );
15267  }),
15268
15269  pageDown: spinner_modifier(function( pages ) {
15270    this._stepDown( (pages || 1) * this.options.page );
15271  }),
15272
15273  value: function( newVal ) {
15274    if ( !arguments.length ) {
15275      return this._parse( this.element.val() );
15276    }
15277    spinner_modifier( this._value ).call( this, newVal );
15278  },
15279
15280  widget: function() {
15281    return this.uiSpinner;
15282  }
15283});
15284
15285
15286/*!
15287 * jQuery UI Tabs 1.11.4
15288 * http://jqueryui.com
15289 *
15290 * Copyright jQuery Foundation and other contributors
15291 * Released under the MIT license.
15292 * http://jquery.org/license
15293 *
15294 * http://api.jqueryui.com/tabs/
15295 */
15296
15297
15298var tabs = $.widget( "ui.tabs", {
15299  version: "1.11.4",
15300  delay: 300,
15301  options: {
15302    active: null,
15303    collapsible: false,
15304    event: "click",
15305    heightStyle: "content",
15306    hide: null,
15307    show: null,
15308
15309    // callbacks
15310    activate: null,
15311    beforeActivate: null,
15312    beforeLoad: null,
15313    load: null
15314  },
15315
15316  _isLocal: (function() {
15317    var rhash = /#.*$/;
15318
15319    return function( anchor ) {
15320      var anchorUrl, locationUrl;
15321
15322      // support: IE7
15323      // IE7 doesn't normalize the href property when set via script (#9317)
15324      anchor = anchor.cloneNode( false );
15325
15326      anchorUrl = anchor.href.replace( rhash, "" );
15327      locationUrl = location.href.replace( rhash, "" );
15328
15329      // decoding may throw an error if the URL isn't UTF-8 (#9518)
vendor: 39,008 bytes, lines 15330-16617
15330      try {
15331        anchorUrl = decodeURIComponent( anchorUrl );
15332      } catch ( error ) {}
15333      try {
15334        locationUrl = decodeURIComponent( locationUrl );
15335      } catch ( error ) {}
15336
15337      return anchor.hash.length > 1 && anchorUrl === locationUrl;
15338    };
15339  })(),
15340
15341  _create: function() {
15342    var that = this,
15343      options = this.options;
15344
15345    this.running = false;
15346
15347    this.element
15348      .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15349      .toggleClass( "ui-tabs-collapsible", options.collapsible );
15350
15351    this._processTabs();
15352    options.active = this._initialActive();
15353
15354    // Take disabling tabs via class attribute from HTML
15355    // into account and update option properly.
15356    if ( $.isArray( options.disabled ) ) {
15357      options.disabled = $.unique( options.disabled.concat(
15358        $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15359          return that.tabs.index( li );
15360        })
15361      ) ).sort();
15362    }
15363
15364    // check for length avoids error when initializing empty list
15365    if ( this.options.active !== false && this.anchors.length ) {
15366      this.active = this._findActive( options.active );
15367    } else {
15368      this.active = $();
15369    }
15370
15371    this._refresh();
15372
15373    if ( this.active.length ) {
15374      this.load( options.active );
15375    }
15376  },
15377
15378  _initialActive: function() {
15379    var active = this.options.active,
15380      collapsible = this.options.collapsible,
15381      locationHash = location.hash.substring( 1 );
15382
15383    if ( active === null ) {
15384      // check the fragment identifier in the URL
15385      if ( locationHash ) {
15386        this.tabs.each(function( i, tab ) {
15387          if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15388            active = i;
15389            return false;
15390          }
15391        });
15392      }
15393
15394      // check for a tab marked active via a class
15395      if ( active === null ) {
15396        active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15397      }
15398
15399      // no active tab, set to false
15400      if ( active === null || active === -1 ) {
15401        active = this.tabs.length ? 0 : false;
15402      }
15403    }
15404
15405    // handle numbers: negative, out of range
15406    if ( active !== false ) {
15407      active = this.tabs.index( this.tabs.eq( active ) );
15408      if ( active === -1 ) {
15409        active = collapsible ? false : 0;
15410      }
15411    }
15412
15413    // don't allow collapsible: false and active: false
15414    if ( !collapsible && active === false && this.anchors.length ) {
15415      active = 0;
15416    }
15417
15418    return active;
15419  },
15420
15421  _getCreateEventData: function() {
15422    return {
15423      tab: this.active,
15424      panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15425    };
15426  },
15427
15428  _tabKeydown: function( event ) {
15429    var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15430      selectedIndex = this.tabs.index( focusedTab ),
15431      goingForward = true;
15432
15433    if ( this._handlePageNav( event ) ) {
15434      return;
15435    }
15436
15437    switch ( event.keyCode ) {
15438      case $.ui.keyCode.RIGHT:
15439      case $.ui.keyCode.DOWN:
15440        selectedIndex++;
15441        break;
15442      case $.ui.keyCode.UP:
15443      case $.ui.keyCode.LEFT:
15444        goingForward = false;
15445        selectedIndex--;
15446        break;
15447      case $.ui.keyCode.END:
15448        selectedIndex = this.anchors.length - 1;
15449        break;
15450      case $.ui.keyCode.HOME:
15451        selectedIndex = 0;
15452        break;
15453      case $.ui.keyCode.SPACE:
15454        // Activate only, no collapsing
15455        event.preventDefault();
15456        clearTimeout( this.activating );
15457        this._activate( selectedIndex );
15458        return;
15459      case $.ui.keyCode.ENTER:
15460        // Toggle (cancel delayed activation, allow collapsing)
15461        event.preventDefault();
15462        clearTimeout( this.activating );
15463        // Determine if we should collapse or activate
15464        this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15465        return;
15466      default:
15467        return;
15468    }
15469
15470    // Focus the appropriate tab, based on which key was pressed
15471    event.preventDefault();
15472    clearTimeout( this.activating );
15473    selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15474
15475    // Navigating with control/command key will prevent automatic activation
15476    if ( !event.ctrlKey && !event.metaKey ) {
15477
15478      // Update aria-selected immediately so that AT think the tab is already selected.
15479      // Otherwise AT may confuse the user by stating that they need to activate the tab,
15480      // but the tab will already be activated by the time the announcement finishes.
15481      focusedTab.attr( "aria-selected", "false" );
15482      this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15483
15484      this.activating = this._delay(function() {
15485        this.option( "active", selectedIndex );
15486      }, this.delay );
15487    }
15488  },
15489
15490  _panelKeydown: function( event ) {
15491    if ( this._handlePageNav( event ) ) {
15492      return;
15493    }
15494
15495    // Ctrl+up moves focus to the current tab
15496    if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15497      event.preventDefault();
15498      this.active.focus();
15499    }
15500  },
15501
15502  // Alt+page up/down moves focus to the previous/next tab (and activates)
15503  _handlePageNav: function( event ) {
15504    if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15505      this._activate( this._focusNextTab( this.options.active - 1, false ) );
15506      return true;
15507    }
15508    if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15509      this._activate( this._focusNextTab( this.options.active + 1, true ) );
15510      return true;
15511    }
15512  },
15513
15514  _findNextTab: function( index, goingForward ) {
15515    var lastTabIndex = this.tabs.length - 1;
15516
15517    function constrain() {
15518      if ( index > lastTabIndex ) {
15519        index = 0;
15520      }
15521      if ( index < 0 ) {
15522        index = lastTabIndex;
15523      }
15524      return index;
15525    }
15526
15527    while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15528      index = goingForward ? index + 1 : index - 1;
15529    }
15530
15531    return index;
15532  },
15533
15534  _focusNextTab: function( index, goingForward ) {
15535    index = this._findNextTab( index, goingForward );
15536    this.tabs.eq( index ).focus();
15537    return index;
15538  },
15539
15540  _setOption: function( key, value ) {
15541    if ( key === "active" ) {
15542      // _activate() will handle invalid values and update this.options
15543      this._activate( value );
15544      return;
15545    }
15546
15547    if ( key === "disabled" ) {
15548      // don't use the widget factory's disabled handling
15549      this._setupDisabled( value );
15550      return;
15551    }
15552
15553    this._super( key, value);
15554
15555    if ( key === "collapsible" ) {
15556      this.element.toggleClass( "ui-tabs-collapsible", value );
15557      // Setting collapsible: false while collapsed; open first panel
15558      if ( !value && this.options.active === false ) {
15559        this._activate( 0 );
15560      }
15561    }
15562
15563    if ( key === "event" ) {
15564      this._setupEvents( value );
15565    }
15566
15567    if ( key === "heightStyle" ) {
15568      this._setupHeightStyle( value );
15569    }
15570  },
15571
15572  _sanitizeSelector: function( hash ) {
15573    return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15574  },
15575
15576  refresh: function() {
15577    var options = this.options,
15578      lis = this.tablist.children( ":has(a[href])" );
15579
15580    // get disabled tabs from class attribute from HTML
15581    // this will get converted to a boolean if needed in _refresh()
15582    options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15583      return lis.index( tab );
15584    });
15585
15586    this._processTabs();
15587
15588    // was collapsed or no tabs
15589    if ( options.active === false || !this.anchors.length ) {
15590      options.active = false;
15591      this.active = $();
15592    // was active, but active tab is gone
15593    } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15594      // all remaining tabs are disabled
15595      if ( this.tabs.length === options.disabled.length ) {
15596        options.active = false;
15597        this.active = $();
15598      // activate previous tab
15599      } else {
15600        this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15601      }
15602    // was active, active tab still exists
15603    } else {
15604      // make sure active index is correct
15605      options.active = this.tabs.index( this.active );
15606    }
15607
15608    this._refresh();
15609  },
15610
15611  _refresh: function() {
15612    this._setupDisabled( this.options.disabled );
15613    this._setupEvents( this.options.event );
15614    this._setupHeightStyle( this.options.heightStyle );
15615
15616    this.tabs.not( this.active ).attr({
15617      "aria-selected": "false",
15618      "aria-expanded": "false",
15619      tabIndex: -1
15620    });
15621    this.panels.not( this._getPanelForTab( this.active ) )
15622      .hide()
15623      .attr({
15624        "aria-hidden": "true"
15625      });
15626
15627    // Make sure one tab is in the tab order
15628    if ( !this.active.length ) {
15629      this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15630    } else {
15631      this.active
15632        .addClass( "ui-tabs-active ui-state-active" )
15633        .attr({
15634          "aria-selected": "true",
15635          "aria-expanded": "true",
15636          tabIndex: 0
15637        });
15638      this._getPanelForTab( this.active )
15639        .show()
15640        .attr({
15641          "aria-hidden": "false"
15642        });
15643    }
15644  },
15645
15646  _processTabs: function() {
15647    var that = this,
15648      prevTabs = this.tabs,
15649      prevAnchors = this.anchors,
15650      prevPanels = this.panels;
15651
15652    this.tablist = this._getList()
15653      .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15654      .attr( "role", "tablist" )
15655
15656      // Prevent users from focusing disabled tabs via click
15657      .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15658        if ( $( this ).is( ".ui-state-disabled" ) ) {
15659          event.preventDefault();
15660        }
15661      })
15662
15663      // support: IE <9
15664      // Preventing the default action in mousedown doesn't prevent IE
15665      // from focusing the element, so if the anchor gets focused, blur.
15666      // We don't have to worry about focusing the previously focused
15667      // element since clicking on a non-focusable element should focus
15668      // the body anyway.
15669      .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15670        if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15671          this.blur();
15672        }
15673      });
15674
15675    this.tabs = this.tablist.find( "> li:has(a[href])" )
15676      .addClass( "ui-state-default ui-corner-top" )
15677      .attr({
15678        role: "tab",
15679        tabIndex: -1
15680      });
15681
15682    this.anchors = this.tabs.map(function() {
15683        return $( "a", this )[ 0 ];
15684      })
15685      .addClass( "ui-tabs-anchor" )
15686      .attr({
15687        role: "presentation",
15688        tabIndex: -1
15689      });
15690
15691    this.panels = $();
15692
15693    this.anchors.each(function( i, anchor ) {
15694      var selector, panel, panelId,
15695        anchorId = $( anchor ).uniqueId().attr( "id" ),
15696        tab = $( anchor ).closest( "li" ),
15697        originalAriaControls = tab.attr( "aria-controls" );
15698
15699      // inline tab
15700      if ( that._isLocal( anchor ) ) {
15701        selector = anchor.hash;
15702        panelId = selector.substring( 1 );
15703        panel = that.element.find( that._sanitizeSelector( selector ) );
15704      // remote tab
15705      } else {
15706        // If the tab doesn't already have aria-controls,
15707        // generate an id by using a throw-away element
15708        panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15709        selector = "#" + panelId;
15710        panel = that.element.find( selector );
15711        if ( !panel.length ) {
15712          panel = that._createPanel( panelId );
15713          panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15714        }
15715        panel.attr( "aria-live", "polite" );
15716      }
15717
15718      if ( panel.length) {
15719        that.panels = that.panels.add( panel );
15720      }
15721      if ( originalAriaControls ) {
15722        tab.data( "ui-tabs-aria-controls", originalAriaControls );
15723      }
15724      tab.attr({
15725        "aria-controls": panelId,
15726        "aria-labelledby": anchorId
15727      });
15728      panel.attr( "aria-labelledby", anchorId );
15729    });
15730
15731    this.panels
15732      .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15733      .attr( "role", "tabpanel" );
15734
15735    // Avoid memory leaks (#10056)
15736    if ( prevTabs ) {
15737      this._off( prevTabs.not( this.tabs ) );
15738      this._off( prevAnchors.not( this.anchors ) );
15739      this._off( prevPanels.not( this.panels ) );
15740    }
15741  },
15742
15743  // allow overriding how to find the list for rare usage scenarios (#7715)
15744  _getList: function() {
15745    return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15746  },
15747
15748  _createPanel: function( id ) {
15749    return $( "<div>" )
15750      .attr( "id", id )
15751      .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15752      .data( "ui-tabs-destroy", true );
15753  },
15754
15755  _setupDisabled: function( disabled ) {
15756    if ( $.isArray( disabled ) ) {
15757      if ( !disabled.length ) {
15758        disabled = false;
15759      } else if ( disabled.length === this.anchors.length ) {
15760        disabled = true;
15761      }
15762    }
15763
15764    // disable tabs
15765    for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15766      if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15767        $( li )
15768          .addClass( "ui-state-disabled" )
15769          .attr( "aria-disabled", "true" );
15770      } else {
15771        $( li )
15772          .removeClass( "ui-state-disabled" )
15773          .removeAttr( "aria-disabled" );
15774      }
15775    }
15776
15777    this.options.disabled = disabled;
15778  },
15779
15780  _setupEvents: function( event ) {
15781    var events = {};
15782    if ( event ) {
15783      $.each( event.split(" "), function( index, eventName ) {
15784        events[ eventName ] = "_eventHandler";
15785      });
15786    }
15787
15788    this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15789    // Always prevent the default action, even when disabled
15790    this._on( true, this.anchors, {
15791      click: function( event ) {
15792        event.preventDefault();
15793      }
15794    });
15795    this._on( this.anchors, events );
15796    this._on( this.tabs, { keydown: "_tabKeydown" } );
15797    this._on( this.panels, { keydown: "_panelKeydown" } );
15798
15799    this._focusable( this.tabs );
15800    this._hoverable( this.tabs );
15801  },
15802
15803  _setupHeightStyle: function( heightStyle ) {
15804    var maxHeight,
15805      parent = this.element.parent();
15806
15807    if ( heightStyle === "fill" ) {
15808      maxHeight = parent.height();
15809      maxHeight -= this.element.outerHeight() - this.element.height();
15810
15811      this.element.siblings( ":visible" ).each(function() {
15812        var elem = $( this ),
15813          position = elem.css( "position" );
15814
15815        if ( position === "absolute" || position === "fixed" ) {
15816          return;
15817        }
15818        maxHeight -= elem.outerHeight( true );
15819      });
15820
15821      this.element.children().not( this.panels ).each(function() {
15822        maxHeight -= $( this ).outerHeight( true );
15823      });
15824
15825      this.panels.each(function() {
15826        $( this ).height( Math.max( 0, maxHeight -
15827          $( this ).innerHeight() + $( this ).height() ) );
15828      })
15829      .css( "overflow", "auto" );
15830    } else if ( heightStyle === "auto" ) {
15831      maxHeight = 0;
15832      this.panels.each(function() {
15833        maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15834      }).height( maxHeight );
15835    }
15836  },
15837
15838  _eventHandler: function( event ) {
15839    var options = this.options,
15840      active = this.active,
15841      anchor = $( event.currentTarget ),
15842      tab = anchor.closest( "li" ),
15843      clickedIsActive = tab[ 0 ] === active[ 0 ],
15844      collapsing = clickedIsActive && options.collapsible,
15845      toShow = collapsing ? $() : this._getPanelForTab( tab ),
15846      toHide = !active.length ? $() : this._getPanelForTab( active ),
15847      eventData = {
15848        oldTab: active,
15849        oldPanel: toHide,
15850        newTab: collapsing ? $() : tab,
15851        newPanel: toShow
15852      };
15853
15854    event.preventDefault();
15855
15856    if ( tab.hasClass( "ui-state-disabled" ) ||
15857        // tab is already loading
15858        tab.hasClass( "ui-tabs-loading" ) ||
15859        // can't switch durning an animation
15860        this.running ||
15861        // click on active header, but not collapsible
15862        ( clickedIsActive && !options.collapsible ) ||
15863        // allow canceling activation
15864        ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15865      return;
15866    }
15867
15868    options.active = collapsing ? false : this.tabs.index( tab );
15869
15870    this.active = clickedIsActive ? $() : tab;
15871    if ( this.xhr ) {
15872      this.xhr.abort();
15873    }
15874
15875    if ( !toHide.length && !toShow.length ) {
15876      $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15877    }
15878
15879    if ( toShow.length ) {
15880      this.load( this.tabs.index( tab ), event );
15881    }
15882    this._toggle( event, eventData );
15883  },
15884
15885  // handles show/hide for selecting tabs
15886  _toggle: function( event, eventData ) {
15887    var that = this,
15888      toShow = eventData.newPanel,
15889      toHide = eventData.oldPanel;
15890
15891    this.running = true;
15892
15893    function complete() {
15894      that.running = false;
15895      that._trigger( "activate", event, eventData );
15896    }
15897
15898    function show() {
15899      eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15900
15901      if ( toShow.length && that.options.show ) {
15902        that._show( toShow, that.options.show, complete );
15903      } else {
15904        toShow.show();
15905        complete();
15906      }
15907    }
15908
15909    // start out by hiding, then showing, then completing
15910    if ( toHide.length && this.options.hide ) {
15911      this._hide( toHide, this.options.hide, function() {
15912        eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15913        show();
15914      });
15915    } else {
15916      eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15917      toHide.hide();
15918      show();
15919    }
15920
15921    toHide.attr( "aria-hidden", "true" );
15922    eventData.oldTab.attr({
15923      "aria-selected": "false",
15924      "aria-expanded": "false"
15925    });
15926    // If we're switching tabs, remove the old tab from the tab order.
15927    // If we're opening from collapsed state, remove the previous tab from the tab order.
15928    // If we're collapsing, then keep the collapsing tab in the tab order.
15929    if ( toShow.length && toHide.length ) {
15930      eventData.oldTab.attr( "tabIndex", -1 );
15931    } else if ( toShow.length ) {
15932      this.tabs.filter(function() {
15933        return $( this ).attr( "tabIndex" ) === 0;
15934      })
15935      .attr( "tabIndex", -1 );
15936    }
15937
15938    toShow.attr( "aria-hidden", "false" );
15939    eventData.newTab.attr({
15940      "aria-selected": "true",
15941      "aria-expanded": "true",
15942      tabIndex: 0
15943    });
15944  },
15945
15946  _activate: function( index ) {
15947    var anchor,
15948      active = this._findActive( index );
15949
15950    // trying to activate the already active panel
15951    if ( active[ 0 ] === this.active[ 0 ] ) {
15952      return;
15953    }
15954
15955    // trying to collapse, simulate a click on the current active header
15956    if ( !active.length ) {
15957      active = this.active;
15958    }
15959
15960    anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15961    this._eventHandler({
15962      target: anchor,
15963      currentTarget: anchor,
15964      preventDefault: $.noop
15965    });
15966  },
15967
15968  _findActive: function( index ) {
15969    return index === false ? $() : this.tabs.eq( index );
15970  },
15971
15972  _getIndex: function( index ) {
15973    // meta-function to give users option to provide a href string instead of a numerical index.
15974    if ( typeof index === "string" ) {
15975      index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15976    }
15977
15978    return index;
15979  },
15980
15981  _destroy: function() {
15982    if ( this.xhr ) {
15983      this.xhr.abort();
15984    }
15985
15986    this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15987
15988    this.tablist
15989      .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15990      .removeAttr( "role" );
15991
15992    this.anchors
15993      .removeClass( "ui-tabs-anchor" )
15994      .removeAttr( "role" )
15995      .removeAttr( "tabIndex" )
15996      .removeUniqueId();
15997
15998    this.tablist.unbind( this.eventNamespace );
15999
16000    this.tabs.add( this.panels ).each(function() {
16001      if ( $.data( this, "ui-tabs-destroy" ) ) {
16002        $( this ).remove();
16003      } else {
16004        $( this )
16005          .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
16006            "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
16007          .removeAttr( "tabIndex" )
16008          .removeAttr( "aria-live" )
16009          .removeAttr( "aria-busy" )
16010          .removeAttr( "aria-selected" )
16011          .removeAttr( "aria-labelledby" )
16012          .removeAttr( "aria-hidden" )
16013          .removeAttr( "aria-expanded" )
16014          .removeAttr( "role" );
16015      }
16016    });
16017
16018    this.tabs.each(function() {
16019      var li = $( this ),
16020        prev = li.data( "ui-tabs-aria-controls" );
16021      if ( prev ) {
16022        li
16023          .attr( "aria-controls", prev )
16024          .removeData( "ui-tabs-aria-controls" );
16025      } else {
16026        li.removeAttr( "aria-controls" );
16027      }
16028    });
16029
16030    this.panels.show();
16031
16032    if ( this.options.heightStyle !== "content" ) {
16033      this.panels.css( "height", "" );
16034    }
16035  },
16036
16037  enable: function( index ) {
16038    var disabled = this.options.disabled;
16039    if ( disabled === false ) {
16040      return;
16041    }
16042
16043    if ( index === undefined ) {
16044      disabled = false;
16045    } else {
16046      index = this._getIndex( index );
16047      if ( $.isArray( disabled ) ) {
16048        disabled = $.map( disabled, function( num ) {
16049          return num !== index ? num : null;
16050        });
16051      } else {
16052        disabled = $.map( this.tabs, function( li, num ) {
16053          return num !== index ? num : null;
16054        });
16055      }
16056    }
16057    this._setupDisabled( disabled );
16058  },
16059
16060  disable: function( index ) {
16061    var disabled = this.options.disabled;
16062    if ( disabled === true ) {
16063      return;
16064    }
16065
16066    if ( index === undefined ) {
16067      disabled = true;
16068    } else {
16069      index = this._getIndex( index );
16070      if ( $.inArray( index, disabled ) !== -1 ) {
16071        return;
16072      }
16073      if ( $.isArray( disabled ) ) {
16074        disabled = $.merge( [ index ], disabled ).sort();
16075      } else {
16076        disabled = [ index ];
16077      }
16078    }
16079    this._setupDisabled( disabled );
16080  },
16081
16082  load: function( index, event ) {
16083    index = this._getIndex( index );
16084    var that = this,
16085      tab = this.tabs.eq( index ),
16086      anchor = tab.find( ".ui-tabs-anchor" ),
16087      panel = this._getPanelForTab( tab ),
16088      eventData = {
16089        tab: tab,
16090        panel: panel
16091      },
16092      complete = function( jqXHR, status ) {
16093        if ( status === "abort" ) {
16094          that.panels.stop( false, true );
16095        }
16096
16097        tab.removeClass( "ui-tabs-loading" );
16098        panel.removeAttr( "aria-busy" );
16099
16100        if ( jqXHR === that.xhr ) {
16101          delete that.xhr;
16102        }
16103      };
16104
16105    // not remote
16106    if ( this._isLocal( anchor[ 0 ] ) ) {
16107      return;
16108    }
16109
16110    this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
16111
16112    // support: jQuery <1.8
16113    // jQuery <1.8 returns false if the request is canceled in beforeSend,
16114    // but as of 1.8, $.ajax() always returns a jqXHR object.
16115    if ( this.xhr && this.xhr.statusText !== "canceled" ) {
16116      tab.addClass( "ui-tabs-loading" );
16117      panel.attr( "aria-busy", "true" );
16118
16119      this.xhr
16120        .done(function( response, status, jqXHR ) {
16121          // support: jQuery <1.8
16122          // http://bugs.jquery.com/ticket/11778
16123          setTimeout(function() {
16124            panel.html( response );
16125            that._trigger( "load", event, eventData );
16126
16127            complete( jqXHR, status );
16128          }, 1 );
16129        })
16130        .fail(function( jqXHR, status ) {
16131          // support: jQuery <1.8
16132          // http://bugs.jquery.com/ticket/11778
16133          setTimeout(function() {
16134            complete( jqXHR, status );
16135          }, 1 );
16136        });
16137    }
16138  },
16139
16140  _ajaxSettings: function( anchor, event, eventData ) {
16141    var that = this;
16142    return {
16143      url: anchor.attr( "href" ),
16144      beforeSend: function( jqXHR, settings ) {
16145        return that._trigger( "beforeLoad", event,
16146          $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
16147      }
16148    };
16149  },
16150
16151  _getPanelForTab: function( tab ) {
16152    var id = $( tab ).attr( "aria-controls" );
16153    return this.element.find( this._sanitizeSelector( "#" + id ) );
16154  }
16155});
16156
16157
16158/*!
16159 * jQuery UI Tooltip 1.11.4
16160 * http://jqueryui.com
16161 *
16162 * Copyright jQuery Foundation and other contributors
16163 * Released under the MIT license.
16164 * http://jquery.org/license
16165 *
16166 * http://api.jqueryui.com/tooltip/
16167 */
16168
16169
16170var tooltip = $.widget( "ui.tooltip", {
16171  version: "1.11.4",
16172  options: {
16173    content: function() {
16174      // support: IE<9, Opera in jQuery <1.7
16175      // .text() can't accept undefined, so coerce to a string
16176      var title = $( this ).attr( "title" ) || "";
16177      // Escape title, since we're going from an attribute to raw HTML
16178      return $( "<a>" ).text( title ).html();
16179    },
16180    hide: true,
16181    // Disabled elements have inconsistent behavior across browsers (#8661)
16182    items: "[title]:not([disabled])",
16183    position: {
16184      my: "left top+15",
16185      at: "left bottom",
16186      collision: "flipfit flip"
16187    },
16188    show: true,
16189    tooltipClass: null,
16190    track: false,
16191
16192    // callbacks
16193    close: null,
16194    open: null
16195  },
16196
16197  _addDescribedBy: function( elem, id ) {
16198    var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
16199    describedby.push( id );
16200    elem
16201      .data( "ui-tooltip-id", id )
16202      .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
16203  },
16204
16205  _removeDescribedBy: function( elem ) {
16206    var id = elem.data( "ui-tooltip-id" ),
16207      describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
16208      index = $.inArray( id, describedby );
16209
16210    if ( index !== -1 ) {
16211      describedby.splice( index, 1 );
16212    }
16213
16214    elem.removeData( "ui-tooltip-id" );
16215    describedby = $.trim( describedby.join( " " ) );
16216    if ( describedby ) {
16217      elem.attr( "aria-describedby", describedby );
16218    } else {
16219      elem.removeAttr( "aria-describedby" );
16220    }
16221  },
16222
16223  _create: function() {
16224    this._on({
16225      mouseover: "open",
16226      focusin: "open"
16227    });
16228
16229    // IDs of generated tooltips, needed for destroy
16230    this.tooltips = {};
16231
16232    // IDs of parent tooltips where we removed the title attribute
16233    this.parents = {};
16234
16235    if ( this.options.disabled ) {
16236      this._disable();
16237    }
16238
16239    // Append the aria-live region so tooltips announce correctly
16240    this.liveRegion = $( "<div>" )
16241      .attr({
16242        role: "log",
16243        "aria-live": "assertive",
16244        "aria-relevant": "additions"
16245      })
16246      .addClass( "ui-helper-hidden-accessible" )
16247      .appendTo( this.document[ 0 ].body );
16248  },
16249
16250  _setOption: function( key, value ) {
16251    var that = this;
16252
16253    if ( key === "disabled" ) {
16254      this[ value ? "_disable" : "_enable" ]();
16255      this.options[ key ] = value;
16256      // disable element style changes
16257      return;
16258    }
16259
16260    this._super( key, value );
16261
16262    if ( key === "content" ) {
16263      $.each( this.tooltips, function( id, tooltipData ) {
16264        that._updateContent( tooltipData.element );
16265      });
16266    }
16267  },
16268
16269  _disable: function() {
16270    var that = this;
16271
16272    // close open tooltips
16273    $.each( this.tooltips, function( id, tooltipData ) {
16274      var event = $.Event( "blur" );
16275      event.target = event.currentTarget = tooltipData.element[ 0 ];
16276      that.close( event, true );
16277    });
16278
16279    // remove title attributes to prevent native tooltips
16280    this.element.find( this.options.items ).addBack().each(function() {
16281      var element = $( this );
16282      if ( element.is( "[title]" ) ) {
16283        element
16284          .data( "ui-tooltip-title", element.attr( "title" ) )
16285          .removeAttr( "title" );
16286      }
16287    });
16288  },
16289
16290  _enable: function() {
16291    // restore title attributes
16292    this.element.find( this.options.items ).addBack().each(function() {
16293      var element = $( this );
16294      if ( element.data( "ui-tooltip-title" ) ) {
16295        element.attr( "title", element.data( "ui-tooltip-title" ) );
16296      }
16297    });
16298  },
16299
16300  open: function( event ) {
16301    var that = this,
16302      target = $( event ? event.target : this.element )
16303        // we need closest here due to mouseover bubbling,
16304        // but always pointing at the same event target
16305        .closest( this.options.items );
16306
16307    // No element to show a tooltip for or the tooltip is already open
16308    if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16309      return;
16310    }
16311
16312    if ( target.attr( "title" ) ) {
16313      target.data( "ui-tooltip-title", target.attr( "title" ) );
16314    }
16315
16316    target.data( "ui-tooltip-open", true );
16317
16318    // kill parent tooltips, custom or native, for hover
16319    if ( event && event.type === "mouseover" ) {
16320      target.parents().each(function() {
16321        var parent = $( this ),
16322          blurEvent;
16323        if ( parent.data( "ui-tooltip-open" ) ) {
16324          blurEvent = $.Event( "blur" );
16325          blurEvent.target = blurEvent.currentTarget = this;
16326          that.close( blurEvent, true );
16327        }
16328        if ( parent.attr( "title" ) ) {
16329          parent.uniqueId();
16330          that.parents[ this.id ] = {
16331            element: this,
16332            title: parent.attr( "title" )
16333          };
16334          parent.attr( "title", "" );
16335        }
16336      });
16337    }
16338
16339    this._registerCloseHandlers( event, target );
16340    this._updateContent( target, event );
16341  },
16342
16343  _updateContent: function( target, event ) {
16344    var content,
16345      contentOption = this.options.content,
16346      that = this,
16347      eventType = event ? event.type : null;
16348
16349    if ( typeof contentOption === "string" ) {
16350      return this._open( event, target, contentOption );
16351    }
16352
16353    content = contentOption.call( target[0], function( response ) {
16354
16355      // IE may instantly serve a cached response for ajax requests
16356      // delay this call to _open so the other call to _open runs first
16357      that._delay(function() {
16358
16359        // Ignore async response if tooltip was closed already
16360        if ( !target.data( "ui-tooltip-open" ) ) {
16361          return;
16362        }
16363
16364        // jQuery creates a special event for focusin when it doesn't
16365        // exist natively. To improve performance, the native event
16366        // object is reused and the type is changed. Therefore, we can't
16367        // rely on the type being correct after the event finished
16368        // bubbling, so we set it back to the previous value. (#8740)
16369        if ( event ) {
16370          event.type = eventType;
16371        }
16372        this._open( event, target, response );
16373      });
16374    });
16375    if ( content ) {
16376      this._open( event, target, content );
16377    }
16378  },
16379
16380  _open: function( event, target, content ) {
16381    var tooltipData, tooltip, delayedShow, a11yContent,
16382      positionOption = $.extend( {}, this.options.position );
16383
16384    if ( !content ) {
16385      return;
16386    }
16387
16388    // Content can be updated multiple times. If the tooltip already
16389    // exists, then just update the content and bail.
16390    tooltipData = this._find( target );
16391    if ( tooltipData ) {
16392      tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
16393      return;
16394    }
16395
16396    // if we have a title, clear it to prevent the native tooltip
16397    // we have to check first to avoid defining a title if none exists
16398    // (we don't want to cause an element to start matching [title])
16399    //
16400    // We use removeAttr only for key events, to allow IE to export the correct
16401    // accessible attributes. For mouse events, set to empty string to avoid
16402    // native tooltip showing up (happens only when removing inside mouseover).
16403    if ( target.is( "[title]" ) ) {
16404      if ( event && event.type === "mouseover" ) {
16405        target.attr( "title", "" );
16406      } else {
16407        target.removeAttr( "title" );
16408      }
16409    }
16410
16411    tooltipData = this._tooltip( target );
16412    tooltip = tooltipData.tooltip;
16413    this._addDescribedBy( target, tooltip.attr( "id" ) );
16414    tooltip.find( ".ui-tooltip-content" ).html( content );
16415
16416    // Support: Voiceover on OS X, JAWS on IE <= 9
16417    // JAWS announces deletions even when aria-relevant="additions"
16418    // Voiceover will sometimes re-read the entire log region's contents from the beginning
16419    this.liveRegion.children().hide();
16420    if ( content.clone ) {
16421      a11yContent = content.clone();
16422      a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16423    } else {
16424      a11yContent = content;
16425    }
16426    $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16427
16428    function position( event ) {
16429      positionOption.of = event;
16430      if ( tooltip.is( ":hidden" ) ) {
16431        return;
16432      }
16433      tooltip.position( positionOption );
16434    }
16435    if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16436      this._on( this.document, {
16437        mousemove: position
16438      });
16439      // trigger once to override element-relative positioning
16440      position( event );
16441    } else {
16442      tooltip.position( $.extend({
16443        of: target
16444      }, this.options.position ) );
16445    }
16446
16447    tooltip.hide();
16448
16449    this._show( tooltip, this.options.show );
16450    // Handle tracking tooltips that are shown with a delay (#8644). As soon
16451    // as the tooltip is visible, position the tooltip using the most recent
16452    // event.
16453    if ( this.options.show && this.options.show.delay ) {
16454      delayedShow = this.delayedShow = setInterval(function() {
16455        if ( tooltip.is( ":visible" ) ) {
16456          position( positionOption.of );
16457          clearInterval( delayedShow );
16458        }
16459      }, $.fx.interval );
16460    }
16461
16462    this._trigger( "open", event, { tooltip: tooltip } );
16463  },
16464
16465  _registerCloseHandlers: function( event, target ) {
16466    var events = {
16467      keyup: function( event ) {
16468        if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16469          var fakeEvent = $.Event(event);
16470          fakeEvent.currentTarget = target[0];
16471          this.close( fakeEvent, true );
16472        }
16473      }
16474    };
16475
16476    // Only bind remove handler for delegated targets. Non-delegated
16477    // tooltips will handle this in destroy.
16478    if ( target[ 0 ] !== this.element[ 0 ] ) {
16479      events.remove = function() {
16480        this._removeTooltip( this._find( target ).tooltip );
16481      };
16482    }
16483
16484    if ( !event || event.type === "mouseover" ) {
16485      events.mouseleave = "close";
16486    }
16487    if ( !event || event.type === "focusin" ) {
16488      events.focusout = "close";
16489    }
16490    this._on( true, target, events );
16491  },
16492
16493  close: function( event ) {
16494    var tooltip,
16495      that = this,
16496      target = $( event ? event.currentTarget : this.element ),
16497      tooltipData = this._find( target );
16498
16499    // The tooltip may already be closed
16500    if ( !tooltipData ) {
16501
16502      // We set ui-tooltip-open immediately upon open (in open()), but only set the
16503      // additional data once there's actually content to show (in _open()). So even if the
16504      // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
16505      // the period between open() and _open().
16506      target.removeData( "ui-tooltip-open" );
16507      return;
16508    }
16509
16510    tooltip = tooltipData.tooltip;
16511
16512    // disabling closes the tooltip, so we need to track when we're closing
16513    // to avoid an infinite loop in case the tooltip becomes disabled on close
16514    if ( tooltipData.closing ) {
16515      return;
16516    }
16517
16518    // Clear the interval for delayed tracking tooltips
16519    clearInterval( this.delayedShow );
16520
16521    // only set title if we had one before (see comment in _open())
16522    // If the title attribute has changed since open(), don't restore
16523    if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16524      target.attr( "title", target.data( "ui-tooltip-title" ) );
16525    }
16526
16527    this._removeDescribedBy( target );
16528
16529    tooltipData.hiding = true;
16530    tooltip.stop( true );
16531    this._hide( tooltip, this.options.hide, function() {
16532      that._removeTooltip( $( this ) );
16533    });
16534
16535    target.removeData( "ui-tooltip-open" );
16536    this._off( target, "mouseleave focusout keyup" );
16537
16538    // Remove 'remove' binding only on delegated targets
16539    if ( target[ 0 ] !== this.element[ 0 ] ) {
16540      this._off( target, "remove" );
16541    }
16542    this._off( this.document, "mousemove" );
16543
16544    if ( event && event.type === "mouseleave" ) {
16545      $.each( this.parents, function( id, parent ) {
16546        $( parent.element ).attr( "title", parent.title );
16547        delete that.parents[ id ];
16548      });
16549    }
16550
16551    tooltipData.closing = true;
16552    this._trigger( "close", event, { tooltip: tooltip } );
16553    if ( !tooltipData.hiding ) {
16554      tooltipData.closing = false;
16555    }
16556  },
16557
16558  _tooltip: function( element ) {
16559    var tooltip = $( "<div>" )
16560        .attr( "role", "tooltip" )
16561        .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16562          ( this.options.tooltipClass || "" ) ),
16563      id = tooltip.uniqueId().attr( "id" );
16564
16565    $( "<div>" )
16566      .addClass( "ui-tooltip-content" )
16567      .appendTo( tooltip );
16568
16569    tooltip.appendTo( this.document[0].body );
16570
16571    return this.tooltips[ id ] = {
16572      element: element,
16573      tooltip: tooltip
16574    };
16575  },
16576
16577  _find: function( target ) {
16578    var id = target.data( "ui-tooltip-id" );
16579    return id ? this.tooltips[ id ] : null;
16580  },
16581
16582  _removeTooltip: function( tooltip ) {
16583    tooltip.remove();
16584    delete this.tooltips[ tooltip.attr( "id" ) ];
16585  },
16586
16587  _destroy: function() {
16588    var that = this;
16589
16590    // close open tooltips
16591    $.each( this.tooltips, function( id, tooltipData ) {
16592      // Delegate to close method to handle common cleanup
16593      var event = $.Event( "blur" ),
16594        element = tooltipData.element;
16595      event.target = event.currentTarget = element[ 0 ];
16596      that.close( event, true );
16597
16598      // Remove immediately; destroying an open tooltip doesn't use the
16599      // hide animation
16600      $( "#" + id ).remove();
16601
16602      // Restore the title
16603      if ( element.data( "ui-tooltip-title" ) ) {
16604        // If the title attribute has changed since open(), don't restore
16605        if ( !element.attr( "title" ) ) {
16606          element.attr( "title", element.data( "ui-tooltip-title" ) );
16607        }
16608        element.removeData( "ui-tooltip-title" );
16609      }
16610    });
16611    this.liveRegion.remove();
16612  }
16613});
16614
16615
16616
16617}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.