[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/jquery/ui-1.11.4/ -> jquery-ui.js (source)

   1  /*! jQuery UI - v1.11.4 - 2015-03-15
   2  * http://jqueryui.com
   3  * Includes: core.js, widget.js, mouse.js, position.js, draggable.js, droppable.js, resizable.js, selectable.js, sortable.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, menu.js, progressbar.js, selectmenu.js, slider.js, spinner.js, tabs.js, tooltip.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js
   4  * Copyright 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
  94  function 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  
 115  function 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
 146  if ( !$( "<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
 193  if ( !$.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)
 202  if ( $( "<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  
 323  var 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          });
 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  
 856  var 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  
 871  var mouseHandled = false;
 872  $( document ).mouseup( function() {
 873      mouseHandled = false;
 874  });
 875  
 876  var 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
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  
1060  var 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  
1071  function 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  
1078  function parseCss( element, property ) {
1079      return parseInt( $.css( element, property ), 10 ) || 0;
1080  }
1081  
1082  function 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  
1549  var position = $.ui.position;
1550  
1551  
1552  /*!
1553   * jQuery UI Draggable 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/draggable/
1561   */
1562  
1563  
1564  $.widget("ui.draggable", $.ui.mouse, {
1565      version: "1.11.4",
1566      widgetEventPrefix: "drag",
1567      options: {
1568          addClasses: true,
1569          appendTo: "parent",
1570          axis: false,
1571          connectToSortable: false,
1572          containment: false,
1573          cursor: "auto",
1574          cursorAt: false,
1575          grid: false,
1576          handle: false,
1577          helper: "original",
1578          iframeFix: false,
1579          opacity: false,
1580          refreshPositions: false,
1581          revert: false,
1582          revertDuration: 500,
1583          scope: "default",
1584          scroll: true,
1585          scrollSensitivity: 20,
1586          scrollSpeed: 20,
1587          snap: false,
1588          snapMode: "both",
1589          snapTolerance: 20,
1590          stack: false,
1591          zIndex: false,
1592  
1593          // callbacks
1594          drag: null,
1595          start: null,
1596          stop: null
1597      },
1598      _create: function() {
1599  
1600          if ( this.options.helper === "original" ) {
1601              this._setPositionRelative();
1602          }
1603          if (this.options.addClasses){
1604              this.element.addClass("ui-draggable");
1605          }
1606          if (this.options.disabled){
1607              this.element.addClass("ui-draggable-disabled");
1608          }
1609          this._setHandleClassName();
1610  
1611          this._mouseInit();
1612      },
1613  
1614      _setOption: function( key, value ) {
1615          this._super( key, value );
1616          if ( key === "handle" ) {
1617              this._removeHandleClassName();
1618              this._setHandleClassName();
1619          }
1620      },
1621  
1622      _destroy: function() {
1623          if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1624              this.destroyOnClear = true;
1625              return;
1626          }
1627          this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1628          this._removeHandleClassName();
1629          this._mouseDestroy();
1630      },
1631  
1632      _mouseCapture: function(event) {
1633          var o = this.options;
1634  
1635          this._blurActiveElement( event );
1636  
1637          // among others, prevent a drag on a resizable-handle
1638          if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1639              return false;
1640          }
1641  
1642          //Quit if we're not on a valid handle
1643          this.handle = this._getHandle(event);
1644          if (!this.handle) {
1645              return false;
1646          }
1647  
1648          this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1649  
1650          return true;
1651  
1652      },
1653  
1654      _blockFrames: function( selector ) {
1655          this.iframeBlocks = this.document.find( selector ).map(function() {
1656              var iframe = $( this );
1657  
1658              return $( "<div>" )
1659                  .css( "position", "absolute" )
1660                  .appendTo( iframe.parent() )
1661                  .outerWidth( iframe.outerWidth() )
1662                  .outerHeight( iframe.outerHeight() )
1663                  .offset( iframe.offset() )[ 0 ];
1664          });
1665      },
1666  
1667      _unblockFrames: function() {
1668          if ( this.iframeBlocks ) {
1669              this.iframeBlocks.remove();
1670              delete this.iframeBlocks;
1671          }
1672      },
1673  
1674      _blurActiveElement: function( event ) {
1675          var document = this.document[ 0 ];
1676  
1677          // Only need to blur if the event occurred on the draggable itself, see #10527
1678          if ( !this.handleElement.is( event.target ) ) {
1679              return;
1680          }
1681  
1682          // support: IE9
1683          // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1684          try {
1685  
1686              // Support: IE9, IE10
1687              // If the <body> is blurred, IE will switch windows, see #9520
1688              if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
1689  
1690                  // Blur any element that currently has focus, see #4261
1691                  $( document.activeElement ).blur();
1692              }
1693          } catch ( error ) {}
1694      },
1695  
1696      _mouseStart: function(event) {
1697  
1698          var o = this.options;
1699  
1700          //Create and append the visible helper
1701          this.helper = this._createHelper(event);
1702  
1703          this.helper.addClass("ui-draggable-dragging");
1704  
1705          //Cache the helper size
1706          this._cacheHelperProportions();
1707  
1708          //If ddmanager is used for droppables, set the global draggable
1709          if ($.ui.ddmanager) {
1710              $.ui.ddmanager.current = this;
1711          }
1712  
1713          /*
1714           * - Position generation -
1715           * This block generates everything position related - it's the core of draggables.
1716           */
1717  
1718          //Cache the margins of the original element
1719          this._cacheMargins();
1720  
1721          //Store the helper's css position
1722          this.cssPosition = this.helper.css( "position" );
1723          this.scrollParent = this.helper.scrollParent( true );
1724          this.offsetParent = this.helper.offsetParent();
1725          this.hasFixedAncestor = this.helper.parents().filter(function() {
1726                  return $( this ).css( "position" ) === "fixed";
1727              }).length > 0;
1728  
1729          //The element's absolute position on the page minus margins
1730          this.positionAbs = this.element.offset();
1731          this._refreshOffsets( event );
1732  
1733          //Generate the original position
1734          this.originalPosition = this.position = this._generatePosition( event, false );
1735          this.originalPageX = event.pageX;
1736          this.originalPageY = event.pageY;
1737  
1738          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1739          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1740  
1741          //Set a containment if given in the options
1742          this._setContainment();
1743  
1744          //Trigger event + callbacks
1745          if (this._trigger("start", event) === false) {
1746              this._clear();
1747              return false;
1748          }
1749  
1750          //Recache the helper size
1751          this._cacheHelperProportions();
1752  
1753          //Prepare the droppable offsets
1754          if ($.ui.ddmanager && !o.dropBehaviour) {
1755              $.ui.ddmanager.prepareOffsets(this, event);
1756          }
1757  
1758          // Reset helper's right/bottom css if they're set and set explicit width/height instead
1759          // as this prevents resizing of elements with right/bottom set (see #7772)
1760          this._normalizeRightBottom();
1761  
1762          this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1763  
1764          //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1765          if ( $.ui.ddmanager ) {
1766              $.ui.ddmanager.dragStart(this, event);
1767          }
1768  
1769          return true;
1770      },
1771  
1772      _refreshOffsets: function( event ) {
1773          this.offset = {
1774              top: this.positionAbs.top - this.margins.top,
1775              left: this.positionAbs.left - this.margins.left,
1776              scroll: false,
1777              parent: this._getParentOffset(),
1778              relative: this._getRelativeOffset()
1779          };
1780  
1781          this.offset.click = {
1782              left: event.pageX - this.offset.left,
1783              top: event.pageY - this.offset.top
1784          };
1785      },
1786  
1787      _mouseDrag: function(event, noPropagation) {
1788          // reset any necessary cached properties (see #5009)
1789          if ( this.hasFixedAncestor ) {
1790              this.offset.parent = this._getParentOffset();
1791          }
1792  
1793          //Compute the helpers position
1794          this.position = this._generatePosition( event, true );
1795          this.positionAbs = this._convertPositionTo("absolute");
1796  
1797          //Call plugins and callbacks and use the resulting position if something is returned
1798          if (!noPropagation) {
1799              var ui = this._uiHash();
1800              if (this._trigger("drag", event, ui) === false) {
1801                  this._mouseUp({});
1802                  return false;
1803              }
1804              this.position = ui.position;
1805          }
1806  
1807          this.helper[ 0 ].style.left = this.position.left + "px";
1808          this.helper[ 0 ].style.top = this.position.top + "px";
1809  
1810          if ($.ui.ddmanager) {
1811              $.ui.ddmanager.drag(this, event);
1812          }
1813  
1814          return false;
1815      },
1816  
1817      _mouseStop: function(event) {
1818  
1819          //If we are using droppables, inform the manager about the drop
1820          var that = this,
1821              dropped = false;
1822          if ($.ui.ddmanager && !this.options.dropBehaviour) {
1823              dropped = $.ui.ddmanager.drop(this, event);
1824          }
1825  
1826          //if a drop comes from outside (a sortable)
1827          if (this.dropped) {
1828              dropped = this.dropped;
1829              this.dropped = false;
1830          }
1831  
1832          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))) {
1833              $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1834                  if (that._trigger("stop", event) !== false) {
1835                      that._clear();
1836                  }
1837              });
1838          } else {
1839              if (this._trigger("stop", event) !== false) {
1840                  this._clear();
1841              }
1842          }
1843  
1844          return false;
1845      },
1846  
1847      _mouseUp: function( event ) {
1848          this._unblockFrames();
1849  
1850          //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1851          if ( $.ui.ddmanager ) {
1852              $.ui.ddmanager.dragStop(this, event);
1853          }
1854  
1855          // Only need to focus if the event occurred on the draggable itself, see #10527
1856          if ( this.handleElement.is( event.target ) ) {
1857              // The interaction is over; whether or not the click resulted in a drag, focus the element
1858              this.element.focus();
1859          }
1860  
1861          return $.ui.mouse.prototype._mouseUp.call(this, event);
1862      },
1863  
1864      cancel: function() {
1865  
1866          if (this.helper.is(".ui-draggable-dragging")) {
1867              this._mouseUp({});
1868          } else {
1869              this._clear();
1870          }
1871  
1872          return this;
1873  
1874      },
1875  
1876      _getHandle: function(event) {
1877          return this.options.handle ?
1878              !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1879              true;
1880      },
1881  
1882      _setHandleClassName: function() {
1883          this.handleElement = this.options.handle ?
1884              this.element.find( this.options.handle ) : this.element;
1885          this.handleElement.addClass( "ui-draggable-handle" );
1886      },
1887  
1888      _removeHandleClassName: function() {
1889          this.handleElement.removeClass( "ui-draggable-handle" );
1890      },
1891  
1892      _createHelper: function(event) {
1893  
1894          var o = this.options,
1895              helperIsFunction = $.isFunction( o.helper ),
1896              helper = helperIsFunction ?
1897                  $( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1898                  ( o.helper === "clone" ?
1899                      this.element.clone().removeAttr( "id" ) :
1900                      this.element );
1901  
1902          if (!helper.parents("body").length) {
1903              helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1904          }
1905  
1906          // http://bugs.jqueryui.com/ticket/9446
1907          // a helper function can return the original element
1908          // which wouldn't have been set to relative in _create
1909          if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1910              this._setPositionRelative();
1911          }
1912  
1913          if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1914              helper.css("position", "absolute");
1915          }
1916  
1917          return helper;
1918  
1919      },
1920  
1921      _setPositionRelative: function() {
1922          if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1923              this.element[ 0 ].style.position = "relative";
1924          }
1925      },
1926  
1927      _adjustOffsetFromHelper: function(obj) {
1928          if (typeof obj === "string") {
1929              obj = obj.split(" ");
1930          }
1931          if ($.isArray(obj)) {
1932              obj = { left: +obj[0], top: +obj[1] || 0 };
1933          }
1934          if ("left" in obj) {
1935              this.offset.click.left = obj.left + this.margins.left;
1936          }
1937          if ("right" in obj) {
1938              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1939          }
1940          if ("top" in obj) {
1941              this.offset.click.top = obj.top + this.margins.top;
1942          }
1943          if ("bottom" in obj) {
1944              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1945          }
1946      },
1947  
1948      _isRootNode: function( element ) {
1949          return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1950      },
1951  
1952      _getParentOffset: function() {
1953  
1954          //Get the offsetParent and cache its position
1955          var po = this.offsetParent.offset(),
1956              document = this.document[ 0 ];
1957  
1958          // This is a special case where we need to modify a offset calculated on start, since the following happened:
1959          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1960          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1961          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1962          if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1963              po.left += this.scrollParent.scrollLeft();
1964              po.top += this.scrollParent.scrollTop();
1965          }
1966  
1967          if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1968              po = { top: 0, left: 0 };
1969          }
1970  
1971          return {
1972              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
1973              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
1974          };
1975  
1976      },
1977  
1978      _getRelativeOffset: function() {
1979          if ( this.cssPosition !== "relative" ) {
1980              return { top: 0, left: 0 };
1981          }
1982  
1983          var p = this.element.position(),
1984              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1985  
1986          return {
1987              top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1988              left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1989          };
1990  
1991      },
1992  
1993      _cacheMargins: function() {
1994          this.margins = {
1995              left: (parseInt(this.element.css("marginLeft"), 10) || 0),
1996              top: (parseInt(this.element.css("marginTop"), 10) || 0),
1997              right: (parseInt(this.element.css("marginRight"), 10) || 0),
1998              bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
1999          };
2000      },
2001  
2002      _cacheHelperProportions: function() {
2003          this.helperProportions = {
2004              width: this.helper.outerWidth(),
2005              height: this.helper.outerHeight()
2006          };
2007      },
2008  
2009      _setContainment: function() {
2010  
2011          var isUserScrollable, c, ce,
2012              o = this.options,
2013              document = this.document[ 0 ];
2014  
2015          this.relativeContainer = null;
2016  
2017          if ( !o.containment ) {
2018              this.containment = null;
2019              return;
2020          }
2021  
2022          if ( o.containment === "window" ) {
2023              this.containment = [
2024                  $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
2025                  $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
2026                  $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
2027                  $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2028              ];
2029              return;
2030          }
2031  
2032          if ( o.containment === "document") {
2033              this.containment = [
2034                  0,
2035                  0,
2036                  $( document ).width() - this.helperProportions.width - this.margins.left,
2037                  ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
2038              ];
2039              return;
2040          }
2041  
2042          if ( o.containment.constructor === Array ) {
2043              this.containment = o.containment;
2044              return;
2045          }
2046  
2047          if ( o.containment === "parent" ) {
2048              o.containment = this.helper[ 0 ].parentNode;
2049          }
2050  
2051          c = $( o.containment );
2052          ce = c[ 0 ];
2053  
2054          if ( !ce ) {
2055              return;
2056          }
2057  
2058          isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
2059  
2060          this.containment = [
2061              ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
2062              ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
2063              ( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
2064                  ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
2065                  ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
2066                  this.helperProportions.width -
2067                  this.margins.left -
2068                  this.margins.right,
2069              ( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
2070                  ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
2071                  ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
2072                  this.helperProportions.height -
2073                  this.margins.top -
2074                  this.margins.bottom
2075          ];
2076          this.relativeContainer = c;
2077      },
2078  
2079      _convertPositionTo: function(d, pos) {
2080  
2081          if (!pos) {
2082              pos = this.position;
2083          }
2084  
2085          var mod = d === "absolute" ? 1 : -1,
2086              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
2087  
2088          return {
2089              top: (
2090                  pos.top    +                                                                // The absolute mouse position
2091                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
2092                  this.offset.parent.top * mod -                                        // The offsetParent's offset without borders (offset + border)
2093                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
2094              ),
2095              left: (
2096                  pos.left +                                                                // The absolute mouse position
2097                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
2098                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
2099                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
2100              )
2101          };
2102  
2103      },
2104  
2105      _generatePosition: function( event, constrainPosition ) {
2106  
2107          var containment, co, top, left,
2108              o = this.options,
2109              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
2110              pageX = event.pageX,
2111              pageY = event.pageY;
2112  
2113          // Cache the scroll
2114          if ( !scrollIsRootNode || !this.offset.scroll ) {
2115              this.offset.scroll = {
2116                  top: this.scrollParent.scrollTop(),
2117                  left: this.scrollParent.scrollLeft()
2118              };
2119          }
2120  
2121          /*
2122           * - Position constraining -
2123           * Constrain the position to a mix of grid, containment.
2124           */
2125  
2126          // If we are not dragging yet, we won't check for options
2127          if ( constrainPosition ) {
2128              if ( this.containment ) {
2129                  if ( this.relativeContainer ){
2130                      co = this.relativeContainer.offset();
2131                      containment = [
2132                          this.containment[ 0 ] + co.left,
2133                          this.containment[ 1 ] + co.top,
2134                          this.containment[ 2 ] + co.left,
2135                          this.containment[ 3 ] + co.top
2136                      ];
2137                  } else {
2138                      containment = this.containment;
2139                  }
2140  
2141                  if (event.pageX - this.offset.click.left < containment[0]) {
2142                      pageX = containment[0] + this.offset.click.left;
2143                  }
2144                  if (event.pageY - this.offset.click.top < containment[1]) {
2145                      pageY = containment[1] + this.offset.click.top;
2146                  }
2147                  if (event.pageX - this.offset.click.left > containment[2]) {
2148                      pageX = containment[2] + this.offset.click.left;
2149                  }
2150                  if (event.pageY - this.offset.click.top > containment[3]) {
2151                      pageY = containment[3] + this.offset.click.top;
2152                  }
2153              }
2154  
2155              if (o.grid) {
2156                  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
2157                  top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
2158                  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;
2159  
2160                  left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
2161                  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;
2162              }
2163  
2164              if ( o.axis === "y" ) {
2165                  pageX = this.originalPageX;
2166              }
2167  
2168              if ( o.axis === "x" ) {
2169                  pageY = this.originalPageY;
2170              }
2171          }
2172  
2173          return {
2174              top: (
2175                  pageY -                                                                    // The absolute mouse position
2176                  this.offset.click.top    -                                                // Click offset (relative to the element)
2177                  this.offset.relative.top -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2178                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
2179                  ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
2180              ),
2181              left: (
2182                  pageX -                                                                    // The absolute mouse position
2183                  this.offset.click.left -                                                // Click offset (relative to the element)
2184                  this.offset.relative.left -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
2185                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
2186                  ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
2187              )
2188          };
2189  
2190      },
2191  
2192      _clear: function() {
2193          this.helper.removeClass("ui-draggable-dragging");
2194          if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2195              this.helper.remove();
2196          }
2197          this.helper = null;
2198          this.cancelHelperRemoval = false;
2199          if ( this.destroyOnClear ) {
2200              this.destroy();
2201          }
2202      },
2203  
2204      _normalizeRightBottom: function() {
2205          if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
2206              this.helper.width( this.helper.width() );
2207              this.helper.css( "right", "auto" );
2208          }
2209          if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
2210              this.helper.height( this.helper.height() );
2211              this.helper.css( "bottom", "auto" );
2212          }
2213      },
2214  
2215      // From now on bulk stuff - mainly helpers
2216  
2217      _trigger: function( type, event, ui ) {
2218          ui = ui || this._uiHash();
2219          $.ui.plugin.call( this, type, [ event, ui, this ], true );
2220  
2221          // Absolute position and offset (see #6884 ) have to be recalculated after plugins
2222          if ( /^(drag|start|stop)/.test( type ) ) {
2223              this.positionAbs = this._convertPositionTo( "absolute" );
2224              ui.offset = this.positionAbs;
2225          }
2226          return $.Widget.prototype._trigger.call( this, type, event, ui );
2227      },
2228  
2229      plugins: {},
2230  
2231      _uiHash: function() {
2232          return {
2233              helper: this.helper,
2234              position: this.position,
2235              originalPosition: this.originalPosition,
2236              offset: this.positionAbs
2237          };
2238      }
2239  
2240  });
2241  
2242  $.ui.plugin.add( "draggable", "connectToSortable", {
2243      start: function( event, ui, draggable ) {
2244          var uiSortable = $.extend( {}, ui, {
2245              item: draggable.element
2246          });
2247  
2248          draggable.sortables = [];
2249          $( draggable.options.connectToSortable ).each(function() {
2250              var sortable = $( this ).sortable( "instance" );
2251  
2252              if ( sortable && !sortable.options.disabled ) {
2253                  draggable.sortables.push( sortable );
2254  
2255                  // refreshPositions is called at drag start to refresh the containerCache
2256                  // which is used in drag. This ensures it's initialized and synchronized
2257                  // with any changes that might have happened on the page since initialization.
2258                  sortable.refreshPositions();
2259                  sortable._trigger("activate", event, uiSortable);
2260              }
2261          });
2262      },
2263      stop: function( event, ui, draggable ) {
2264          var uiSortable = $.extend( {}, ui, {
2265              item: draggable.element
2266          });
2267  
2268          draggable.cancelHelperRemoval = false;
2269  
2270          $.each( draggable.sortables, function() {
2271              var sortable = this;
2272  
2273              if ( sortable.isOver ) {
2274                  sortable.isOver = 0;
2275  
2276                  // Allow this sortable to handle removing the helper
2277                  draggable.cancelHelperRemoval = true;
2278                  sortable.cancelHelperRemoval = false;
2279  
2280                  // Use _storedCSS To restore properties in the sortable,
2281                  // as this also handles revert (#9675) since the draggable
2282                  // may have modified them in unexpected ways (#8809)
2283                  sortable._storedCSS = {
2284                      position: sortable.placeholder.css( "position" ),
2285                      top: sortable.placeholder.css( "top" ),
2286                      left: sortable.placeholder.css( "left" )
2287                  };
2288  
2289                  sortable._mouseStop(event);
2290  
2291                  // Once drag has ended, the sortable should return to using
2292                  // its original helper, not the shared helper from draggable
2293                  sortable.options.helper = sortable.options._helper;
2294              } else {
2295                  // Prevent this Sortable from removing the helper.
2296                  // However, don't set the draggable to remove the helper
2297                  // either as another connected Sortable may yet handle the removal.
2298                  sortable.cancelHelperRemoval = true;
2299  
2300                  sortable._trigger( "deactivate", event, uiSortable );
2301              }
2302          });
2303      },
2304      drag: function( event, ui, draggable ) {
2305          $.each( draggable.sortables, function() {
2306              var innermostIntersecting = false,
2307                  sortable = this;
2308  
2309              // Copy over variables that sortable's _intersectsWith uses
2310              sortable.positionAbs = draggable.positionAbs;
2311              sortable.helperProportions = draggable.helperProportions;
2312              sortable.offset.click = draggable.offset.click;
2313  
2314              if ( sortable._intersectsWith( sortable.containerCache ) ) {
2315                  innermostIntersecting = true;
2316  
2317                  $.each( draggable.sortables, function() {
2318                      // Copy over variables that sortable's _intersectsWith uses
2319                      this.positionAbs = draggable.positionAbs;
2320                      this.helperProportions = draggable.helperProportions;
2321                      this.offset.click = draggable.offset.click;
2322  
2323                      if ( this !== sortable &&
2324                              this._intersectsWith( this.containerCache ) &&
2325                              $.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
2326                          innermostIntersecting = false;
2327                      }
2328  
2329                      return innermostIntersecting;
2330                  });
2331              }
2332  
2333              if ( innermostIntersecting ) {
2334                  // If it intersects, we use a little isOver variable and set it once,
2335                  // so that the move-in stuff gets fired only once.
2336                  if ( !sortable.isOver ) {
2337                      sortable.isOver = 1;
2338  
2339                      // Store draggable's parent in case we need to reappend to it later.
2340                      draggable._parent = ui.helper.parent();
2341  
2342                      sortable.currentItem = ui.helper
2343                          .appendTo( sortable.element )
2344                          .data( "ui-sortable-item", true );
2345  
2346                      // Store helper option to later restore it
2347                      sortable.options._helper = sortable.options.helper;
2348  
2349                      sortable.options.helper = function() {
2350                          return ui.helper[ 0 ];
2351                      };
2352  
2353                      // Fire the start events of the sortable with our passed browser event,
2354                      // and our own helper (so it doesn't create a new one)
2355                      event.target = sortable.currentItem[ 0 ];
2356                      sortable._mouseCapture( event, true );
2357                      sortable._mouseStart( event, true, true );
2358  
2359                      // Because the browser event is way off the new appended portlet,
2360                      // modify necessary variables to reflect the changes
2361                      sortable.offset.click.top = draggable.offset.click.top;
2362                      sortable.offset.click.left = draggable.offset.click.left;
2363                      sortable.offset.parent.left -= draggable.offset.parent.left -
2364                          sortable.offset.parent.left;
2365                      sortable.offset.parent.top -= draggable.offset.parent.top -
2366                          sortable.offset.parent.top;
2367  
2368                      draggable._trigger( "toSortable", event );
2369  
2370                      // Inform draggable that the helper is in a valid drop zone,
2371                      // used solely in the revert option to handle "valid/invalid".
2372                      draggable.dropped = sortable.element;
2373  
2374                      // Need to refreshPositions of all sortables in the case that
2375                      // adding to one sortable changes the location of the other sortables (#9675)
2376                      $.each( draggable.sortables, function() {
2377                          this.refreshPositions();
2378                      });
2379  
2380                      // hack so receive/update callbacks work (mostly)
2381                      draggable.currentItem = draggable.element;
2382                      sortable.fromOutside = draggable;
2383                  }
2384  
2385                  if ( sortable.currentItem ) {
2386                      sortable._mouseDrag( event );
2387                      // Copy the sortable's position because the draggable's can potentially reflect
2388                      // a relative position, while sortable is always absolute, which the dragged
2389                      // element has now become. (#8809)
2390                      ui.position = sortable.position;
2391                  }
2392              } else {
2393                  // If it doesn't intersect with the sortable, and it intersected before,
2394                  // we fake the drag stop of the sortable, but make sure it doesn't remove
2395                  // the helper by using cancelHelperRemoval.
2396                  if ( sortable.isOver ) {
2397  
2398                      sortable.isOver = 0;
2399                      sortable.cancelHelperRemoval = true;
2400  
2401                      // Calling sortable's mouseStop would trigger a revert,
2402                      // so revert must be temporarily false until after mouseStop is called.
2403                      sortable.options._revert = sortable.options.revert;
2404                      sortable.options.revert = false;
2405  
2406                      sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2407                      sortable._mouseStop( event, true );
2408  
2409                      // restore sortable behaviors that were modfied
2410                      // when the draggable entered the sortable area (#9481)
2411                      sortable.options.revert = sortable.options._revert;
2412                      sortable.options.helper = sortable.options._helper;
2413  
2414                      if ( sortable.placeholder ) {
2415                          sortable.placeholder.remove();
2416                      }
2417  
2418                      // Restore and recalculate the draggable's offset considering the sortable
2419                      // may have modified them in unexpected ways. (#8809, #10669)
2420                      ui.helper.appendTo( draggable._parent );
2421                      draggable._refreshOffsets( event );
2422                      ui.position = draggable._generatePosition( event, true );
2423  
2424                      draggable._trigger( "fromSortable", event );
2425  
2426                      // Inform draggable that the helper is no longer in a valid drop zone
2427                      draggable.dropped = false;
2428  
2429                      // Need to refreshPositions of all sortables just in case removing
2430                      // from one sortable changes the location of other sortables (#9675)
2431                      $.each( draggable.sortables, function() {
2432                          this.refreshPositions();
2433                      });
2434                  }
2435              }
2436          });
2437      }
2438  });
2439  
2440  $.ui.plugin.add("draggable", "cursor", {
2441      start: function( event, ui, instance ) {
2442          var t = $( "body" ),
2443              o = instance.options;
2444  
2445          if (t.css("cursor")) {
2446              o._cursor = t.css("cursor");
2447          }
2448          t.css("cursor", o.cursor);
2449      },
2450      stop: function( event, ui, instance ) {
2451          var o = instance.options;
2452          if (o._cursor) {
2453              $("body").css("cursor", o._cursor);
2454          }
2455      }
2456  });
2457  
2458  $.ui.plugin.add("draggable", "opacity", {
2459      start: function( event, ui, instance ) {
2460          var t = $( ui.helper ),
2461              o = instance.options;
2462          if (t.css("opacity")) {
2463              o._opacity = t.css("opacity");
2464          }
2465          t.css("opacity", o.opacity);
2466      },
2467      stop: function( event, ui, instance ) {
2468          var o = instance.options;
2469          if (o._opacity) {
2470              $(ui.helper).css("opacity", o._opacity);
2471          }
2472      }
2473  });
2474  
2475  $.ui.plugin.add("draggable", "scroll", {
2476      start: function( event, ui, i ) {
2477          if ( !i.scrollParentNotHidden ) {
2478              i.scrollParentNotHidden = i.helper.scrollParent( false );
2479          }
2480  
2481          if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2482              i.overflowOffset = i.scrollParentNotHidden.offset();
2483          }
2484      },
2485      drag: function( event, ui, i  ) {
2486  
2487          var o = i.options,
2488              scrolled = false,
2489              scrollParent = i.scrollParentNotHidden[ 0 ],
2490              document = i.document[ 0 ];
2491  
2492          if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2493              if ( !o.axis || o.axis !== "x" ) {
2494                  if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
2495                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2496                  } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2497                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2498                  }
2499              }
2500  
2501              if ( !o.axis || o.axis !== "y" ) {
2502                  if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
2503                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2504                  } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2505                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2506                  }
2507              }
2508  
2509          } else {
2510  
2511              if (!o.axis || o.axis !== "x") {
2512                  if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2513                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2514                  } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2515                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2516                  }
2517              }
2518  
2519              if (!o.axis || o.axis !== "y") {
2520                  if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2521                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2522                  } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2523                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2524                  }
2525              }
2526  
2527          }
2528  
2529          if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2530              $.ui.ddmanager.prepareOffsets(i, event);
2531          }
2532  
2533      }
2534  });
2535  
2536  $.ui.plugin.add("draggable", "snap", {
2537      start: function( event, ui, i ) {
2538  
2539          var o = i.options;
2540  
2541          i.snapElements = [];
2542  
2543          $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2544              var $t = $(this),
2545                  $o = $t.offset();
2546              if (this !== i.element[0]) {
2547                  i.snapElements.push({
2548                      item: this,
2549                      width: $t.outerWidth(), height: $t.outerHeight(),
2550                      top: $o.top, left: $o.left
2551                  });
2552              }
2553          });
2554  
2555      },
2556      drag: function( event, ui, inst ) {
2557  
2558          var ts, bs, ls, rs, l, r, t, b, i, first,
2559              o = inst.options,
2560              d = o.snapTolerance,
2561              x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2562              y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2563  
2564          for (i = inst.snapElements.length - 1; i >= 0; i--){
2565  
2566              l = inst.snapElements[i].left - inst.margins.left;
2567              r = l + inst.snapElements[i].width;
2568              t = inst.snapElements[i].top - inst.margins.top;
2569              b = t + inst.snapElements[i].height;
2570  
2571              if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2572                  if (inst.snapElements[i].snapping) {
2573                      (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2574                  }
2575                  inst.snapElements[i].snapping = false;
2576                  continue;
2577              }
2578  
2579              if (o.snapMode !== "inner") {
2580                  ts = Math.abs(t - y2) <= d;
2581                  bs = Math.abs(b - y1) <= d;
2582                  ls = Math.abs(l - x2) <= d;
2583                  rs = Math.abs(r - x1) <= d;
2584                  if (ts) {
2585                      ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
2586                  }
2587                  if (bs) {
2588                      ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
2589                  }
2590                  if (ls) {
2591                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
2592                  }
2593                  if (rs) {
2594                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
2595                  }
2596              }
2597  
2598              first = (ts || bs || ls || rs);
2599  
2600              if (o.snapMode !== "outer") {
2601                  ts = Math.abs(t - y1) <= d;
2602                  bs = Math.abs(b - y2) <= d;
2603                  ls = Math.abs(l - x1) <= d;
2604                  rs = Math.abs(r - x2) <= d;
2605                  if (ts) {
2606                      ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
2607                  }
2608                  if (bs) {
2609                      ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
2610                  }
2611                  if (ls) {
2612                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
2613                  }
2614                  if (rs) {
2615                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
2616                  }
2617              }
2618  
2619              if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2620                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2621              }
2622              inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2623  
2624          }
2625  
2626      }
2627  });
2628  
2629  $.ui.plugin.add("draggable", "stack", {
2630      start: function( event, ui, instance ) {
2631          var min,
2632              o = instance.options,
2633              group = $.makeArray($(o.stack)).sort(function(a, b) {
2634                  return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
2635              });
2636  
2637          if (!group.length) { return; }
2638  
2639          min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2640          $(group).each(function(i) {
2641              $(this).css("zIndex", min + i);
2642          });
2643          this.css("zIndex", (min + group.length));
2644      }
2645  });
2646  
2647  $.ui.plugin.add("draggable", "zIndex", {
2648      start: function( event, ui, instance ) {
2649          var t = $( ui.helper ),
2650              o = instance.options;
2651  
2652          if (t.css("zIndex")) {
2653              o._zIndex = t.css("zIndex");
2654          }
2655          t.css("zIndex", o.zIndex);
2656      },
2657      stop: function( event, ui, instance ) {
2658          var o = instance.options;
2659  
2660          if (o._zIndex) {
2661              $(ui.helper).css("zIndex", o._zIndex);
2662          }
2663      }
2664  });
2665  
2666  var draggable = $.ui.draggable;
2667  
2668  
2669  /*!
2670   * jQuery UI Droppable 1.11.4
2671   * http://jqueryui.com
2672   *
2673   * Copyright jQuery Foundation and other contributors
2674   * Released under the MIT license.
2675   * http://jquery.org/license
2676   *
2677   * http://api.jqueryui.com/droppable/
2678   */
2679  
2680  
2681  $.widget( "ui.droppable", {
2682      version: "1.11.4",
2683      widgetEventPrefix: "drop",
2684      options: {
2685          accept: "*",
2686          activeClass: false,
2687          addClasses: true,
2688          greedy: false,
2689          hoverClass: false,
2690          scope: "default",
2691          tolerance: "intersect",
2692  
2693          // callbacks
2694          activate: null,
2695          deactivate: null,
2696          drop: null,
2697          out: null,
2698          over: null
2699      },
2700      _create: function() {
2701  
2702          var proportions,
2703              o = this.options,
2704              accept = o.accept;
2705  
2706          this.isover = false;
2707          this.isout = true;
2708  
2709          this.accept = $.isFunction( accept ) ? accept : function( d ) {
2710              return d.is( accept );
2711          };
2712  
2713          this.proportions = function( /* valueToWrite */ ) {
2714              if ( arguments.length ) {
2715                  // Store the droppable's proportions
2716                  proportions = arguments[ 0 ];
2717              } else {
2718                  // Retrieve or derive the droppable's proportions
2719                  return proportions ?
2720                      proportions :
2721                      proportions = {
2722                          width: this.element[ 0 ].offsetWidth,
2723                          height: this.element[ 0 ].offsetHeight
2724                      };
2725              }
2726          };
2727  
2728          this._addToManager( o.scope );
2729  
2730          o.addClasses && this.element.addClass( "ui-droppable" );
2731  
2732      },
2733  
2734      _addToManager: function( scope ) {
2735          // Add the reference and positions to the manager
2736          $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2737          $.ui.ddmanager.droppables[ scope ].push( this );
2738      },
2739  
2740      _splice: function( drop ) {
2741          var i = 0;
2742          for ( ; i < drop.length; i++ ) {
2743              if ( drop[ i ] === this ) {
2744                  drop.splice( i, 1 );
2745              }
2746          }
2747      },
2748  
2749      _destroy: function() {
2750          var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2751  
2752          this._splice( drop );
2753  
2754          this.element.removeClass( "ui-droppable ui-droppable-disabled" );
2755      },
2756  
2757      _setOption: function( key, value ) {
2758  
2759          if ( key === "accept" ) {
2760              this.accept = $.isFunction( value ) ? value : function( d ) {
2761                  return d.is( value );
2762              };
2763          } else if ( key === "scope" ) {
2764              var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2765  
2766              this._splice( drop );
2767              this._addToManager( value );
2768          }
2769  
2770          this._super( key, value );
2771      },
2772  
2773      _activate: function( event ) {
2774          var draggable = $.ui.ddmanager.current;
2775          if ( this.options.activeClass ) {
2776              this.element.addClass( this.options.activeClass );
2777          }
2778          if ( draggable ){
2779              this._trigger( "activate", event, this.ui( draggable ) );
2780          }
2781      },
2782  
2783      _deactivate: function( event ) {
2784          var draggable = $.ui.ddmanager.current;
2785          if ( this.options.activeClass ) {
2786              this.element.removeClass( this.options.activeClass );
2787          }
2788          if ( draggable ){
2789              this._trigger( "deactivate", event, this.ui( draggable ) );
2790          }
2791      },
2792  
2793      _over: function( event ) {
2794  
2795          var draggable = $.ui.ddmanager.current;
2796  
2797          // Bail if draggable and droppable are same element
2798          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2799              return;
2800          }
2801  
2802          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2803              if ( this.options.hoverClass ) {
2804                  this.element.addClass( this.options.hoverClass );
2805              }
2806              this._trigger( "over", event, this.ui( draggable ) );
2807          }
2808  
2809      },
2810  
2811      _out: function( event ) {
2812  
2813          var draggable = $.ui.ddmanager.current;
2814  
2815          // Bail if draggable and droppable are same element
2816          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2817              return;
2818          }
2819  
2820          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2821              if ( this.options.hoverClass ) {
2822                  this.element.removeClass( this.options.hoverClass );
2823              }
2824              this._trigger( "out", event, this.ui( draggable ) );
2825          }
2826  
2827      },
2828  
2829      _drop: function( event, custom ) {
2830  
2831          var draggable = custom || $.ui.ddmanager.current,
2832              childrenIntersection = false;
2833  
2834          // Bail if draggable and droppable are same element
2835          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
2836              return false;
2837          }
2838  
2839          this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
2840              var inst = $( this ).droppable( "instance" );
2841              if (
2842                  inst.options.greedy &&
2843                  !inst.options.disabled &&
2844                  inst.options.scope === draggable.options.scope &&
2845                  inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
2846                  $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
2847              ) { childrenIntersection = true; return false; }
2848          });
2849          if ( childrenIntersection ) {
2850              return false;
2851          }
2852  
2853          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2854              if ( this.options.activeClass ) {
2855                  this.element.removeClass( this.options.activeClass );
2856              }
2857              if ( this.options.hoverClass ) {
2858                  this.element.removeClass( this.options.hoverClass );
2859              }
2860              this._trigger( "drop", event, this.ui( draggable ) );
2861              return this.element;
2862          }
2863  
2864          return false;
2865  
2866      },
2867  
2868      ui: function( c ) {
2869          return {
2870              draggable: ( c.currentItem || c.element ),
2871              helper: c.helper,
2872              position: c.position,
2873              offset: c.positionAbs
2874          };
2875      }
2876  
2877  });
2878  
2879  $.ui.intersect = (function() {
2880  	function isOverAxis( x, reference, size ) {
2881          return ( x >= reference ) && ( x < ( reference + size ) );
2882      }
2883  
2884      return function( draggable, droppable, toleranceMode, event ) {
2885  
2886          if ( !droppable.offset ) {
2887              return false;
2888          }
2889  
2890          var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
2891              y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
2892              x2 = x1 + draggable.helperProportions.width,
2893              y2 = y1 + draggable.helperProportions.height,
2894              l = droppable.offset.left,
2895              t = droppable.offset.top,
2896              r = l + droppable.proportions().width,
2897              b = t + droppable.proportions().height;
2898  
2899          switch ( toleranceMode ) {
2900          case "fit":
2901              return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2902          case "intersect":
2903              return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2904                  x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2905                  t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2906                  y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2907          case "pointer":
2908              return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
2909          case "touch":
2910              return (
2911                  ( y1 >= t && y1 <= b ) || // Top edge touching
2912                  ( y2 >= t && y2 <= b ) || // Bottom edge touching
2913                  ( y1 < t && y2 > b ) // Surrounded vertically
2914              ) && (
2915                  ( x1 >= l && x1 <= r ) || // Left edge touching
2916                  ( x2 >= l && x2 <= r ) || // Right edge touching
2917                  ( x1 < l && x2 > r ) // Surrounded horizontally
2918              );
2919          default:
2920              return false;
2921          }
2922      };
2923  })();
2924  
2925  /*
2926      This manager tracks offsets of draggables and droppables
2927  */
2928  $.ui.ddmanager = {
2929      current: null,
2930      droppables: { "default": [] },
2931      prepareOffsets: function( t, event ) {
2932  
2933          var i, j,
2934              m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2935              type = event ? event.type : null, // workaround for #2317
2936              list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2937  
2938          droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2939  
2940              // No disabled and non-accepted
2941              if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
2942                  continue;
2943              }
2944  
2945              // Filter out elements in the current dragged item
2946              for ( j = 0; j < list.length; j++ ) {
2947                  if ( list[ j ] === m[ i ].element[ 0 ] ) {
2948                      m[ i ].proportions().height = 0;
2949                      continue droppablesLoop;
2950                  }
2951              }
2952  
2953              m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2954              if ( !m[ i ].visible ) {
2955                  continue;
2956              }
2957  
2958              // Activate the droppable if used directly from draggables
2959              if ( type === "mousedown" ) {
2960                  m[ i ]._activate.call( m[ i ], event );
2961              }
2962  
2963              m[ i ].offset = m[ i ].element.offset();
2964              m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2965  
2966          }
2967  
2968      },
2969      drop: function( draggable, event ) {
2970  
2971          var dropped = false;
2972          // Create a copy of the droppables in case the list changes during the drop (#9116)
2973          $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2974  
2975              if ( !this.options ) {
2976                  return;
2977              }
2978              if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
2979                  dropped = this._drop.call( this, event ) || dropped;
2980              }
2981  
2982              if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
2983                  this.isout = true;
2984                  this.isover = false;
2985                  this._deactivate.call( this, event );
2986              }
2987  
2988          });
2989          return dropped;
2990  
2991      },
2992      dragStart: function( draggable, event ) {
2993          // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2994          draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2995              if ( !draggable.options.refreshPositions ) {
2996                  $.ui.ddmanager.prepareOffsets( draggable, event );
2997              }
2998          });
2999      },
3000      drag: function( draggable, event ) {
3001  
3002          // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
3003          if ( draggable.options.refreshPositions ) {
3004              $.ui.ddmanager.prepareOffsets( draggable, event );
3005          }
3006  
3007          // Run through all droppables and check their positions based on specific tolerance options
3008          $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
3009  
3010              if ( this.options.disabled || this.greedyChild || !this.visible ) {
3011                  return;
3012              }
3013  
3014              var parentInstance, scope, parent,
3015                  intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
3016                  c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
3017              if ( !c ) {
3018                  return;
3019              }
3020  
3021              if ( this.options.greedy ) {
3022                  // find droppable parents with same scope
3023                  scope = this.options.scope;
3024                  parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
3025                      return $( this ).droppable( "instance" ).options.scope === scope;
3026                  });
3027  
3028                  if ( parent.length ) {
3029                      parentInstance = $( parent[ 0 ] ).droppable( "instance" );
3030                      parentInstance.greedyChild = ( c === "isover" );
3031                  }
3032              }
3033  
3034              // we just moved into a greedy child
3035              if ( parentInstance && c === "isover" ) {
3036                  parentInstance.isover = false;
3037                  parentInstance.isout = true;
3038                  parentInstance._out.call( parentInstance, event );
3039              }
3040  
3041              this[ c ] = true;
3042              this[c === "isout" ? "isover" : "isout"] = false;
3043              this[c === "isover" ? "_over" : "_out"].call( this, event );
3044  
3045              // we just moved out of a greedy child
3046              if ( parentInstance && c === "isout" ) {
3047                  parentInstance.isout = false;
3048                  parentInstance.isover = true;
3049                  parentInstance._over.call( parentInstance, event );
3050              }
3051          });
3052  
3053      },
3054      dragStop: function( draggable, event ) {
3055          draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
3056          // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
3057          if ( !draggable.options.refreshPositions ) {
3058              $.ui.ddmanager.prepareOffsets( draggable, event );
3059          }
3060      }
3061  };
3062  
3063  var droppable = $.ui.droppable;
3064  
3065  
3066  /*!
3067   * jQuery UI Resizable 1.11.4
3068   * http://jqueryui.com
3069   *
3070   * Copyright jQuery Foundation and other contributors
3071   * Released under the MIT license.
3072   * http://jquery.org/license
3073   *
3074   * http://api.jqueryui.com/resizable/
3075   */
3076  
3077  
3078  $.widget("ui.resizable", $.ui.mouse, {
3079      version: "1.11.4",
3080      widgetEventPrefix: "resize",
3081      options: {
3082          alsoResize: false,
3083          animate: false,
3084          animateDuration: "slow",
3085          animateEasing: "swing",
3086          aspectRatio: false,
3087          autoHide: false,
3088          containment: false,
3089          ghost: false,
3090          grid: false,
3091          handles: "e,s,se",
3092          helper: false,
3093          maxHeight: null,
3094          maxWidth: null,
3095          minHeight: 10,
3096          minWidth: 10,
3097          // See #7960
3098          zIndex: 90,
3099  
3100          // callbacks
3101          resize: null,
3102          start: null,
3103          stop: null
3104      },
3105  
3106      _num: function( value ) {
3107          return parseInt( value, 10 ) || 0;
3108      },
3109  
3110      _isNumber: function( value ) {
3111          return !isNaN( parseInt( value, 10 ) );
3112      },
3113  
3114      _hasScroll: function( el, a ) {
3115  
3116          if ( $( el ).css( "overflow" ) === "hidden") {
3117              return false;
3118          }
3119  
3120          var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
3121              has = false;
3122  
3123          if ( el[ scroll ] > 0 ) {
3124              return true;
3125          }
3126  
3127          // TODO: determine which cases actually cause this to happen
3128          // if the element doesn't have the scroll set, see if it's possible to
3129          // set the scroll
3130          el[ scroll ] = 1;
3131          has = ( el[ scroll ] > 0 );
3132          el[ scroll ] = 0;
3133          return has;
3134      },
3135  
3136      _create: function() {
3137  
3138          var n, i, handle, axis, hname,
3139              that = this,
3140              o = this.options;
3141          this.element.addClass("ui-resizable");
3142  
3143          $.extend(this, {
3144              _aspectRatio: !!(o.aspectRatio),
3145              aspectRatio: o.aspectRatio,
3146              originalElement: this.element,
3147              _proportionallyResizeElements: [],
3148              _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
3149          });
3150  
3151          // Wrap the element if it cannot hold child nodes
3152          if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
3153  
3154              this.element.wrap(
3155                  $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
3156                      position: this.element.css("position"),
3157                      width: this.element.outerWidth(),
3158                      height: this.element.outerHeight(),
3159                      top: this.element.css("top"),
3160                      left: this.element.css("left")
3161                  })
3162              );
3163  
3164              this.element = this.element.parent().data(
3165                  "ui-resizable", this.element.resizable( "instance" )
3166              );
3167  
3168              this.elementIsWrapper = true;
3169  
3170              this.element.css({
3171                  marginLeft: this.originalElement.css("marginLeft"),
3172                  marginTop: this.originalElement.css("marginTop"),
3173                  marginRight: this.originalElement.css("marginRight"),
3174                  marginBottom: this.originalElement.css("marginBottom")
3175              });
3176              this.originalElement.css({
3177                  marginLeft: 0,
3178                  marginTop: 0,
3179                  marginRight: 0,
3180                  marginBottom: 0
3181              });
3182              // support: Safari
3183              // Prevent Safari textarea resize
3184              this.originalResizeStyle = this.originalElement.css("resize");
3185              this.originalElement.css("resize", "none");
3186  
3187              this._proportionallyResizeElements.push( this.originalElement.css({
3188                  position: "static",
3189                  zoom: 1,
3190                  display: "block"
3191              }) );
3192  
3193              // support: IE9
3194              // avoid IE jump (hard set the margin)
3195              this.originalElement.css({ margin: this.originalElement.css("margin") });
3196  
3197              this._proportionallyResize();
3198          }
3199  
3200          this.handles = o.handles ||
3201              ( !$(".ui-resizable-handle", this.element).length ?
3202                  "e,s,se" : {
3203                      n: ".ui-resizable-n",
3204                      e: ".ui-resizable-e",
3205                      s: ".ui-resizable-s",
3206                      w: ".ui-resizable-w",
3207                      se: ".ui-resizable-se",
3208                      sw: ".ui-resizable-sw",
3209                      ne: ".ui-resizable-ne",
3210                      nw: ".ui-resizable-nw"
3211                  } );
3212  
3213          this._handles = $();
3214          if ( this.handles.constructor === String ) {
3215  
3216              if ( this.handles === "all") {
3217                  this.handles = "n,e,s,w,se,sw,ne,nw";
3218              }
3219  
3220              n = this.handles.split(",");
3221              this.handles = {};
3222  
3223              for (i = 0; i < n.length; i++) {
3224  
3225                  handle = $.trim(n[i]);
3226                  hname = "ui-resizable-" + handle;
3227                  axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
3228  
3229                  axis.css({ zIndex: o.zIndex });
3230  
3231                  // TODO : What's going on here?
3232                  if ("se" === handle) {
3233                      axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
3234                  }
3235  
3236                  this.handles[handle] = ".ui-resizable-" + handle;
3237                  this.element.append(axis);
3238              }
3239  
3240          }
3241  
3242          this._renderAxis = function(target) {
3243  
3244              var i, axis, padPos, padWrapper;
3245  
3246              target = target || this.element;
3247  
3248              for (i in this.handles) {
3249  
3250                  if (this.handles[i].constructor === String) {
3251                      this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
3252                  } else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3253                      this.handles[ i ] = $( this.handles[ i ] );
3254                      this._on( this.handles[ i ], { "mousedown": that._mouseDown });
3255                  }
3256  
3257                  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
3258  
3259                      axis = $(this.handles[i], this.element);
3260  
3261                      padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
3262  
3263                      padPos = [ "padding",
3264                          /ne|nw|n/.test(i) ? "Top" :
3265                          /se|sw|s/.test(i) ? "Bottom" :
3266                          /^e$/.test(i) ? "Right" : "Left" ].join("");
3267  
3268                      target.css(padPos, padWrapper);
3269  
3270                      this._proportionallyResize();
3271                  }
3272  
3273                  this._handles = this._handles.add( this.handles[ i ] );
3274              }
3275          };
3276  
3277          // TODO: make renderAxis a prototype function
3278          this._renderAxis(this.element);
3279  
3280          this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3281          this._handles.disableSelection();
3282  
3283          this._handles.mouseover(function() {
3284              if (!that.resizing) {
3285                  if (this.className) {
3286                      axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
3287                  }
3288                  that.axis = axis && axis[1] ? axis[1] : "se";
3289              }
3290          });
3291  
3292          if (o.autoHide) {
3293              this._handles.hide();
3294              $(this.element)
3295                  .addClass("ui-resizable-autohide")
3296                  .mouseenter(function() {
3297                      if (o.disabled) {
3298                          return;
3299                      }
3300                      $(this).removeClass("ui-resizable-autohide");
3301                      that._handles.show();
3302                  })
3303                  .mouseleave(function() {
3304                      if (o.disabled) {
3305                          return;
3306                      }
3307                      if (!that.resizing) {
3308                          $(this).addClass("ui-resizable-autohide");
3309                          that._handles.hide();
3310                      }
3311                  });
3312          }
3313  
3314          this._mouseInit();
3315      },
3316  
3317      _destroy: function() {
3318  
3319          this._mouseDestroy();
3320  
3321          var wrapper,
3322              _destroy = function(exp) {
3323                  $(exp)
3324                      .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
3325                      .removeData("resizable")
3326                      .removeData("ui-resizable")
3327                      .unbind(".resizable")
3328                      .find(".ui-resizable-handle")
3329                          .remove();
3330              };
3331  
3332          // TODO: Unwrap at same DOM position
3333          if (this.elementIsWrapper) {
3334              _destroy(this.element);
3335              wrapper = this.element;
3336              this.originalElement.css({
3337                  position: wrapper.css("position"),
3338                  width: wrapper.outerWidth(),
3339                  height: wrapper.outerHeight(),
3340                  top: wrapper.css("top"),
3341                  left: wrapper.css("left")
3342              }).insertAfter( wrapper );
3343              wrapper.remove();
3344          }
3345  
3346          this.originalElement.css("resize", this.originalResizeStyle);
3347          _destroy(this.originalElement);
3348  
3349          return this;
3350      },
3351  
3352      _mouseCapture: function(event) {
3353          var i, handle,
3354              capture = false;
3355  
3356          for (i in this.handles) {
3357              handle = $(this.handles[i])[0];
3358              if (handle === event.target || $.contains(handle, event.target)) {
3359                  capture = true;
3360              }
3361          }
3362  
3363          return !this.options.disabled && capture;
3364      },
3365  
3366      _mouseStart: function(event) {
3367  
3368          var curleft, curtop, cursor,
3369              o = this.options,
3370              el = this.element;
3371  
3372          this.resizing = true;
3373  
3374          this._renderProxy();
3375  
3376          curleft = this._num(this.helper.css("left"));
3377          curtop = this._num(this.helper.css("top"));
3378  
3379          if (o.containment) {
3380              curleft += $(o.containment).scrollLeft() || 0;
3381              curtop += $(o.containment).scrollTop() || 0;
3382          }
3383  
3384          this.offset = this.helper.offset();
3385          this.position = { left: curleft, top: curtop };
3386  
3387          this.size = this._helper ? {
3388                  width: this.helper.width(),
3389                  height: this.helper.height()
3390              } : {
3391                  width: el.width(),
3392                  height: el.height()
3393              };
3394  
3395          this.originalSize = this._helper ? {
3396                  width: el.outerWidth(),
3397                  height: el.outerHeight()
3398              } : {
3399                  width: el.width(),
3400                  height: el.height()
3401              };
3402  
3403          this.sizeDiff = {
3404              width: el.outerWidth() - el.width(),
3405              height: el.outerHeight() - el.height()
3406          };
3407  
3408          this.originalPosition = { left: curleft, top: curtop };
3409          this.originalMousePosition = { left: event.pageX, top: event.pageY };
3410  
3411          this.aspectRatio = (typeof o.aspectRatio === "number") ?
3412              o.aspectRatio :
3413              ((this.originalSize.width / this.originalSize.height) || 1);
3414  
3415          cursor = $(".ui-resizable-" + this.axis).css("cursor");
3416          $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3417  
3418          el.addClass("ui-resizable-resizing");
3419          this._propagate("start", event);
3420          return true;
3421      },
3422  
3423      _mouseDrag: function(event) {
3424  
3425          var data, props,
3426              smp = this.originalMousePosition,
3427              a = this.axis,
3428              dx = (event.pageX - smp.left) || 0,
3429              dy = (event.pageY - smp.top) || 0,
3430              trigger = this._change[a];
3431  
3432          this._updatePrevProperties();
3433  
3434          if (!trigger) {
3435              return false;
3436          }
3437  
3438          data = trigger.apply(this, [ event, dx, dy ]);
3439  
3440          this._updateVirtualBoundaries(event.shiftKey);
3441          if (this._aspectRatio || event.shiftKey) {
3442              data = this._updateRatio(data, event);
3443          }
3444  
3445          data = this._respectSize(data, event);
3446  
3447          this._updateCache(data);
3448  
3449          this._propagate("resize", event);
3450  
3451          props = this._applyChanges();
3452  
3453          if ( !this._helper && this._proportionallyResizeElements.length ) {
3454              this._proportionallyResize();
3455          }
3456  
3457          if ( !$.isEmptyObject( props ) ) {
3458              this._updatePrevProperties();
3459              this._trigger( "resize", event, this.ui() );
3460              this._applyChanges();
3461          }
3462  
3463          return false;
3464      },
3465  
3466      _mouseStop: function(event) {
3467  
3468          this.resizing = false;
3469          var pr, ista, soffseth, soffsetw, s, left, top,
3470              o = this.options, that = this;
3471  
3472          if (this._helper) {
3473  
3474              pr = this._proportionallyResizeElements;
3475              ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3476              soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
3477              soffsetw = ista ? 0 : that.sizeDiff.width;
3478  
3479              s = {
3480                  width: (that.helper.width()  - soffsetw),
3481                  height: (that.helper.height() - soffseth)
3482              };
3483              left = (parseInt(that.element.css("left"), 10) +
3484                  (that.position.left - that.originalPosition.left)) || null;
3485              top = (parseInt(that.element.css("top"), 10) +
3486                  (that.position.top - that.originalPosition.top)) || null;
3487  
3488              if (!o.animate) {
3489                  this.element.css($.extend(s, { top: top, left: left }));
3490              }
3491  
3492              that.helper.height(that.size.height);
3493              that.helper.width(that.size.width);
3494  
3495              if (this._helper && !o.animate) {
3496                  this._proportionallyResize();
3497              }
3498          }
3499  
3500          $("body").css("cursor", "auto");
3501  
3502          this.element.removeClass("ui-resizable-resizing");
3503  
3504          this._propagate("stop", event);
3505  
3506          if (this._helper) {
3507              this.helper.remove();
3508          }
3509  
3510          return false;
3511  
3512      },
3513  
3514      _updatePrevProperties: function() {
3515          this.prevPosition = {
3516              top: this.position.top,
3517              left: this.position.left
3518          };
3519          this.prevSize = {
3520              width: this.size.width,
3521              height: this.size.height
3522          };
3523      },
3524  
3525      _applyChanges: function() {
3526          var props = {};
3527  
3528          if ( this.position.top !== this.prevPosition.top ) {
3529              props.top = this.position.top + "px";
3530          }
3531          if ( this.position.left !== this.prevPosition.left ) {
3532              props.left = this.position.left + "px";
3533          }
3534          if ( this.size.width !== this.prevSize.width ) {
3535              props.width = this.size.width + "px";
3536          }
3537          if ( this.size.height !== this.prevSize.height ) {
3538              props.height = this.size.height + "px";
3539          }
3540  
3541          this.helper.css( props );
3542  
3543          return props;
3544      },
3545  
3546      _updateVirtualBoundaries: function(forceAspectRatio) {
3547          var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3548              o = this.options;
3549  
3550          b = {
3551              minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
3552              maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3553              minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
3554              maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
3555          };
3556  
3557          if (this._aspectRatio || forceAspectRatio) {
3558              pMinWidth = b.minHeight * this.aspectRatio;
3559              pMinHeight = b.minWidth / this.aspectRatio;
3560              pMaxWidth = b.maxHeight * this.aspectRatio;
3561              pMaxHeight = b.maxWidth / this.aspectRatio;
3562  
3563              if (pMinWidth > b.minWidth) {
3564                  b.minWidth = pMinWidth;
3565              }
3566              if (pMinHeight > b.minHeight) {
3567                  b.minHeight = pMinHeight;
3568              }
3569              if (pMaxWidth < b.maxWidth) {
3570                  b.maxWidth = pMaxWidth;
3571              }
3572              if (pMaxHeight < b.maxHeight) {
3573                  b.maxHeight = pMaxHeight;
3574              }
3575          }
3576          this._vBoundaries = b;
3577      },
3578  
3579      _updateCache: function(data) {
3580          this.offset = this.helper.offset();
3581          if (this._isNumber(data.left)) {
3582              this.position.left = data.left;
3583          }
3584          if (this._isNumber(data.top)) {
3585              this.position.top = data.top;
3586          }
3587          if (this._isNumber(data.height)) {
3588              this.size.height = data.height;
3589          }
3590          if (this._isNumber(data.width)) {
3591              this.size.width = data.width;
3592          }
3593      },
3594  
3595      _updateRatio: function( data ) {
3596  
3597          var cpos = this.position,
3598              csize = this.size,
3599              a = this.axis;
3600  
3601          if (this._isNumber(data.height)) {
3602              data.width = (data.height * this.aspectRatio);
3603          } else if (this._isNumber(data.width)) {
3604              data.height = (data.width / this.aspectRatio);
3605          }
3606  
3607          if (a === "sw") {
3608              data.left = cpos.left + (csize.width - data.width);
3609              data.top = null;
3610          }
3611          if (a === "nw") {
3612              data.top = cpos.top + (csize.height - data.height);
3613              data.left = cpos.left + (csize.width - data.width);
3614          }
3615  
3616          return data;
3617      },
3618  
3619      _respectSize: function( data ) {
3620  
3621          var o = this._vBoundaries,
3622              a = this.axis,
3623              ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
3624              ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3625              isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
3626              isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3627              dw = this.originalPosition.left + this.originalSize.width,
3628              dh = this.position.top + this.size.height,
3629              cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3630          if (isminw) {
3631              data.width = o.minWidth;
3632          }
3633          if (isminh) {
3634              data.height = o.minHeight;
3635          }
3636          if (ismaxw) {
3637              data.width = o.maxWidth;
3638          }
3639          if (ismaxh) {
3640              data.height = o.maxHeight;
3641          }
3642  
3643          if (isminw && cw) {
3644              data.left = dw - o.minWidth;
3645          }
3646          if (ismaxw && cw) {
3647              data.left = dw - o.maxWidth;
3648          }
3649          if (isminh && ch) {
3650              data.top = dh - o.minHeight;
3651          }
3652          if (ismaxh && ch) {
3653              data.top = dh - o.maxHeight;
3654          }
3655  
3656          // Fixing jump error on top/left - bug #2330
3657          if (!data.width && !data.height && !data.left && data.top) {
3658              data.top = null;
3659          } else if (!data.width && !data.height && !data.top && data.left) {
3660              data.left = null;
3661          }
3662  
3663          return data;
3664      },
3665  
3666      _getPaddingPlusBorderDimensions: function( element ) {
3667          var i = 0,
3668              widths = [],
3669              borders = [
3670                  element.css( "borderTopWidth" ),
3671                  element.css( "borderRightWidth" ),
3672                  element.css( "borderBottomWidth" ),
3673                  element.css( "borderLeftWidth" )
3674              ],
3675              paddings = [
3676                  element.css( "paddingTop" ),
3677                  element.css( "paddingRight" ),
3678                  element.css( "paddingBottom" ),
3679                  element.css( "paddingLeft" )
3680              ];
3681  
3682          for ( ; i < 4; i++ ) {
3683              widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
3684              widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
3685          }
3686  
3687          return {
3688              height: widths[ 0 ] + widths[ 2 ],
3689              width: widths[ 1 ] + widths[ 3 ]
3690          };
3691      },
3692  
3693      _proportionallyResize: function() {
3694  
3695          if (!this._proportionallyResizeElements.length) {
3696              return;
3697          }
3698  
3699          var prel,
3700              i = 0,
3701              element = this.helper || this.element;
3702  
3703          for ( ; i < this._proportionallyResizeElements.length; i++) {
3704  
3705              prel = this._proportionallyResizeElements[i];
3706  
3707              // TODO: Seems like a bug to cache this.outerDimensions
3708              // considering that we are in a loop.
3709              if (!this.outerDimensions) {
3710                  this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3711              }
3712  
3713              prel.css({
3714                  height: (element.height() - this.outerDimensions.height) || 0,
3715                  width: (element.width() - this.outerDimensions.width) || 0
3716              });
3717  
3718          }
3719  
3720      },
3721  
3722      _renderProxy: function() {
3723  
3724          var el = this.element, o = this.options;
3725          this.elementOffset = el.offset();
3726  
3727          if (this._helper) {
3728  
3729              this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3730  
3731              this.helper.addClass(this._helper).css({
3732                  width: this.element.outerWidth() - 1,
3733                  height: this.element.outerHeight() - 1,
3734                  position: "absolute",
3735                  left: this.elementOffset.left + "px",
3736                  top: this.elementOffset.top + "px",
3737                  zIndex: ++o.zIndex //TODO: Don't modify option
3738              });
3739  
3740              this.helper
3741                  .appendTo("body")
3742                  .disableSelection();
3743  
3744          } else {
3745              this.helper = this.element;
3746          }
3747  
3748      },
3749  
3750      _change: {
3751          e: function(event, dx) {
3752              return { width: this.originalSize.width + dx };
3753          },
3754          w: function(event, dx) {
3755              var cs = this.originalSize, sp = this.originalPosition;
3756              return { left: sp.left + dx, width: cs.width - dx };
3757          },
3758          n: function(event, dx, dy) {
3759              var cs = this.originalSize, sp = this.originalPosition;
3760              return { top: sp.top + dy, height: cs.height - dy };
3761          },
3762          s: function(event, dx, dy) {
3763              return { height: this.originalSize.height + dy };
3764          },
3765          se: function(event, dx, dy) {
3766              return $.extend(this._change.s.apply(this, arguments),
3767                  this._change.e.apply(this, [ event, dx, dy ]));
3768          },
3769          sw: function(event, dx, dy) {
3770              return $.extend(this._change.s.apply(this, arguments),
3771                  this._change.w.apply(this, [ event, dx, dy ]));
3772          },
3773          ne: function(event, dx, dy) {
3774              return $.extend(this._change.n.apply(this, arguments),
3775                  this._change.e.apply(this, [ event, dx, dy ]));
3776          },
3777          nw: function(event, dx, dy) {
3778              return $.extend(this._change.n.apply(this, arguments),
3779                  this._change.w.apply(this, [ event, dx, dy ]));
3780          }
3781      },
3782  
3783      _propagate: function(n, event) {
3784          $.ui.plugin.call(this, n, [ event, this.ui() ]);
3785          (n !== "resize" && this._trigger(n, event, this.ui()));
3786      },
3787  
3788      plugins: {},
3789  
3790      ui: function() {
3791          return {
3792              originalElement: this.originalElement,
3793              element: this.element,
3794              helper: this.helper,
3795              position: this.position,
3796              size: this.size,
3797              originalSize: this.originalSize,
3798              originalPosition: this.originalPosition
3799          };
3800      }
3801  
3802  });
3803  
3804  /*
3805   * Resizable Extensions
3806   */
3807  
3808  $.ui.plugin.add("resizable", "animate", {
3809  
3810      stop: function( event ) {
3811          var that = $(this).resizable( "instance" ),
3812              o = that.options,
3813              pr = that._proportionallyResizeElements,
3814              ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3815              soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
3816              soffsetw = ista ? 0 : that.sizeDiff.width,
3817              style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3818              left = (parseInt(that.element.css("left"), 10) +
3819                  (that.position.left - that.originalPosition.left)) || null,
3820              top = (parseInt(that.element.css("top"), 10) +
3821                  (that.position.top - that.originalPosition.top)) || null;
3822  
3823          that.element.animate(
3824              $.extend(style, top && left ? { top: top, left: left } : {}), {
3825                  duration: o.animateDuration,
3826                  easing: o.animateEasing,
3827                  step: function() {
3828  
3829                      var data = {
3830                          width: parseInt(that.element.css("width"), 10),
3831                          height: parseInt(that.element.css("height"), 10),
3832                          top: parseInt(that.element.css("top"), 10),
3833                          left: parseInt(that.element.css("left"), 10)
3834                      };
3835  
3836                      if (pr && pr.length) {
3837                          $(pr[0]).css({ width: data.width, height: data.height });
3838                      }
3839  
3840                      // propagating resize, and updating values for each animation step
3841                      that._updateCache(data);
3842                      that._propagate("resize", event);
3843  
3844                  }
3845              }
3846          );
3847      }
3848  
3849  });
3850  
3851  $.ui.plugin.add( "resizable", "containment", {
3852  
3853      start: function() {
3854          var element, p, co, ch, cw, width, height,
3855              that = $( this ).resizable( "instance" ),
3856              o = that.options,
3857              el = that.element,
3858              oc = o.containment,
3859              ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3860  
3861          if ( !ce ) {
3862              return;
3863          }
3864  
3865          that.containerElement = $( ce );
3866  
3867          if ( /document/.test( oc ) || oc === document ) {
3868              that.containerOffset = {
3869                  left: 0,
3870                  top: 0
3871              };
3872              that.containerPosition = {
3873                  left: 0,
3874                  top: 0
3875              };
3876  
3877              that.parentData = {
3878                  element: $( document ),
3879                  left: 0,
3880                  top: 0,
3881                  width: $( document ).width(),
3882                  height: $( document ).height() || document.body.parentNode.scrollHeight
3883              };
3884          } else {
3885              element = $( ce );
3886              p = [];
3887              $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
3888                  p[ i ] = that._num( element.css( "padding" + name ) );
3889              });
3890  
3891              that.containerOffset = element.offset();
3892              that.containerPosition = element.position();
3893              that.containerSize = {
3894                  height: ( element.innerHeight() - p[ 3 ] ),
3895                  width: ( element.innerWidth() - p[ 1 ] )
3896              };
3897  
3898              co = that.containerOffset;
3899              ch = that.containerSize.height;
3900              cw = that.containerSize.width;
3901              width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3902              height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3903  
3904              that.parentData = {
3905                  element: ce,
3906                  left: co.left,
3907                  top: co.top,
3908                  width: width,
3909                  height: height
3910              };
3911          }
3912      },
3913  
3914      resize: function( event ) {
3915          var woset, hoset, isParent, isOffsetRelative,
3916              that = $( this ).resizable( "instance" ),
3917              o = that.options,
3918              co = that.containerOffset,
3919              cp = that.position,
3920              pRatio = that._aspectRatio || event.shiftKey,
3921              cop = {
3922                  top: 0,
3923                  left: 0
3924              },
3925              ce = that.containerElement,
3926              continueResize = true;
3927  
3928          if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3929              cop = co;
3930          }
3931  
3932          if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3933              that.size.width = that.size.width +
3934                  ( that._helper ?
3935                      ( that.position.left - co.left ) :
3936                      ( that.position.left - cop.left ) );
3937  
3938              if ( pRatio ) {
3939                  that.size.height = that.size.width / that.aspectRatio;
3940                  continueResize = false;
3941              }
3942              that.position.left = o.helper ? co.left : 0;
3943          }
3944  
3945          if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3946              that.size.height = that.size.height +
3947                  ( that._helper ?
3948                      ( that.position.top - co.top ) :
3949                      that.position.top );
3950  
3951              if ( pRatio ) {
3952                  that.size.width = that.size.height * that.aspectRatio;
3953                  continueResize = false;
3954              }
3955              that.position.top = that._helper ? co.top : 0;
3956          }
3957  
3958          isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3959          isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3960  
3961          if ( isParent && isOffsetRelative ) {
3962              that.offset.left = that.parentData.left + that.position.left;
3963              that.offset.top = that.parentData.top + that.position.top;
3964          } else {
3965              that.offset.left = that.element.offset().left;
3966              that.offset.top = that.element.offset().top;
3967          }
3968  
3969          woset = Math.abs( that.sizeDiff.width +
3970              (that._helper ?
3971                  that.offset.left - cop.left :
3972                  (that.offset.left - co.left)) );
3973  
3974          hoset = Math.abs( that.sizeDiff.height +
3975              (that._helper ?
3976                  that.offset.top - cop.top :
3977                  (that.offset.top - co.top)) );
3978  
3979          if ( woset + that.size.width >= that.parentData.width ) {
3980              that.size.width = that.parentData.width - woset;
3981              if ( pRatio ) {
3982                  that.size.height = that.size.width / that.aspectRatio;
3983                  continueResize = false;
3984              }
3985          }
3986  
3987          if ( hoset + that.size.height >= that.parentData.height ) {
3988              that.size.height = that.parentData.height - hoset;
3989              if ( pRatio ) {
3990                  that.size.width = that.size.height * that.aspectRatio;
3991                  continueResize = false;
3992              }
3993          }
3994  
3995          if ( !continueResize ) {
3996              that.position.left = that.prevPosition.left;
3997              that.position.top = that.prevPosition.top;
3998              that.size.width = that.prevSize.width;
3999              that.size.height = that.prevSize.height;
4000          }
4001      },
4002  
4003      stop: function() {
4004          var that = $( this ).resizable( "instance" ),
4005              o = that.options,
4006              co = that.containerOffset,
4007              cop = that.containerPosition,
4008              ce = that.containerElement,
4009              helper = $( that.helper ),
4010              ho = helper.offset(),
4011              w = helper.outerWidth() - that.sizeDiff.width,
4012              h = helper.outerHeight() - that.sizeDiff.height;
4013  
4014          if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
4015              $( this ).css({
4016                  left: ho.left - cop.left - co.left,
4017                  width: w,
4018                  height: h
4019              });
4020          }
4021  
4022          if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
4023              $( this ).css({
4024                  left: ho.left - cop.left - co.left,
4025                  width: w,
4026                  height: h
4027              });
4028          }
4029      }
4030  });
4031  
4032  $.ui.plugin.add("resizable", "alsoResize", {
4033  
4034      start: function() {
4035          var that = $(this).resizable( "instance" ),
4036              o = that.options;
4037  
4038          $(o.alsoResize).each(function() {
4039              var el = $(this);
4040              el.data("ui-resizable-alsoresize", {
4041                  width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
4042                  left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
4043              });
4044          });
4045      },
4046  
4047      resize: function(event, ui) {
4048          var that = $(this).resizable( "instance" ),
4049              o = that.options,
4050              os = that.originalSize,
4051              op = that.originalPosition,
4052              delta = {
4053                  height: (that.size.height - os.height) || 0,
4054                  width: (that.size.width - os.width) || 0,
4055                  top: (that.position.top - op.top) || 0,
4056                  left: (that.position.left - op.left) || 0
4057              };
4058  
4059              $(o.alsoResize).each(function() {
4060                  var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
4061                      css = el.parents(ui.originalElement[0]).length ?
4062                              [ "width", "height" ] :
4063                              [ "width", "height", "top", "left" ];
4064  
4065                  $.each(css, function(i, prop) {
4066                      var sum = (start[prop] || 0) + (delta[prop] || 0);
4067                      if (sum && sum >= 0) {
4068                          style[prop] = sum || null;
4069                      }
4070                  });
4071  
4072                  el.css(style);
4073              });
4074      },
4075  
4076      stop: function() {
4077          $(this).removeData("resizable-alsoresize");
4078      }
4079  });
4080  
4081  $.ui.plugin.add("resizable", "ghost", {
4082  
4083      start: function() {
4084  
4085          var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
4086  
4087          that.ghost = that.originalElement.clone();
4088          that.ghost
4089              .css({
4090                  opacity: 0.25,
4091                  display: "block",
4092                  position: "relative",
4093                  height: cs.height,
4094                  width: cs.width,
4095                  margin: 0,
4096                  left: 0,
4097                  top: 0
4098              })
4099              .addClass("ui-resizable-ghost")
4100              .addClass(typeof o.ghost === "string" ? o.ghost : "");
4101  
4102          that.ghost.appendTo(that.helper);
4103  
4104      },
4105  
4106      resize: function() {
4107          var that = $(this).resizable( "instance" );
4108          if (that.ghost) {
4109              that.ghost.css({
4110                  position: "relative",
4111                  height: that.size.height,
4112                  width: that.size.width
4113              });
4114          }
4115      },
4116  
4117      stop: function() {
4118          var that = $(this).resizable( "instance" );
4119          if (that.ghost && that.helper) {
4120              that.helper.get(0).removeChild(that.ghost.get(0));
4121          }
4122      }
4123  
4124  });
4125  
4126  $.ui.plugin.add("resizable", "grid", {
4127  
4128      resize: function() {
4129          var outerDimensions,
4130              that = $(this).resizable( "instance" ),
4131              o = that.options,
4132              cs = that.size,
4133              os = that.originalSize,
4134              op = that.originalPosition,
4135              a = that.axis,
4136              grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
4137              gridX = (grid[0] || 1),
4138              gridY = (grid[1] || 1),
4139              ox = Math.round((cs.width - os.width) / gridX) * gridX,
4140              oy = Math.round((cs.height - os.height) / gridY) * gridY,
4141              newWidth = os.width + ox,
4142              newHeight = os.height + oy,
4143              isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
4144              isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
4145              isMinWidth = o.minWidth && (o.minWidth > newWidth),
4146              isMinHeight = o.minHeight && (o.minHeight > newHeight);
4147  
4148          o.grid = grid;
4149  
4150          if (isMinWidth) {
4151              newWidth += gridX;
4152          }
4153          if (isMinHeight) {
4154              newHeight += gridY;
4155          }
4156          if (isMaxWidth) {
4157              newWidth -= gridX;
4158          }
4159          if (isMaxHeight) {
4160              newHeight -= gridY;
4161          }
4162  
4163          if (/^(se|s|e)$/.test(a)) {
4164              that.size.width = newWidth;
4165              that.size.height = newHeight;
4166          } else if (/^(ne)$/.test(a)) {
4167              that.size.width = newWidth;
4168              that.size.height = newHeight;
4169              that.position.top = op.top - oy;
4170          } else if (/^(sw)$/.test(a)) {
4171              that.size.width = newWidth;
4172              that.size.height = newHeight;
4173              that.position.left = op.left - ox;
4174          } else {
4175              if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
4176                  outerDimensions = that._getPaddingPlusBorderDimensions( this );
4177              }
4178  
4179              if ( newHeight - gridY > 0 ) {
4180                  that.size.height = newHeight;
4181                  that.position.top = op.top - oy;
4182              } else {
4183                  newHeight = gridY - outerDimensions.height;
4184                  that.size.height = newHeight;
4185                  that.position.top = op.top + os.height - newHeight;
4186              }
4187              if ( newWidth - gridX > 0 ) {
4188                  that.size.width = newWidth;
4189                  that.position.left = op.left - ox;
4190              } else {
4191                  newWidth = gridX - outerDimensions.width;
4192                  that.size.width = newWidth;
4193                  that.position.left = op.left + os.width - newWidth;
4194              }
4195          }
4196      }
4197  
4198  });
4199  
4200  var resizable = $.ui.resizable;
4201  
4202  
4203  /*!
4204   * jQuery UI Selectable 1.11.4
4205   * http://jqueryui.com
4206   *
4207   * Copyright jQuery Foundation and other contributors
4208   * Released under the MIT license.
4209   * http://jquery.org/license
4210   *
4211   * http://api.jqueryui.com/selectable/
4212   */
4213  
4214  
4215  var selectable = $.widget("ui.selectable", $.ui.mouse, {
4216      version: "1.11.4",
4217      options: {
4218          appendTo: "body",
4219          autoRefresh: true,
4220          distance: 0,
4221          filter: "*",
4222          tolerance: "touch",
4223  
4224          // callbacks
4225          selected: null,
4226          selecting: null,
4227          start: null,
4228          stop: null,
4229          unselected: null,
4230          unselecting: null
4231      },
4232      _create: function() {
4233          var selectees,
4234              that = this;
4235  
4236          this.element.addClass("ui-selectable");
4237  
4238          this.dragged = false;
4239  
4240          // cache selectee children based on filter
4241          this.refresh = function() {
4242              selectees = $(that.options.filter, that.element[0]);
4243              selectees.addClass("ui-selectee");
4244              selectees.each(function() {
4245                  var $this = $(this),
4246                      pos = $this.offset();
4247                  $.data(this, "selectable-item", {
4248                      element: this,
4249                      $element: $this,
4250                      left: pos.left,
4251                      top: pos.top,
4252                      right: pos.left + $this.outerWidth(),
4253                      bottom: pos.top + $this.outerHeight(),
4254                      startselected: false,
4255                      selected: $this.hasClass("ui-selected"),
4256                      selecting: $this.hasClass("ui-selecting"),
4257                      unselecting: $this.hasClass("ui-unselecting")
4258                  });
4259              });
4260          };
4261          this.refresh();
4262  
4263          this.selectees = selectees.addClass("ui-selectee");
4264  
4265          this._mouseInit();
4266  
4267          this.helper = $("<div class='ui-selectable-helper'></div>");
4268      },
4269  
4270      _destroy: function() {
4271          this.selectees
4272              .removeClass("ui-selectee")
4273              .removeData("selectable-item");
4274          this.element
4275              .removeClass("ui-selectable ui-selectable-disabled");
4276          this._mouseDestroy();
4277      },
4278  
4279      _mouseStart: function(event) {
4280          var that = this,
4281              options = this.options;
4282  
4283          this.opos = [ event.pageX, event.pageY ];
4284  
4285          if (this.options.disabled) {
4286              return;
4287          }
4288  
4289          this.selectees = $(options.filter, this.element[0]);
4290  
4291          this._trigger("start", event);
4292  
4293          $(options.appendTo).append(this.helper);
4294          // position helper (lasso)
4295          this.helper.css({
4296              "left": event.pageX,
4297              "top": event.pageY,
4298              "width": 0,
4299              "height": 0
4300          });
4301  
4302          if (options.autoRefresh) {
4303              this.refresh();
4304          }
4305  
4306          this.selectees.filter(".ui-selected").each(function() {
4307              var selectee = $.data(this, "selectable-item");
4308              selectee.startselected = true;
4309              if (!event.metaKey && !event.ctrlKey) {
4310                  selectee.$element.removeClass("ui-selected");
4311                  selectee.selected = false;
4312                  selectee.$element.addClass("ui-unselecting");
4313                  selectee.unselecting = true;
4314                  // selectable UNSELECTING callback
4315                  that._trigger("unselecting", event, {
4316                      unselecting: selectee.element
4317                  });
4318              }
4319          });
4320  
4321          $(event.target).parents().addBack().each(function() {
4322              var doSelect,
4323                  selectee = $.data(this, "selectable-item");
4324              if (selectee) {
4325                  doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
4326                  selectee.$element
4327                      .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
4328                      .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
4329                  selectee.unselecting = !doSelect;
4330                  selectee.selecting = doSelect;
4331                  selectee.selected = doSelect;
4332                  // selectable (UN)SELECTING callback
4333                  if (doSelect) {
4334                      that._trigger("selecting", event, {
4335                          selecting: selectee.element
4336                      });
4337                  } else {
4338                      that._trigger("unselecting", event, {
4339                          unselecting: selectee.element
4340                      });
4341                  }
4342                  return false;
4343              }
4344          });
4345  
4346      },
4347  
4348      _mouseDrag: function(event) {
4349  
4350          this.dragged = true;
4351  
4352          if (this.options.disabled) {
4353              return;
4354          }
4355  
4356          var tmp,
4357              that = this,
4358              options = this.options,
4359              x1 = this.opos[0],
4360              y1 = this.opos[1],
4361              x2 = event.pageX,
4362              y2 = event.pageY;
4363  
4364          if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
4365          if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
4366          this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
4367  
4368          this.selectees.each(function() {
4369              var selectee = $.data(this, "selectable-item"),
4370                  hit = false;
4371  
4372              //prevent helper from being selected if appendTo: selectable
4373              if (!selectee || selectee.element === that.element[0]) {
4374                  return;
4375              }
4376  
4377              if (options.tolerance === "touch") {
4378                  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
4379              } else if (options.tolerance === "fit") {
4380                  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
4381              }
4382  
4383              if (hit) {
4384                  // SELECT
4385                  if (selectee.selected) {
4386                      selectee.$element.removeClass("ui-selected");
4387                      selectee.selected = false;
4388                  }
4389                  if (selectee.unselecting) {
4390                      selectee.$element.removeClass("ui-unselecting");
4391                      selectee.unselecting = false;
4392                  }
4393                  if (!selectee.selecting) {
4394                      selectee.$element.addClass("ui-selecting");
4395                      selectee.selecting = true;
4396                      // selectable SELECTING callback
4397                      that._trigger("selecting", event, {
4398                          selecting: selectee.element
4399                      });
4400                  }
4401              } else {
4402                  // UNSELECT
4403                  if (selectee.selecting) {
4404                      if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
4405                          selectee.$element.removeClass("ui-selecting");
4406                          selectee.selecting = false;
4407                          selectee.$element.addClass("ui-selected");
4408                          selectee.selected = true;
4409                      } else {
4410                          selectee.$element.removeClass("ui-selecting");
4411                          selectee.selecting = false;
4412                          if (selectee.startselected) {
4413                              selectee.$element.addClass("ui-unselecting");
4414                              selectee.unselecting = true;
4415                          }
4416                          // selectable UNSELECTING callback
4417                          that._trigger("unselecting", event, {
4418                              unselecting: selectee.element
4419                          });
4420                      }
4421                  }
4422                  if (selectee.selected) {
4423                      if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
4424                          selectee.$element.removeClass("ui-selected");
4425                          selectee.selected = false;
4426  
4427                          selectee.$element.addClass("ui-unselecting");
4428                          selectee.unselecting = true;
4429                          // selectable UNSELECTING callback
4430                          that._trigger("unselecting", event, {
4431                              unselecting: selectee.element
4432                          });
4433                      }
4434                  }
4435              }
4436          });
4437  
4438          return false;
4439      },
4440  
4441      _mouseStop: function(event) {
4442          var that = this;
4443  
4444          this.dragged = false;
4445  
4446          $(".ui-unselecting", this.element[0]).each(function() {
4447              var selectee = $.data(this, "selectable-item");
4448              selectee.$element.removeClass("ui-unselecting");
4449              selectee.unselecting = false;
4450              selectee.startselected = false;
4451              that._trigger("unselected", event, {
4452                  unselected: selectee.element
4453              });
4454          });
4455          $(".ui-selecting", this.element[0]).each(function() {
4456              var selectee = $.data(this, "selectable-item");
4457              selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
4458              selectee.selecting = false;
4459              selectee.selected = true;
4460              selectee.startselected = true;
4461              that._trigger("selected", event, {
4462                  selected: selectee.element
4463              });
4464          });
4465          this._trigger("stop", event);
4466  
4467          this.helper.remove();
4468  
4469          return false;
4470      }
4471  
4472  });
4473  
4474  
4475  /*!
4476   * jQuery UI Sortable 1.11.4
4477   * http://jqueryui.com
4478   *
4479   * Copyright jQuery Foundation and other contributors
4480   * Released under the MIT license.
4481   * http://jquery.org/license
4482   *
4483   * http://api.jqueryui.com/sortable/
4484   */
4485  
4486  
4487  var sortable = $.widget("ui.sortable", $.ui.mouse, {
4488      version: "1.11.4",
4489      widgetEventPrefix: "sort",
4490      ready: false,
4491      options: {
4492          appendTo: "parent",
4493          axis: false,
4494          connectWith: false,
4495          containment: false,
4496          cursor: "auto",
4497          cursorAt: false,
4498          dropOnEmpty: true,
4499          forcePlaceholderSize: false,
4500          forceHelperSize: false,
4501          grid: false,
4502          handle: false,
4503          helper: "original",
4504          items: "> *",
4505          opacity: false,
4506          placeholder: false,
4507          revert: false,
4508          scroll: true,
4509          scrollSensitivity: 20,
4510          scrollSpeed: 20,
4511          scope: "default",
4512          tolerance: "intersect",
4513          zIndex: 1000,
4514  
4515          // callbacks
4516          activate: null,
4517          beforeStop: null,
4518          change: null,
4519          deactivate: null,
4520          out: null,
4521          over: null,
4522          receive: null,
4523          remove: null,
4524          sort: null,
4525          start: null,
4526          stop: null,
4527          update: null
4528      },
4529  
4530      _isOverAxis: function( x, reference, size ) {
4531          return ( x >= reference ) && ( x < ( reference + size ) );
4532      },
4533  
4534      _isFloating: function( item ) {
4535          return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
4536      },
4537  
4538      _create: function() {
4539          this.containerCache = {};
4540          this.element.addClass("ui-sortable");
4541  
4542          //Get the items
4543          this.refresh();
4544  
4545          //Let's determine the parent's offset
4546          this.offset = this.element.offset();
4547  
4548          //Initialize mouse events for interaction
4549          this._mouseInit();
4550  
4551          this._setHandleClassName();
4552  
4553          //We're ready to go
4554          this.ready = true;
4555  
4556      },
4557  
4558      _setOption: function( key, value ) {
4559          this._super( key, value );
4560  
4561          if ( key === "handle" ) {
4562              this._setHandleClassName();
4563          }
4564      },
4565  
4566      _setHandleClassName: function() {
4567          this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
4568          $.each( this.items, function() {
4569              ( this.instance.options.handle ?
4570                  this.item.find( this.instance.options.handle ) : this.item )
4571                  .addClass( "ui-sortable-handle" );
4572          });
4573      },
4574  
4575      _destroy: function() {
4576          this.element
4577              .removeClass( "ui-sortable ui-sortable-disabled" )
4578              .find( ".ui-sortable-handle" )
4579                  .removeClass( "ui-sortable-handle" );
4580          this._mouseDestroy();
4581  
4582          for ( var i = this.items.length - 1; i >= 0; i-- ) {
4583              this.items[i].item.removeData(this.widgetName + "-item");
4584          }
4585  
4586          return this;
4587      },
4588  
4589      _mouseCapture: function(event, overrideHandle) {
4590          var currentItem = null,
4591              validHandle = false,
4592              that = this;
4593  
4594          if (this.reverting) {
4595              return false;
4596          }
4597  
4598          if(this.options.disabled || this.options.type === "static") {
4599              return false;
4600          }
4601  
4602          //We have to refresh the items data once first
4603          this._refreshItems(event);
4604  
4605          //Find out if the clicked node (or one of its parents) is a actual item in this.items
4606          $(event.target).parents().each(function() {
4607              if($.data(this, that.widgetName + "-item") === that) {
4608                  currentItem = $(this);
4609                  return false;
4610              }
4611          });
4612          if($.data(event.target, that.widgetName + "-item") === that) {
4613              currentItem = $(event.target);
4614          }
4615  
4616          if(!currentItem) {
4617              return false;
4618          }
4619          if(this.options.handle && !overrideHandle) {
4620              $(this.options.handle, currentItem).find("*").addBack().each(function() {
4621                  if(this === event.target) {
4622                      validHandle = true;
4623                  }
4624              });
4625              if(!validHandle) {
4626                  return false;
4627              }
4628          }
4629  
4630          this.currentItem = currentItem;
4631          this._removeCurrentsFromItems();
4632          return true;
4633  
4634      },
4635  
4636      _mouseStart: function(event, overrideHandle, noActivation) {
4637  
4638          var i, body,
4639              o = this.options;
4640  
4641          this.currentContainer = this;
4642  
4643          //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4644          this.refreshPositions();
4645  
4646          //Create and append the visible helper
4647          this.helper = this._createHelper(event);
4648  
4649          //Cache the helper size
4650          this._cacheHelperProportions();
4651  
4652          /*
4653           * - Position generation -
4654           * This block generates everything position related - it's the core of draggables.
4655           */
4656  
4657          //Cache the margins of the original element
4658          this._cacheMargins();
4659  
4660          //Get the next scrolling parent
4661          this.scrollParent = this.helper.scrollParent();
4662  
4663          //The element's absolute position on the page minus margins
4664          this.offset = this.currentItem.offset();
4665          this.offset = {
4666              top: this.offset.top - this.margins.top,
4667              left: this.offset.left - this.margins.left
4668          };
4669  
4670          $.extend(this.offset, {
4671              click: { //Where the click happened, relative to the element
4672                  left: event.pageX - this.offset.left,
4673                  top: event.pageY - this.offset.top
4674              },
4675              parent: this._getParentOffset(),
4676              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4677          });
4678  
4679          // Only after we got the offset, we can change the helper's position to absolute
4680          // TODO: Still need to figure out a way to make relative sorting possible
4681          this.helper.css("position", "absolute");
4682          this.cssPosition = this.helper.css("position");
4683  
4684          //Generate the original position
4685          this.originalPosition = this._generatePosition(event);
4686          this.originalPageX = event.pageX;
4687          this.originalPageY = event.pageY;
4688  
4689          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4690          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4691  
4692          //Cache the former DOM position
4693          this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4694  
4695          //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
4696          if(this.helper[0] !== this.currentItem[0]) {
4697              this.currentItem.hide();
4698          }
4699  
4700          //Create the placeholder
4701          this._createPlaceholder();
4702  
4703          //Set a containment if given in the options
4704          if(o.containment) {
4705              this._setContainment();
4706          }
4707  
4708          if( o.cursor && o.cursor !== "auto" ) { // cursor option
4709              body = this.document.find( "body" );
4710  
4711              // support: IE
4712              this.storedCursor = body.css( "cursor" );
4713              body.css( "cursor", o.cursor );
4714  
4715              this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4716          }
4717  
4718          if(o.opacity) { // opacity option
4719              if (this.helper.css("opacity")) {
4720                  this._storedOpacity = this.helper.css("opacity");
4721              }
4722              this.helper.css("opacity", o.opacity);
4723          }
4724  
4725          if(o.zIndex) { // zIndex option
4726              if (this.helper.css("zIndex")) {
4727                  this._storedZIndex = this.helper.css("zIndex");
4728              }
4729              this.helper.css("zIndex", o.zIndex);
4730          }
4731  
4732          //Prepare scrolling
4733          if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4734              this.overflowOffset = this.scrollParent.offset();
4735          }
4736  
4737          //Call callbacks
4738          this._trigger("start", event, this._uiHash());
4739  
4740          //Recache the helper size
4741          if(!this._preserveHelperProportions) {
4742              this._cacheHelperProportions();
4743          }
4744  
4745  
4746          //Post "activate" events to possible containers
4747          if( !noActivation ) {
4748              for ( i = this.containers.length - 1; i >= 0; i-- ) {
4749                  this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4750              }
4751          }
4752  
4753          //Prepare possible droppables
4754          if($.ui.ddmanager) {
4755              $.ui.ddmanager.current = this;
4756          }
4757  
4758          if ($.ui.ddmanager && !o.dropBehaviour) {
4759              $.ui.ddmanager.prepareOffsets(this, event);
4760          }
4761  
4762          this.dragging = true;
4763  
4764          this.helper.addClass("ui-sortable-helper");
4765          this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4766          return true;
4767  
4768      },
4769  
4770      _mouseDrag: function(event) {
4771          var i, item, itemElement, intersection,
4772              o = this.options,
4773              scrolled = false;
4774  
4775          //Compute the helpers position
4776          this.position = this._generatePosition(event);
4777          this.positionAbs = this._convertPositionTo("absolute");
4778  
4779          if (!this.lastPositionAbs) {
4780              this.lastPositionAbs = this.positionAbs;
4781          }
4782  
4783          //Do scrolling
4784          if(this.options.scroll) {
4785              if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
4786  
4787                  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4788                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4789                  } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4790                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4791                  }
4792  
4793                  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4794                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4795                  } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4796                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4797                  }
4798  
4799              } else {
4800  
4801                  if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
4802                      scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
4803                  } else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
4804                      scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
4805                  }
4806  
4807                  if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
4808                      scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
4809                  } else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
4810                      scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
4811                  }
4812  
4813              }
4814  
4815              if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4816                  $.ui.ddmanager.prepareOffsets(this, event);
4817              }
4818          }
4819  
4820          //Regenerate the absolute position used for position checks
4821          this.positionAbs = this._convertPositionTo("absolute");
4822  
4823          //Set the helper position
4824          if(!this.options.axis || this.options.axis !== "y") {
4825              this.helper[0].style.left = this.position.left+"px";
4826          }
4827          if(!this.options.axis || this.options.axis !== "x") {
4828              this.helper[0].style.top = this.position.top+"px";
4829          }
4830  
4831          //Rearrange
4832          for (i = this.items.length - 1; i >= 0; i--) {
4833  
4834              //Cache variables and intersection, continue if no intersection
4835              item = this.items[i];
4836              itemElement = item.item[0];
4837              intersection = this._intersectsWithPointer(item);
4838              if (!intersection) {
4839                  continue;
4840              }
4841  
4842              // Only put the placeholder inside the current Container, skip all
4843              // items from other containers. This works because when moving
4844              // an item from one container to another the
4845              // currentContainer is switched before the placeholder is moved.
4846              //
4847              // Without this, moving items in "sub-sortables" can cause
4848              // the placeholder to jitter between the outer and inner container.
4849              if (item.instance !== this.currentContainer) {
4850                  continue;
4851              }
4852  
4853              // cannot intersect with itself
4854              // no useless actions that have been done before
4855              // no action if the item moved is the parent of the item checked
4856              if (itemElement !== this.currentItem[0] &&
4857                  this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4858                  !$.contains(this.placeholder[0], itemElement) &&
4859                  (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4860              ) {
4861  
4862                  this.direction = intersection === 1 ? "down" : "up";
4863  
4864                  if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4865                      this._rearrange(event, item);
4866                  } else {
4867                      break;
4868                  }
4869  
4870                  this._trigger("change", event, this._uiHash());
4871                  break;
4872              }
4873          }
4874  
4875          //Post events to containers
4876          this._contactContainers(event);
4877  
4878          //Interconnect with droppables
4879          if($.ui.ddmanager) {
4880              $.ui.ddmanager.drag(this, event);
4881          }
4882  
4883          //Call callbacks
4884          this._trigger("sort", event, this._uiHash());
4885  
4886          this.lastPositionAbs = this.positionAbs;
4887          return false;
4888  
4889      },
4890  
4891      _mouseStop: function(event, noPropagation) {
4892  
4893          if(!event) {
4894              return;
4895          }
4896  
4897          //If we are using droppables, inform the manager about the drop
4898          if ($.ui.ddmanager && !this.options.dropBehaviour) {
4899              $.ui.ddmanager.drop(this, event);
4900          }
4901  
4902          if(this.options.revert) {
4903              var that = this,
4904                  cur = this.placeholder.offset(),
4905                  axis = this.options.axis,
4906                  animation = {};
4907  
4908              if ( !axis || axis === "x" ) {
4909                  animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
4910              }
4911              if ( !axis || axis === "y" ) {
4912                  animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
4913              }
4914              this.reverting = true;
4915              $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4916                  that._clear(event);
4917              });
4918          } else {
4919              this._clear(event, noPropagation);
4920          }
4921  
4922          return false;
4923  
4924      },
4925  
4926      cancel: function() {
4927  
4928          if(this.dragging) {
4929  
4930              this._mouseUp({ target: null });
4931  
4932              if(this.options.helper === "original") {
4933                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4934              } else {
4935                  this.currentItem.show();
4936              }
4937  
4938              //Post deactivating events to containers
4939              for (var i = this.containers.length - 1; i >= 0; i--){
4940                  this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4941                  if(this.containers[i].containerCache.over) {
4942                      this.containers[i]._trigger("out", null, this._uiHash(this));
4943                      this.containers[i].containerCache.over = 0;
4944                  }
4945              }
4946  
4947          }
4948  
4949          if (this.placeholder) {
4950              //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4951              if(this.placeholder[0].parentNode) {
4952                  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4953              }
4954              if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4955                  this.helper.remove();
4956              }
4957  
4958              $.extend(this, {
4959                  helper: null,
4960                  dragging: false,
4961                  reverting: false,
4962                  _noFinalSort: null
4963              });
4964  
4965              if(this.domPosition.prev) {
4966                  $(this.domPosition.prev).after(this.currentItem);
4967              } else {
4968                  $(this.domPosition.parent).prepend(this.currentItem);
4969              }
4970          }
4971  
4972          return this;
4973  
4974      },
4975  
4976      serialize: function(o) {
4977  
4978          var items = this._getItemsAsjQuery(o && o.connected),
4979              str = [];
4980          o = o || {};
4981  
4982          $(items).each(function() {
4983              var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4984              if (res) {
4985                  str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4986              }
4987          });
4988  
4989          if(!str.length && o.key) {
4990              str.push(o.key + "=");
4991          }
4992  
4993          return str.join("&");
4994  
4995      },
4996  
4997      toArray: function(o) {
4998  
4999          var items = this._getItemsAsjQuery(o && o.connected),
5000              ret = [];
5001  
5002          o = o || {};
5003  
5004          items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
5005          return ret;
5006  
5007      },
5008  
5009      /* Be careful with the following core functions */
5010      _intersectsWith: function(item) {
5011  
5012          var x1 = this.positionAbs.left,
5013              x2 = x1 + this.helperProportions.width,
5014              y1 = this.positionAbs.top,
5015              y2 = y1 + this.helperProportions.height,
5016              l = item.left,
5017              r = l + item.width,
5018              t = item.top,
5019              b = t + item.height,
5020              dyClick = this.offset.click.top,
5021              dxClick = this.offset.click.left,
5022              isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
5023              isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
5024              isOverElement = isOverElementHeight && isOverElementWidth;
5025  
5026          if ( this.options.tolerance === "pointer" ||
5027              this.options.forcePointerForContainers ||
5028              (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
5029          ) {
5030              return isOverElement;
5031          } else {
5032  
5033              return (l < x1 + (this.helperProportions.width / 2) && // Right Half
5034                  x2 - (this.helperProportions.width / 2) < r && // Left Half
5035                  t < y1 + (this.helperProportions.height / 2) && // Bottom Half
5036                  y2 - (this.helperProportions.height / 2) < b ); // Top Half
5037  
5038          }
5039      },
5040  
5041      _intersectsWithPointer: function(item) {
5042  
5043          var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
5044              isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
5045              isOverElement = isOverElementHeight && isOverElementWidth,
5046              verticalDirection = this._getDragVerticalDirection(),
5047              horizontalDirection = this._getDragHorizontalDirection();
5048  
5049          if (!isOverElement) {
5050              return false;
5051          }
5052  
5053          return this.floating ?
5054              ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
5055              : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
5056  
5057      },
5058  
5059      _intersectsWithSides: function(item) {
5060  
5061          var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
5062              isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
5063              verticalDirection = this._getDragVerticalDirection(),
5064              horizontalDirection = this._getDragHorizontalDirection();
5065  
5066          if (this.floating && horizontalDirection) {
5067              return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
5068          } else {
5069              return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
5070          }
5071  
5072      },
5073  
5074      _getDragVerticalDirection: function() {
5075          var delta = this.positionAbs.top - this.lastPositionAbs.top;
5076          return delta !== 0 && (delta > 0 ? "down" : "up");
5077      },
5078  
5079      _getDragHorizontalDirection: function() {
5080          var delta = this.positionAbs.left - this.lastPositionAbs.left;
5081          return delta !== 0 && (delta > 0 ? "right" : "left");
5082      },
5083  
5084      refresh: function(event) {
5085          this._refreshItems(event);
5086          this._setHandleClassName();
5087          this.refreshPositions();
5088          return this;
5089      },
5090  
5091      _connectWith: function() {
5092          var options = this.options;
5093          return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
5094      },
5095  
5096      _getItemsAsjQuery: function(connected) {
5097  
5098          var i, j, cur, inst,
5099              items = [],
5100              queries = [],
5101              connectWith = this._connectWith();
5102  
5103          if(connectWith && connected) {
5104              for (i = connectWith.length - 1; i >= 0; i--){
5105                  cur = $(connectWith[i], this.document[0]);
5106                  for ( j = cur.length - 1; j >= 0; j--){
5107                      inst = $.data(cur[j], this.widgetFullName);
5108                      if(inst && inst !== this && !inst.options.disabled) {
5109                          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]);
5110                      }
5111                  }
5112              }
5113          }
5114  
5115          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]);
5116  
5117  		function addItems() {
5118              items.push( this );
5119          }
5120          for (i = queries.length - 1; i >= 0; i--){
5121              queries[i][0].each( addItems );
5122          }
5123  
5124          return $(items);
5125  
5126      },
5127  
5128      _removeCurrentsFromItems: function() {
5129  
5130          var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
5131  
5132          this.items = $.grep(this.items, function (item) {
5133              for (var j=0; j < list.length; j++) {
5134                  if(list[j] === item.item[0]) {
5135                      return false;
5136                  }
5137              }
5138              return true;
5139          });
5140  
5141      },
5142  
5143      _refreshItems: function(event) {
5144  
5145          this.items = [];
5146          this.containers = [this];
5147  
5148          var i, j, cur, inst, targetData, _queries, item, queriesLength,
5149              items = this.items,
5150              queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
5151              connectWith = this._connectWith();
5152  
5153          if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
5154              for (i = connectWith.length - 1; i >= 0; i--){
5155                  cur = $(connectWith[i], this.document[0]);
5156                  for (j = cur.length - 1; j >= 0; j--){
5157                      inst = $.data(cur[j], this.widgetFullName);
5158                      if(inst && inst !== this && !inst.options.disabled) {
5159                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
5160                          this.containers.push(inst);
5161                      }
5162                  }
5163              }
5164          }
5165  
5166          for (i = queries.length - 1; i >= 0; i--) {
5167              targetData = queries[i][1];
5168              _queries = queries[i][0];
5169  
5170              for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
5171                  item = $(_queries[j]);
5172  
5173                  item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
5174  
5175                  items.push({
5176                      item: item,
5177                      instance: targetData,
5178                      width: 0, height: 0,
5179                      left: 0, top: 0
5180                  });
5181              }
5182          }
5183  
5184      },
5185  
5186      refreshPositions: function(fast) {
5187  
5188          // Determine whether items are being displayed horizontally
5189          this.floating = this.items.length ?
5190              this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5191              false;
5192  
5193          //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
5194          if(this.offsetParent && this.helper) {
5195              this.offset.parent = this._getParentOffset();
5196          }
5197  
5198          var i, item, t, p;
5199  
5200          for (i = this.items.length - 1; i >= 0; i--){
5201              item = this.items[i];
5202  
5203              //We ignore calculating positions of all connected containers when we're not over them
5204              if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
5205                  continue;
5206              }
5207  
5208              t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
5209  
5210              if (!fast) {
5211                  item.width = t.outerWidth();
5212                  item.height = t.outerHeight();
5213              }
5214  
5215              p = t.offset();
5216              item.left = p.left;
5217              item.top = p.top;
5218          }
5219  
5220          if(this.options.custom && this.options.custom.refreshContainers) {
5221              this.options.custom.refreshContainers.call(this);
5222          } else {
5223              for (i = this.containers.length - 1; i >= 0; i--){
5224                  p = this.containers[i].element.offset();
5225                  this.containers[i].containerCache.left = p.left;
5226                  this.containers[i].containerCache.top = p.top;
5227                  this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
5228                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
5229              }
5230          }
5231  
5232          return this;
5233      },
5234  
5235      _createPlaceholder: function(that) {
5236          that = that || this;
5237          var className,
5238              o = that.options;
5239  
5240          if(!o.placeholder || o.placeholder.constructor === String) {
5241              className = o.placeholder;
5242              o.placeholder = {
5243                  element: function() {
5244  
5245                      var nodeName = that.currentItem[0].nodeName.toLowerCase(),
5246                          element = $( "<" + nodeName + ">", that.document[0] )
5247                              .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
5248                              .removeClass("ui-sortable-helper");
5249  
5250                      if ( nodeName === "tbody" ) {
5251                          that._createTrPlaceholder(
5252                              that.currentItem.find( "tr" ).eq( 0 ),
5253                              $( "<tr>", that.document[ 0 ] ).appendTo( element )
5254                          );
5255                      } else if ( nodeName === "tr" ) {
5256                          that._createTrPlaceholder( that.currentItem, element );
5257                      } else if ( nodeName === "img" ) {
5258                          element.attr( "src", that.currentItem.attr( "src" ) );
5259                      }
5260  
5261                      if ( !className ) {
5262                          element.css( "visibility", "hidden" );
5263                      }
5264  
5265                      return element;
5266                  },
5267                  update: function(container, p) {
5268  
5269                      // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
5270                      // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
5271                      if(className && !o.forcePlaceholderSize) {
5272                          return;
5273                      }
5274  
5275                      //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
5276                      if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
5277                      if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
5278                  }
5279              };
5280          }
5281  
5282          //Create the placeholder
5283          that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
5284  
5285          //Append it after the actual current item
5286          that.currentItem.after(that.placeholder);
5287  
5288          //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5289          o.placeholder.update(that, that.placeholder);
5290  
5291      },
5292  
5293      _createTrPlaceholder: function( sourceTr, targetTr ) {
5294          var that = this;
5295  
5296          sourceTr.children().each(function() {
5297              $( "<td>&#160;</td>", that.document[ 0 ] )
5298                  .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5299                  .appendTo( targetTr );
5300          });
5301      },
5302  
5303      _contactContainers: function(event) {
5304          var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
5305              innermostContainer = null,
5306              innermostIndex = null;
5307  
5308          // get innermost container that intersects with item
5309          for (i = this.containers.length - 1; i >= 0; i--) {
5310  
5311              // never consider a container that's located within the item itself
5312              if($.contains(this.currentItem[0], this.containers[i].element[0])) {
5313                  continue;
5314              }
5315  
5316              if(this._intersectsWith(this.containers[i].containerCache)) {
5317  
5318                  // if we've already found a container and it's more "inner" than this, then continue
5319                  if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
5320                      continue;
5321                  }
5322  
5323                  innermostContainer = this.containers[i];
5324                  innermostIndex = i;
5325  
5326              } else {
5327                  // container doesn't intersect. trigger "out" event if necessary
5328                  if(this.containers[i].containerCache.over) {
5329                      this.containers[i]._trigger("out", event, this._uiHash(this));
5330                      this.containers[i].containerCache.over = 0;
5331                  }
5332              }
5333  
5334          }
5335  
5336          // if no intersecting containers found, return
5337          if(!innermostContainer) {
5338              return;
5339          }
5340  
5341          // move the item into the container if it's not there already
5342          if(this.containers.length === 1) {
5343              if (!this.containers[innermostIndex].containerCache.over) {
5344                  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5345                  this.containers[innermostIndex].containerCache.over = 1;
5346              }
5347          } else {
5348  
5349              //When entering a new container, we will find the item with the least distance and append our item near it
5350              dist = 10000;
5351              itemWithLeastDistance = null;
5352              floating = innermostContainer.floating || this._isFloating(this.currentItem);
5353              posProperty = floating ? "left" : "top";
5354              sizeProperty = floating ? "width" : "height";
5355              axis = floating ? "clientX" : "clientY";
5356  
5357              for (j = this.items.length - 1; j >= 0; j--) {
5358                  if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
5359                      continue;
5360                  }
5361                  if(this.items[j].item[0] === this.currentItem[0]) {
5362                      continue;
5363                  }
5364  
5365                  cur = this.items[j].item.offset()[posProperty];
5366                  nearBottom = false;
5367                  if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5368                      nearBottom = true;
5369                  }
5370  
5371                  if ( Math.abs( event[ axis ] - cur ) < dist ) {
5372                      dist = Math.abs( event[ axis ] - cur );
5373                      itemWithLeastDistance = this.items[ j ];
5374                      this.direction = nearBottom ? "up": "down";
5375                  }
5376              }
5377  
5378              //Check if dropOnEmpty is enabled
5379              if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
5380                  return;
5381              }
5382  
5383              if(this.currentContainer === this.containers[innermostIndex]) {
5384                  if ( !this.currentContainer.containerCache.over ) {
5385                      this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5386                      this.currentContainer.containerCache.over = 1;
5387                  }
5388                  return;
5389              }
5390  
5391              itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
5392              this._trigger("change", event, this._uiHash());
5393              this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
5394              this.currentContainer = this.containers[innermostIndex];
5395  
5396              //Update the placeholder
5397              this.options.placeholder.update(this.currentContainer, this.placeholder);
5398  
5399              this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
5400              this.containers[innermostIndex].containerCache.over = 1;
5401          }
5402  
5403  
5404      },
5405  
5406      _createHelper: function(event) {
5407  
5408          var o = this.options,
5409              helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
5410  
5411          //Add the helper to the DOM if that didn't happen already
5412          if(!helper.parents("body").length) {
5413              $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
5414          }
5415  
5416          if(helper[0] === this.currentItem[0]) {
5417              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") };
5418          }
5419  
5420          if(!helper[0].style.width || o.forceHelperSize) {
5421              helper.width(this.currentItem.width());
5422          }
5423          if(!helper[0].style.height || o.forceHelperSize) {
5424              helper.height(this.currentItem.height());
5425          }
5426  
5427          return helper;
5428  
5429      },
5430  
5431      _adjustOffsetFromHelper: function(obj) {
5432          if (typeof obj === "string") {
5433              obj = obj.split(" ");
5434          }
5435          if ($.isArray(obj)) {
5436              obj = {left: +obj[0], top: +obj[1] || 0};
5437          }
5438          if ("left" in obj) {
5439              this.offset.click.left = obj.left + this.margins.left;
5440          }
5441          if ("right" in obj) {
5442              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5443          }
5444          if ("top" in obj) {
5445              this.offset.click.top = obj.top + this.margins.top;
5446          }
5447          if ("bottom" in obj) {
5448              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5449          }
5450      },
5451  
5452      _getParentOffset: function() {
5453  
5454  
5455          //Get the offsetParent and cache its position
5456          this.offsetParent = this.helper.offsetParent();
5457          var po = this.offsetParent.offset();
5458  
5459          // This is a special case where we need to modify a offset calculated on start, since the following happened:
5460          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
5461          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
5462          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
5463          if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
5464              po.left += this.scrollParent.scrollLeft();
5465              po.top += this.scrollParent.scrollTop();
5466          }
5467  
5468          // This needs to be actually done for all browsers, since pageX/pageY includes this information
5469          // with an ugly IE fix
5470          if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
5471              po = { top: 0, left: 0 };
5472          }
5473  
5474          return {
5475              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
5476              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
5477          };
5478  
5479      },
5480  
5481      _getRelativeOffset: function() {
5482  
5483          if(this.cssPosition === "relative") {
5484              var p = this.currentItem.position();
5485              return {
5486                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
5487                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
5488              };
5489          } else {
5490              return { top: 0, left: 0 };
5491          }
5492  
5493      },
5494  
5495      _cacheMargins: function() {
5496          this.margins = {
5497              left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
5498              top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
5499          };
5500      },
5501  
5502      _cacheHelperProportions: function() {
5503          this.helperProportions = {
5504              width: this.helper.outerWidth(),
5505              height: this.helper.outerHeight()
5506          };
5507      },
5508  
5509      _setContainment: function() {
5510  
5511          var ce, co, over,
5512              o = this.options;
5513          if(o.containment === "parent") {
5514              o.containment = this.helper[0].parentNode;
5515          }
5516          if(o.containment === "document" || o.containment === "window") {
5517              this.containment = [
5518                  0 - this.offset.relative.left - this.offset.parent.left,
5519                  0 - this.offset.relative.top - this.offset.parent.top,
5520                  o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
5521                  (o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
5522              ];
5523          }
5524  
5525          if(!(/^(document|window|parent)$/).test(o.containment)) {
5526              ce = $(o.containment)[0];
5527              co = $(o.containment).offset();
5528              over = ($(ce).css("overflow") !== "hidden");
5529  
5530              this.containment = [
5531                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5532                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5533                  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,
5534                  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
5535              ];
5536          }
5537  
5538      },
5539  
5540      _convertPositionTo: function(d, pos) {
5541  
5542          if(!pos) {
5543              pos = this.position;
5544          }
5545          var mod = d === "absolute" ? 1 : -1,
5546              scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5547              scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5548  
5549          return {
5550              top: (
5551                  pos.top    +                                                                // The absolute mouse position
5552                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
5553                  this.offset.parent.top * mod -                                            // The offsetParent's offset without borders (offset + border)
5554                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5555              ),
5556              left: (
5557                  pos.left +                                                                // The absolute mouse position
5558                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
5559                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
5560                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5561              )
5562          };
5563  
5564      },
5565  
5566      _generatePosition: function(event) {
5567  
5568          var top, left,
5569              o = this.options,
5570              pageX = event.pageX,
5571              pageY = event.pageY,
5572              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);
5573  
5574          // This is another very weird special case that only happens for relative elements:
5575          // 1. If the css position is relative
5576          // 2. and the scroll parent is the document or similar to the offset parent
5577          // we have to refresh the relative offset during the scroll so there are no jumps
5578          if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
5579              this.offset.relative = this._getRelativeOffset();
5580          }
5581  
5582          /*
5583           * - Position constraining -
5584           * Constrain the position to a mix of grid, containment.
5585           */
5586  
5587          if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5588  
5589              if(this.containment) {
5590                  if(event.pageX - this.offset.click.left < this.containment[0]) {
5591                      pageX = this.containment[0] + this.offset.click.left;
5592                  }
5593                  if(event.pageY - this.offset.click.top < this.containment[1]) {
5594                      pageY = this.containment[1] + this.offset.click.top;
5595                  }
5596                  if(event.pageX - this.offset.click.left > this.containment[2]) {
5597                      pageX = this.containment[2] + this.offset.click.left;
5598                  }
5599                  if(event.pageY - this.offset.click.top > this.containment[3]) {
5600                      pageY = this.containment[3] + this.offset.click.top;
5601                  }
5602              }
5603  
5604              if(o.grid) {
5605                  top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5606                  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;
5607  
5608                  left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5609                  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;
5610              }
5611  
5612          }
5613  
5614          return {
5615              top: (
5616                  pageY -                                                                // The absolute mouse position
5617                  this.offset.click.top -                                                    // Click offset (relative to the element)
5618                  this.offset.relative.top    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
5619                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
5620                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5621              ),
5622              left: (
5623                  pageX -                                                                // The absolute mouse position
5624                  this.offset.click.left -                                                // Click offset (relative to the element)
5625                  this.offset.relative.left    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
5626                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
5627                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5628              )
5629          };
5630  
5631      },
5632  
5633      _rearrange: function(event, i, a, hardRefresh) {
5634  
5635          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));
5636  
5637          //Various things done here to improve the performance:
5638          // 1. we create a setTimeout, that calls refreshPositions
5639          // 2. on the instance, we have a counter variable, that get's higher after every append
5640          // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5641          // 4. this lets only the last addition to the timeout stack through
5642          this.counter = this.counter ? ++this.counter : 1;
5643          var counter = this.counter;
5644  
5645          this._delay(function() {
5646              if(counter === this.counter) {
5647                  this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5648              }
5649          });
5650  
5651      },
5652  
5653      _clear: function(event, noPropagation) {
5654  
5655          this.reverting = false;
5656          // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5657          // everything else normalized again
5658          var i,
5659              delayedTriggers = [];
5660  
5661          // We first have to update the dom position of the actual currentItem
5662          // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5663          if(!this._noFinalSort && this.currentItem.parent().length) {
5664              this.placeholder.before(this.currentItem);
5665          }
5666          this._noFinalSort = null;
5667  
5668          if(this.helper[0] === this.currentItem[0]) {
5669              for(i in this._storedCSS) {
5670                  if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5671                      this._storedCSS[i] = "";
5672                  }
5673              }
5674              this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5675          } else {
5676              this.currentItem.show();
5677          }
5678  
5679          if(this.fromOutside && !noPropagation) {
5680              delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5681          }
5682          if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5683              delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5684          }
5685  
5686          // Check if the items Container has Changed and trigger appropriate
5687          // events.
5688          if (this !== this.currentContainer) {
5689              if(!noPropagation) {
5690                  delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5691                  delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
5692                  delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
5693              }
5694          }
5695  
5696  
5697          //Post events to containers
5698  		function delayEvent( type, instance, container ) {
5699              return function( event ) {
5700                  container._trigger( type, event, instance._uiHash( instance ) );
5701              };
5702          }
5703          for (i = this.containers.length - 1; i >= 0; i--){
5704              if (!noPropagation) {
5705                  delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5706              }
5707              if(this.containers[i].containerCache.over) {
5708                  delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5709                  this.containers[i].containerCache.over = 0;
5710              }
5711          }
5712  
5713          //Do what was originally in plugins
5714          if ( this.storedCursor ) {
5715              this.document.find( "body" ).css( "cursor", this.storedCursor );
5716              this.storedStylesheet.remove();
5717          }
5718          if(this._storedOpacity) {
5719              this.helper.css("opacity", this._storedOpacity);
5720          }
5721          if(this._storedZIndex) {
5722              this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5723          }
5724  
5725          this.dragging = false;
5726  
5727          if(!noPropagation) {
5728              this._trigger("beforeStop", event, this._uiHash());
5729          }
5730  
5731          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5732          this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5733  
5734          if ( !this.cancelHelperRemoval ) {
5735              if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5736                  this.helper.remove();
5737              }
5738              this.helper = null;
5739          }
5740  
5741          if(!noPropagation) {
5742              for (i=0; i < delayedTriggers.length; i++) {
5743                  delayedTriggers[i].call(this, event);
5744              } //Trigger all delayed events
5745              this._trigger("stop", event, this._uiHash());
5746          }
5747  
5748          this.fromOutside = false;
5749          return !this.cancelHelperRemoval;
5750  
5751      },
5752  
5753      _trigger: function() {
5754          if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5755              this.cancel();
5756          }
5757      },
5758  
5759      _uiHash: function(_inst) {
5760          var inst = _inst || this;
5761          return {
5762              helper: inst.helper,
5763              placeholder: inst.placeholder || $([]),
5764              position: inst.position,
5765              originalPosition: inst.originalPosition,
5766              offset: inst.positionAbs,
5767              item: inst.currentItem,
5768              sender: _inst ? _inst.element : null
5769          };
5770      }
5771  
5772  });
5773  
5774  
5775  /*!
5776   * jQuery UI Accordion 1.11.4
5777   * http://jqueryui.com
5778   *
5779   * Copyright jQuery Foundation and other contributors
5780   * Released under the MIT license.
5781   * http://jquery.org/license
5782   *
5783   * http://api.jqueryui.com/accordion/
5784   */
5785  
5786  
5787  var accordion = $.widget( "ui.accordion", {
5788      version: "1.11.4",
5789      options: {
5790          active: 0,
5791          animate: {},
5792          collapsible: false,
5793          event: "click",
5794          header: "> li > :first-child,> :not(li):even",
5795          heightStyle: "auto",
5796          icons: {
5797              activeHeader: "ui-icon-triangle-1-s",
5798              header: "ui-icon-triangle-1-e"
5799          },
5800  
5801          // callbacks
5802          activate: null,
5803          beforeActivate: null
5804      },
5805  
5806      hideProps: {
5807          borderTopWidth: "hide",
5808          borderBottomWidth: "hide",
5809          paddingTop: "hide",
5810          paddingBottom: "hide",
5811          height: "hide"
5812      },
5813  
5814      showProps: {
5815          borderTopWidth: "show",
5816          borderBottomWidth: "show",
5817          paddingTop: "show",
5818          paddingBottom: "show",
5819          height: "show"
5820      },
5821  
5822      _create: function() {
5823          var options = this.options;
5824          this.prevShow = this.prevHide = $();
5825          this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5826              // ARIA
5827              .attr( "role", "tablist" );
5828  
5829          // don't allow collapsible: false and active: false / null
5830          if ( !options.collapsible && (options.active === false || options.active == null) ) {
5831              options.active = 0;
5832          }
5833  
5834          this._processPanels();
5835          // handle negative values
5836          if ( options.active < 0 ) {
5837              options.active += this.headers.length;
5838          }
5839          this._refresh();
5840      },
5841  
5842      _getCreateEventData: function() {
5843          return {
5844              header: this.active,
5845              panel: !this.active.length ? $() : this.active.next()
5846          };
5847      },
5848  
5849      _createIcons: function() {
5850          var icons = this.options.icons;
5851          if ( icons ) {
5852              $( "<span>" )
5853                  .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5854                  .prependTo( this.headers );
5855              this.active.children( ".ui-accordion-header-icon" )
5856                  .removeClass( icons.header )
5857                  .addClass( icons.activeHeader );
5858              this.headers.addClass( "ui-accordion-icons" );
5859          }
5860      },
5861  
5862      _destroyIcons: function() {
5863          this.headers
5864              .removeClass( "ui-accordion-icons" )
5865              .children( ".ui-accordion-header-icon" )
5866                  .remove();
5867      },
5868  
5869      _destroy: function() {
5870          var contents;
5871  
5872          // clean up main element
5873          this.element
5874              .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5875              .removeAttr( "role" );
5876  
5877          // clean up headers
5878          this.headers
5879              .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
5880                  "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5881              .removeAttr( "role" )
5882              .removeAttr( "aria-expanded" )
5883              .removeAttr( "aria-selected" )
5884              .removeAttr( "aria-controls" )
5885              .removeAttr( "tabIndex" )
5886              .removeUniqueId();
5887  
5888          this._destroyIcons();
5889  
5890          // clean up content panels
5891          contents = this.headers.next()
5892              .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
5893                  "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5894              .css( "display", "" )
5895              .removeAttr( "role" )
5896              .removeAttr( "aria-hidden" )
5897              .removeAttr( "aria-labelledby" )
5898              .removeUniqueId();
5899  
5900          if ( this.options.heightStyle !== "content" ) {
5901              contents.css( "height", "" );
5902          }
5903      },
5904  
5905      _setOption: function( key, value ) {
5906          if ( key === "active" ) {
5907              // _activate() will handle invalid values and update this.options
5908              this._activate( value );
5909              return;
5910          }
5911  
5912          if ( key === "event" ) {
5913              if ( this.options.event ) {
5914                  this._off( this.headers, this.options.event );
5915              }
5916              this._setupEvents( value );
5917          }
5918  
5919          this._super( key, value );
5920  
5921          // setting collapsible: false while collapsed; open first panel
5922          if ( key === "collapsible" && !value && this.options.active === false ) {
5923              this._activate( 0 );
5924          }
5925  
5926          if ( key === "icons" ) {
5927              this._destroyIcons();
5928              if ( value ) {
5929                  this._createIcons();
5930              }
5931          }
5932  
5933          // #5332 - opacity doesn't cascade to positioned elements in IE
5934          // so we need to add the disabled class to the headers and panels
5935          if ( key === "disabled" ) {
5936              this.element
5937                  .toggleClass( "ui-state-disabled", !!value )
5938                  .attr( "aria-disabled", value );
5939              this.headers.add( this.headers.next() )
5940                  .toggleClass( "ui-state-disabled", !!value );
5941          }
5942      },
5943  
5944      _keydown: function( event ) {
5945          if ( event.altKey || event.ctrlKey ) {
5946              return;
5947          }
5948  
5949          var keyCode = $.ui.keyCode,
5950              length = this.headers.length,
5951              currentIndex = this.headers.index( event.target ),
5952              toFocus = false;
5953  
5954          switch ( event.keyCode ) {
5955              case keyCode.RIGHT:
5956              case keyCode.DOWN:
5957                  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5958                  break;
5959              case keyCode.LEFT:
5960              case keyCode.UP:
5961                  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5962                  break;
5963              case keyCode.SPACE:
5964              case keyCode.ENTER:
5965                  this._eventHandler( event );
5966                  break;
5967              case keyCode.HOME:
5968                  toFocus = this.headers[ 0 ];
5969                  break;
5970              case keyCode.END:
5971                  toFocus = this.headers[ length - 1 ];
5972                  break;
5973          }
5974  
5975          if ( toFocus ) {
5976              $( event.target ).attr( "tabIndex", -1 );
5977              $( toFocus ).attr( "tabIndex", 0 );
5978              toFocus.focus();
5979              event.preventDefault();
5980          }
5981      },
5982  
5983      _panelKeyDown: function( event ) {
5984          if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5985              $( event.currentTarget ).prev().focus();
5986          }
5987      },
5988  
5989      refresh: function() {
5990          var options = this.options;
5991          this._processPanels();
5992  
5993          // was collapsed or no panel
5994          if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5995              options.active = false;
5996              this.active = $();
5997          // active false only when collapsible is true
5998          } else if ( options.active === false ) {
5999              this._activate( 0 );
6000          // was active, but active panel is gone
6001          } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6002              // all remaining panel are disabled
6003              if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6004                  options.active = false;
6005                  this.active = $();
6006              // activate previous panel
6007              } else {
6008                  this._activate( Math.max( 0, options.active - 1 ) );
6009              }
6010          // was active, active panel still exists
6011          } else {
6012              // make sure active index is correct
6013              options.active = this.headers.index( this.active );
6014          }
6015  
6016          this._destroyIcons();
6017  
6018          this._refresh();
6019      },
6020  
6021      _processPanels: function() {
6022          var prevHeaders = this.headers,
6023              prevPanels = this.panels;
6024  
6025          this.headers = this.element.find( this.options.header )
6026              .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
6027  
6028          this.panels = this.headers.next()
6029              .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6030              .filter( ":not(.ui-accordion-content-active)" )
6031              .hide();
6032  
6033          // Avoid memory leaks (#10056)
6034          if ( prevPanels ) {
6035              this._off( prevHeaders.not( this.headers ) );
6036              this._off( prevPanels.not( this.panels ) );
6037          }
6038      },
6039  
6040      _refresh: function() {
6041          var maxHeight,
6042              options = this.options,
6043              heightStyle = options.heightStyle,
6044              parent = this.element.parent();
6045  
6046          this.active = this._findActive( options.active )
6047              .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6048              .removeClass( "ui-corner-all" );
6049          this.active.next()
6050              .addClass( "ui-accordion-content-active" )
6051              .show();
6052  
6053          this.headers
6054              .attr( "role", "tab" )
6055              .each(function() {
6056                  var header = $( this ),
6057                      headerId = header.uniqueId().attr( "id" ),
6058                      panel = header.next(),
6059                      panelId = panel.uniqueId().attr( "id" );
6060                  header.attr( "aria-controls", panelId );
6061                  panel.attr( "aria-labelledby", headerId );
6062              })
6063              .next()
6064                  .attr( "role", "tabpanel" );
6065  
6066          this.headers
6067              .not( this.active )
6068              .attr({
6069                  "aria-selected": "false",
6070                  "aria-expanded": "false",
6071                  tabIndex: -1
6072              })
6073              .next()
6074                  .attr({
6075                      "aria-hidden": "true"
6076                  })
6077                  .hide();
6078  
6079          // make sure at least one header is in the tab order
6080          if ( !this.active.length ) {
6081              this.headers.eq( 0 ).attr( "tabIndex", 0 );
6082          } else {
6083              this.active.attr({
6084                  "aria-selected": "true",
6085                  "aria-expanded": "true",
6086                  tabIndex: 0
6087              })
6088              .next()
6089                  .attr({
6090                      "aria-hidden": "false"
6091                  });
6092          }
6093  
6094          this._createIcons();
6095  
6096          this._setupEvents( options.event );
6097  
6098          if ( heightStyle === "fill" ) {
6099              maxHeight = parent.height();
6100              this.element.siblings( ":visible" ).each(function() {
6101                  var elem = $( this ),
6102                      position = elem.css( "position" );
6103  
6104                  if ( position === "absolute" || position === "fixed" ) {
6105                      return;
6106                  }
6107                  maxHeight -= elem.outerHeight( true );
6108              });
6109  
6110              this.headers.each(function() {
6111                  maxHeight -= $( this ).outerHeight( true );
6112              });
6113  
6114              this.headers.next()
6115                  .each(function() {
6116                      $( this ).height( Math.max( 0, maxHeight -
6117                          $( this ).innerHeight() + $( this ).height() ) );
6118                  })
6119                  .css( "overflow", "auto" );
6120          } else if ( heightStyle === "auto" ) {
6121              maxHeight = 0;
6122              this.headers.next()
6123                  .each(function() {
6124                      maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6125                  })
6126                  .height( maxHeight );
6127          }
6128      },
6129  
6130      _activate: function( index ) {
6131          var active = this._findActive( index )[ 0 ];
6132  
6133          // trying to activate the already active panel
6134          if ( active === this.active[ 0 ] ) {
6135              return;
6136          }
6137  
6138          // trying to collapse, simulate a click on the currently active header
6139          active = active || this.active[ 0 ];
6140  
6141          this._eventHandler({
6142              target: active,
6143              currentTarget: active,
6144              preventDefault: $.noop
6145          });
6146      },
6147  
6148      _findActive: function( selector ) {
6149          return typeof selector === "number" ? this.headers.eq( selector ) : $();
6150      },
6151  
6152      _setupEvents: function( event ) {
6153          var events = {
6154              keydown: "_keydown"
6155          };
6156          if ( event ) {
6157              $.each( event.split( " " ), function( index, eventName ) {
6158                  events[ eventName ] = "_eventHandler";
6159              });
6160          }
6161  
6162          this._off( this.headers.add( this.headers.next() ) );
6163          this._on( this.headers, events );
6164          this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6165          this._hoverable( this.headers );
6166          this._focusable( this.headers );
6167      },
6168  
6169      _eventHandler: function( event ) {
6170          var options = this.options,
6171              active = this.active,
6172              clicked = $( event.currentTarget ),
6173              clickedIsActive = clicked[ 0 ] === active[ 0 ],
6174              collapsing = clickedIsActive && options.collapsible,
6175              toShow = collapsing ? $() : clicked.next(),
6176              toHide = active.next(),
6177              eventData = {
6178                  oldHeader: active,
6179                  oldPanel: toHide,
6180                  newHeader: collapsing ? $() : clicked,
6181                  newPanel: toShow
6182              };
6183  
6184          event.preventDefault();
6185  
6186          if (
6187                  // click on active header, but not collapsible
6188                  ( clickedIsActive && !options.collapsible ) ||
6189                  // allow canceling activation
6190                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6191              return;
6192          }
6193  
6194          options.active = collapsing ? false : this.headers.index( clicked );
6195  
6196          // when the call to ._toggle() comes after the class changes
6197          // it causes a very odd bug in IE 8 (see #6720)
6198          this.active = clickedIsActive ? $() : clicked;
6199          this._toggle( eventData );
6200  
6201          // switch classes
6202          // corner classes on the previously active header stay after the animation
6203          active.removeClass( "ui-accordion-header-active ui-state-active" );
6204          if ( options.icons ) {
6205              active.children( ".ui-accordion-header-icon" )
6206                  .removeClass( options.icons.activeHeader )
6207                  .addClass( options.icons.header );
6208          }
6209  
6210          if ( !clickedIsActive ) {
6211              clicked
6212                  .removeClass( "ui-corner-all" )
6213                  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6214              if ( options.icons ) {
6215                  clicked.children( ".ui-accordion-header-icon" )
6216                      .removeClass( options.icons.header )
6217                      .addClass( options.icons.activeHeader );
6218              }
6219  
6220              clicked
6221                  .next()
6222                  .addClass( "ui-accordion-content-active" );
6223          }
6224      },
6225  
6226      _toggle: function( data ) {
6227          var toShow = data.newPanel,
6228              toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6229  
6230          // handle activating a panel during the animation for another activation
6231          this.prevShow.add( this.prevHide ).stop( true, true );
6232          this.prevShow = toShow;
6233          this.prevHide = toHide;
6234  
6235          if ( this.options.animate ) {
6236              this._animate( toShow, toHide, data );
6237          } else {
6238              toHide.hide();
6239              toShow.show();
6240              this._toggleComplete( data );
6241          }
6242  
6243          toHide.attr({
6244              "aria-hidden": "true"
6245          });
6246          toHide.prev().attr({
6247              "aria-selected": "false",
6248              "aria-expanded": "false"
6249          });
6250          // if we're switching panels, remove the old header from the tab order
6251          // if we're opening from collapsed state, remove the previous header from the tab order
6252          // if we're collapsing, then keep the collapsing header in the tab order
6253          if ( toShow.length && toHide.length ) {
6254              toHide.prev().attr({
6255                  "tabIndex": -1,
6256                  "aria-expanded": "false"
6257              });
6258          } else if ( toShow.length ) {
6259              this.headers.filter(function() {
6260                  return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
6261              })
6262              .attr( "tabIndex", -1 );
6263          }
6264  
6265          toShow
6266              .attr( "aria-hidden", "false" )
6267              .prev()
6268                  .attr({
6269                      "aria-selected": "true",
6270                      "aria-expanded": "true",
6271                      tabIndex: 0
6272                  });
6273      },
6274  
6275      _animate: function( toShow, toHide, data ) {
6276          var total, easing, duration,
6277              that = this,
6278              adjust = 0,
6279              boxSizing = toShow.css( "box-sizing" ),
6280              down = toShow.length &&
6281                  ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6282              animate = this.options.animate || {},
6283              options = down && animate.down || animate,
6284              complete = function() {
6285                  that._toggleComplete( data );
6286              };
6287  
6288          if ( typeof options === "number" ) {
6289              duration = options;
6290          }
6291          if ( typeof options === "string" ) {
6292              easing = options;
6293          }
6294          // fall back from options to animation in case of partial down settings
6295          easing = easing || options.easing || animate.easing;
6296          duration = duration || options.duration || animate.duration;
6297  
6298          if ( !toHide.length ) {
6299              return toShow.animate( this.showProps, duration, easing, complete );
6300          }
6301          if ( !toShow.length ) {
6302              return toHide.animate( this.hideProps, duration, easing, complete );
6303          }
6304  
6305          total = toShow.show().outerHeight();
6306          toHide.animate( this.hideProps, {
6307              duration: duration,
6308              easing: easing,
6309              step: function( now, fx ) {
6310                  fx.now = Math.round( now );
6311              }
6312          });
6313          toShow
6314              .hide()
6315              .animate( this.showProps, {
6316                  duration: duration,
6317                  easing: easing,
6318                  complete: complete,
6319                  step: function( now, fx ) {
6320                      fx.now = Math.round( now );
6321                      if ( fx.prop !== "height" ) {
6322                          if ( boxSizing === "content-box" ) {
6323                              adjust += fx.now;
6324                          }
6325                      } else if ( that.options.heightStyle !== "content" ) {
6326                          fx.now = Math.round( total - toHide.outerHeight() - adjust );
6327                          adjust = 0;
6328                      }
6329                  }
6330              });
6331      },
6332  
6333      _toggleComplete: function( data ) {
6334          var toHide = data.oldPanel;
6335  
6336          toHide
6337              .removeClass( "ui-accordion-content-active" )
6338              .prev()
6339                  .removeClass( "ui-corner-top" )
6340                  .addClass( "ui-corner-all" );
6341  
6342          // Work around for rendering bug in IE (#5421)
6343          if ( toHide.length ) {
6344              toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
6345          }
6346          this._trigger( "activate", null, data );
6347      }
6348  });
6349  
6350  
6351  /*!
6352   * jQuery UI Menu 1.11.4
6353   * http://jqueryui.com
6354   *
6355   * Copyright jQuery Foundation and other contributors
6356   * Released under the MIT license.
6357   * http://jquery.org/license
6358   *
6359   * http://api.jqueryui.com/menu/
6360   */
6361  
6362  
6363  var menu = $.widget( "ui.menu", {
6364      version: "1.11.4",
6365      defaultElement: "<ul>",
6366      delay: 300,
6367      options: {
6368          icons: {
6369              submenu: "ui-icon-carat-1-e"
6370          },
6371          items: "> *",
6372          menus: "ul",
6373          position: {
6374              my: "left-1 top",
6375              at: "right top"
6376          },
6377          role: "menu",
6378  
6379          // callbacks
6380          blur: null,
6381          focus: null,
6382          select: null
6383      },
6384  
6385      _create: function() {
6386          this.activeMenu = this.element;
6387  
6388          // Flag used to prevent firing of the click handler
6389          // as the event bubbles up through nested menus
6390          this.mouseHandled = false;
6391          this.element
6392              .uniqueId()
6393              .addClass( "ui-menu ui-widget ui-widget-content" )
6394              .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
6395              .attr({
6396                  role: this.options.role,
6397                  tabIndex: 0
6398              });
6399  
6400          if ( this.options.disabled ) {
6401              this.element
6402                  .addClass( "ui-state-disabled" )
6403                  .attr( "aria-disabled", "true" );
6404          }
6405  
6406          this._on({
6407              // Prevent focus from sticking to links inside menu after clicking
6408              // them (focus should always stay on UL during navigation).
6409              "mousedown .ui-menu-item": function( event ) {
6410                  event.preventDefault();
6411              },
6412              "click .ui-menu-item": function( event ) {
6413                  var target = $( event.target );
6414                  if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
6415                      this.select( event );
6416  
6417                      // Only set the mouseHandled flag if the event will bubble, see #9469.
6418                      if ( !event.isPropagationStopped() ) {
6419                          this.mouseHandled = true;
6420                      }
6421  
6422                      // Open submenu on click
6423                      if ( target.has( ".ui-menu" ).length ) {
6424                          this.expand( event );
6425                      } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
6426  
6427                          // Redirect focus to the menu
6428                          this.element.trigger( "focus", [ true ] );
6429  
6430                          // If the active item is on the top level, let it stay active.
6431                          // Otherwise, blur the active item since it is no longer visible.
6432                          if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
6433                              clearTimeout( this.timer );
6434                          }
6435                      }
6436                  }
6437              },
6438              "mouseenter .ui-menu-item": function( event ) {
6439                  // Ignore mouse events while typeahead is active, see #10458.
6440                  // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
6441                  // is over an item in the menu
6442                  if ( this.previousFilter ) {
6443                      return;
6444                  }
6445                  var target = $( event.currentTarget );
6446                  // Remove ui-state-active class from siblings of the newly focused menu item
6447                  // to avoid a jump caused by adjacent elements both having a class with a border
6448                  target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
6449                  this.focus( event, target );
6450              },
6451              mouseleave: "collapseAll",
6452              "mouseleave .ui-menu": "collapseAll",
6453              focus: function( event, keepActiveItem ) {
6454                  // If there's already an active item, keep it active
6455                  // If not, activate the first item
6456                  var item = this.active || this.element.find( this.options.items ).eq( 0 );
6457  
6458                  if ( !keepActiveItem ) {
6459                      this.focus( event, item );
6460                  }
6461              },
6462              blur: function( event ) {
6463                  this._delay(function() {
6464                      if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
6465                          this.collapseAll( event );
6466                      }
6467                  });
6468              },
6469              keydown: "_keydown"
6470          });
6471  
6472          this.refresh();
6473  
6474          // Clicks outside of a menu collapse any open menus
6475          this._on( this.document, {
6476              click: function( event ) {
6477                  if ( this._closeOnDocumentClick( event ) ) {
6478                      this.collapseAll( event );
6479                  }
6480  
6481                  // Reset the mouseHandled flag
6482                  this.mouseHandled = false;
6483              }
6484          });
6485      },
6486  
6487      _destroy: function() {
6488          // Destroy (sub)menus
6489          this.element
6490              .removeAttr( "aria-activedescendant" )
6491              .find( ".ui-menu" ).addBack()
6492                  .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
6493                  .removeAttr( "role" )
6494                  .removeAttr( "tabIndex" )
6495                  .removeAttr( "aria-labelledby" )
6496                  .removeAttr( "aria-expanded" )
6497                  .removeAttr( "aria-hidden" )
6498                  .removeAttr( "aria-disabled" )
6499                  .removeUniqueId()
6500                  .show();
6501  
6502          // Destroy menu items
6503          this.element.find( ".ui-menu-item" )
6504              .removeClass( "ui-menu-item" )
6505              .removeAttr( "role" )
6506              .removeAttr( "aria-disabled" )
6507              .removeUniqueId()
6508              .removeClass( "ui-state-hover" )
6509              .removeAttr( "tabIndex" )
6510              .removeAttr( "role" )
6511              .removeAttr( "aria-haspopup" )
6512              .children().each( function() {
6513                  var elem = $( this );
6514                  if ( elem.data( "ui-menu-submenu-carat" ) ) {
6515                      elem.remove();
6516                  }
6517              });
6518  
6519          // Destroy menu dividers
6520          this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
6521      },
6522  
6523      _keydown: function( event ) {
6524          var match, prev, character, skip,
6525              preventDefault = true;
6526  
6527          switch ( event.keyCode ) {
6528          case $.ui.keyCode.PAGE_UP:
6529              this.previousPage( event );
6530              break;
6531          case $.ui.keyCode.PAGE_DOWN:
6532              this.nextPage( event );
6533              break;
6534          case $.ui.keyCode.HOME:
6535              this._move( "first", "first", event );
6536              break;
6537          case $.ui.keyCode.END:
6538              this._move( "last", "last", event );
6539              break;
6540          case $.ui.keyCode.UP:
6541              this.previous( event );
6542              break;
6543          case $.ui.keyCode.DOWN:
6544              this.next( event );
6545              break;
6546          case $.ui.keyCode.LEFT:
6547              this.collapse( event );
6548              break;
6549          case $.ui.keyCode.RIGHT:
6550              if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
6551                  this.expand( event );
6552              }
6553              break;
6554          case $.ui.keyCode.ENTER:
6555          case $.ui.keyCode.SPACE:
6556              this._activate( event );
6557              break;
6558          case $.ui.keyCode.ESCAPE:
6559              this.collapse( event );
6560              break;
6561          default:
6562              preventDefault = false;
6563              prev = this.previousFilter || "";
6564              character = String.fromCharCode( event.keyCode );
6565              skip = false;
6566  
6567              clearTimeout( this.filterTimer );
6568  
6569              if ( character === prev ) {
6570                  skip = true;
6571              } else {
6572                  character = prev + character;
6573              }
6574  
6575              match = this._filterMenuItems( character );
6576              match = skip && match.index( this.active.next() ) !== -1 ?
6577                  this.active.nextAll( ".ui-menu-item" ) :
6578                  match;
6579  
6580              // If no matches on the current filter, reset to the last character pressed
6581              // to move down the menu to the first item that starts with that character
6582              if ( !match.length ) {
6583                  character = String.fromCharCode( event.keyCode );
6584                  match = this._filterMenuItems( character );
6585              }
6586  
6587              if ( match.length ) {
6588                  this.focus( event, match );
6589                  this.previousFilter = character;
6590                  this.filterTimer = this._delay(function() {
6591                      delete this.previousFilter;
6592                  }, 1000 );
6593              } else {
6594                  delete this.previousFilter;
6595              }
6596          }
6597  
6598          if ( preventDefault ) {
6599              event.preventDefault();
6600          }
6601      },
6602  
6603      _activate: function( event ) {
6604          if ( !this.active.is( ".ui-state-disabled" ) ) {
6605              if ( this.active.is( "[aria-haspopup='true']" ) ) {
6606                  this.expand( event );
6607              } else {
6608                  this.select( event );
6609              }
6610          }
6611      },
6612  
6613      refresh: function() {
6614          var menus, items,
6615              that = this,
6616              icon = this.options.icons.submenu,
6617              submenus = this.element.find( this.options.menus );
6618  
6619          this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
6620  
6621          // Initialize nested menus
6622          submenus.filter( ":not(.ui-menu)" )
6623              .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
6624              .hide()
6625              .attr({
6626                  role: this.options.role,
6627                  "aria-hidden": "true",
6628                  "aria-expanded": "false"
6629              })
6630              .each(function() {
6631                  var menu = $( this ),
6632                      item = menu.parent(),
6633                      submenuCarat = $( "<span>" )
6634                          .addClass( "ui-menu-icon ui-icon " + icon )
6635                          .data( "ui-menu-submenu-carat", true );
6636  
6637                  item
6638                      .attr( "aria-haspopup", "true" )
6639                      .prepend( submenuCarat );
6640                  menu.attr( "aria-labelledby", item.attr( "id" ) );
6641              });
6642  
6643          menus = submenus.add( this.element );
6644          items = menus.find( this.options.items );
6645  
6646          // Initialize menu-items containing spaces and/or dashes only as dividers
6647          items.not( ".ui-menu-item" ).each(function() {
6648              var item = $( this );
6649              if ( that._isDivider( item ) ) {
6650                  item.addClass( "ui-widget-content ui-menu-divider" );
6651              }
6652          });
6653  
6654          // Don't refresh list items that are already adapted
6655          items.not( ".ui-menu-item, .ui-menu-divider" )
6656              .addClass( "ui-menu-item" )
6657              .uniqueId()
6658              .attr({
6659                  tabIndex: -1,
6660                  role: this._itemRole()
6661              });
6662  
6663          // Add aria-disabled attribute to any disabled menu item
6664          items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
6665  
6666          // If the active item has been removed, blur the menu
6667          if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6668              this.blur();
6669          }
6670      },
6671  
6672      _itemRole: function() {
6673          return {
6674              menu: "menuitem",
6675              listbox: "option"
6676          }[ this.options.role ];
6677      },
6678  
6679      _setOption: function( key, value ) {
6680          if ( key === "icons" ) {
6681              this.element.find( ".ui-menu-icon" )
6682                  .removeClass( this.options.icons.submenu )
6683                  .addClass( value.submenu );
6684          }
6685          if ( key === "disabled" ) {
6686              this.element
6687                  .toggleClass( "ui-state-disabled", !!value )
6688                  .attr( "aria-disabled", value );
6689          }
6690          this._super( key, value );
6691      },
6692  
6693      focus: function( event, item ) {
6694          var nested, focused;
6695          this.blur( event, event && event.type === "focus" );
6696  
6697          this._scrollIntoView( item );
6698  
6699          this.active = item.first();
6700          focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
6701          // Only update aria-activedescendant if there's a role
6702          // otherwise we assume focus is managed elsewhere
6703          if ( this.options.role ) {
6704              this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
6705          }
6706  
6707          // Highlight active parent menu item, if any
6708          this.active
6709              .parent()
6710              .closest( ".ui-menu-item" )
6711              .addClass( "ui-state-active" );
6712  
6713          if ( event && event.type === "keydown" ) {
6714              this._close();
6715          } else {
6716              this.timer = this._delay(function() {
6717                  this._close();
6718              }, this.delay );
6719          }
6720  
6721          nested = item.children( ".ui-menu" );
6722          if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
6723              this._startOpening(nested);
6724          }
6725          this.activeMenu = item.parent();
6726  
6727          this._trigger( "focus", event, { item: item } );
6728      },
6729  
6730      _scrollIntoView: function( item ) {
6731          var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
6732          if ( this._hasScroll() ) {
6733              borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
6734              paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
6735              offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
6736              scroll = this.activeMenu.scrollTop();
6737              elementHeight = this.activeMenu.height();
6738              itemHeight = item.outerHeight();
6739  
6740              if ( offset < 0 ) {
6741                  this.activeMenu.scrollTop( scroll + offset );
6742              } else if ( offset + itemHeight > elementHeight ) {
6743                  this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
6744              }
6745          }
6746      },
6747  
6748      blur: function( event, fromFocus ) {
6749          if ( !fromFocus ) {
6750              clearTimeout( this.timer );
6751          }
6752  
6753          if ( !this.active ) {
6754              return;
6755          }
6756  
6757          this.active.removeClass( "ui-state-focus" );
6758          this.active = null;
6759  
6760          this._trigger( "blur", event, { item: this.active } );
6761      },
6762  
6763      _startOpening: function( submenu ) {
6764          clearTimeout( this.timer );
6765  
6766          // Don't open if already open fixes a Firefox bug that caused a .5 pixel
6767          // shift in the submenu position when mousing over the carat icon
6768          if ( submenu.attr( "aria-hidden" ) !== "true" ) {
6769              return;
6770          }
6771  
6772          this.timer = this._delay(function() {
6773              this._close();
6774              this._open( submenu );
6775          }, this.delay );
6776      },
6777  
6778      _open: function( submenu ) {
6779          var position = $.extend({
6780              of: this.active
6781          }, this.options.position );
6782  
6783          clearTimeout( this.timer );
6784          this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
6785              .hide()
6786              .attr( "aria-hidden", "true" );
6787  
6788          submenu
6789              .show()
6790              .removeAttr( "aria-hidden" )
6791              .attr( "aria-expanded", "true" )
6792              .position( position );
6793      },
6794  
6795      collapseAll: function( event, all ) {
6796          clearTimeout( this.timer );
6797          this.timer = this._delay(function() {
6798              // If we were passed an event, look for the submenu that contains the event
6799              var currentMenu = all ? this.element :
6800                  $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
6801  
6802              // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
6803              if ( !currentMenu.length ) {
6804                  currentMenu = this.element;
6805              }
6806  
6807              this._close( currentMenu );
6808  
6809              this.blur( event );
6810              this.activeMenu = currentMenu;
6811          }, this.delay );
6812      },
6813  
6814      // With no arguments, closes the currently active menu - if nothing is active
6815      // it closes all menus.  If passed an argument, it will search for menus BELOW
6816      _close: function( startMenu ) {
6817          if ( !startMenu ) {
6818              startMenu = this.active ? this.active.parent() : this.element;
6819          }
6820  
6821          startMenu
6822              .find( ".ui-menu" )
6823                  .hide()
6824                  .attr( "aria-hidden", "true" )
6825                  .attr( "aria-expanded", "false" )
6826              .end()
6827              .find( ".ui-state-active" ).not( ".ui-state-focus" )
6828                  .removeClass( "ui-state-active" );
6829      },
6830  
6831      _closeOnDocumentClick: function( event ) {
6832          return !$( event.target ).closest( ".ui-menu" ).length;
6833      },
6834  
6835      _isDivider: function( item ) {
6836  
6837          // Match hyphen, em dash, en dash
6838          return !/[^\-\u2014\u2013\s]/.test( item.text() );
6839      },
6840  
6841      collapse: function( event ) {
6842          var newItem = this.active &&
6843              this.active.parent().closest( ".ui-menu-item", this.element );
6844          if ( newItem && newItem.length ) {
6845              this._close();
6846              this.focus( event, newItem );
6847          }
6848      },
6849  
6850      expand: function( event ) {
6851          var newItem = this.active &&
6852              this.active
6853                  .children( ".ui-menu " )
6854                  .find( this.options.items )
6855                  .first();
6856  
6857          if ( newItem && newItem.length ) {
6858              this._open( newItem.parent() );
6859  
6860              // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
6861              this._delay(function() {
6862                  this.focus( event, newItem );
6863              });
6864          }
6865      },
6866  
6867      next: function( event ) {
6868          this._move( "next", "first", event );
6869      },
6870  
6871      previous: function( event ) {
6872          this._move( "prev", "last", event );
6873      },
6874  
6875      isFirstItem: function() {
6876          return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
6877      },
6878  
6879      isLastItem: function() {
6880          return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
6881      },
6882  
6883      _move: function( direction, filter, event ) {
6884          var next;
6885          if ( this.active ) {
6886              if ( direction === "first" || direction === "last" ) {
6887                  next = this.active
6888                      [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
6889                      .eq( -1 );
6890              } else {
6891                  next = this.active
6892                      [ direction + "All" ]( ".ui-menu-item" )
6893                      .eq( 0 );
6894              }
6895          }
6896          if ( !next || !next.length || !this.active ) {
6897              next = this.activeMenu.find( this.options.items )[ filter ]();
6898          }
6899  
6900          this.focus( event, next );
6901      },
6902  
6903      nextPage: function( event ) {
6904          var item, base, height;
6905  
6906          if ( !this.active ) {
6907              this.next( event );
6908              return;
6909          }
6910          if ( this.isLastItem() ) {
6911              return;
6912          }
6913          if ( this._hasScroll() ) {
6914              base = this.active.offset().top;
6915              height = this.element.height();
6916              this.active.nextAll( ".ui-menu-item" ).each(function() {
6917                  item = $( this );
6918                  return item.offset().top - base - height < 0;
6919              });
6920  
6921              this.focus( event, item );
6922          } else {
6923              this.focus( event, this.activeMenu.find( this.options.items )
6924                  [ !this.active ? "first" : "last" ]() );
6925          }
6926      },
6927  
6928      previousPage: function( event ) {
6929          var item, base, height;
6930          if ( !this.active ) {
6931              this.next( event );
6932              return;
6933          }
6934          if ( this.isFirstItem() ) {
6935              return;
6936          }
6937          if ( this._hasScroll() ) {
6938              base = this.active.offset().top;
6939              height = this.element.height();
6940              this.active.prevAll( ".ui-menu-item" ).each(function() {
6941                  item = $( this );
6942                  return item.offset().top - base + height > 0;
6943              });
6944  
6945              this.focus( event, item );
6946          } else {
6947              this.focus( event, this.activeMenu.find( this.options.items ).first() );
6948          }
6949      },
6950  
6951      _hasScroll: function() {
6952          return this.element.outerHeight() < this.element.prop( "scrollHeight" );
6953      },
6954  
6955      select: function( event ) {
6956          // TODO: It should never be possible to not have an active item at this
6957          // point, but the tests don't trigger mouseenter before click.
6958          this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
6959          var ui = { item: this.active };
6960          if ( !this.active.has( ".ui-menu" ).length ) {
6961              this.collapseAll( event, true );
6962          }
6963          this._trigger( "select", event, ui );
6964      },
6965  
6966      _filterMenuItems: function(character) {
6967          var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
6968              regex = new RegExp( "^" + escapedCharacter, "i" );
6969  
6970          return this.activeMenu
6971              .find( this.options.items )
6972  
6973              // Only match on items, not dividers or other content (#10571)
6974              .filter( ".ui-menu-item" )
6975              .filter(function() {
6976                  return regex.test( $.trim( $( this ).text() ) );
6977              });
6978      }
6979  });
6980  
6981  
6982  /*!
6983   * jQuery UI Autocomplete 1.11.4
6984   * http://jqueryui.com
6985   *
6986   * Copyright jQuery Foundation and other contributors
6987   * Released under the MIT license.
6988   * http://jquery.org/license
6989   *
6990   * http://api.jqueryui.com/autocomplete/
6991   */
6992  
6993  
6994  $.widget( "ui.autocomplete", {
6995      version: "1.11.4",
6996      defaultElement: "<input>",
6997      options: {
6998          appendTo: null,
6999          autoFocus: false,
7000          delay: 300,
7001          minLength: 1,
7002          position: {
7003              my: "left top",
7004              at: "left bottom",
7005              collision: "none"
7006          },
7007          source: null,
7008  
7009          // callbacks
7010          change: null,
7011          close: null,
7012          focus: null,
7013          open: null,
7014          response: null,
7015          search: null,
7016          select: null
7017      },
7018  
7019      requestIndex: 0,
7020      pending: 0,
7021  
7022      _create: function() {
7023          // Some browsers only repeat keydown events, not keypress events,
7024          // so we use the suppressKeyPress flag to determine if we've already
7025          // handled the keydown event. #7269
7026          // Unfortunately the code for & in keypress is the same as the up arrow,
7027          // so we use the suppressKeyPressRepeat flag to avoid handling keypress
7028          // events when we know the keydown event was used to modify the
7029          // search term. #7799
7030          var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
7031              nodeName = this.element[ 0 ].nodeName.toLowerCase(),
7032              isTextarea = nodeName === "textarea",
7033              isInput = nodeName === "input";
7034  
7035          this.isMultiLine =
7036              // Textareas are always multi-line
7037              isTextarea ? true :
7038              // Inputs are always single-line, even if inside a contentEditable element
7039              // IE also treats inputs as contentEditable
7040              isInput ? false :
7041              // All other element types are determined by whether or not they're contentEditable
7042              this.element.prop( "isContentEditable" );
7043  
7044          this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
7045          this.isNewMenu = true;
7046  
7047          this.element
7048              .addClass( "ui-autocomplete-input" )
7049              .attr( "autocomplete", "off" );
7050  
7051          this._on( this.element, {
7052              keydown: function( event ) {
7053                  if ( this.element.prop( "readOnly" ) ) {
7054                      suppressKeyPress = true;
7055                      suppressInput = true;
7056                      suppressKeyPressRepeat = true;
7057                      return;
7058                  }
7059  
7060                  suppressKeyPress = false;
7061                  suppressInput = false;
7062                  suppressKeyPressRepeat = false;
7063                  var keyCode = $.ui.keyCode;
7064                  switch ( event.keyCode ) {
7065                  case keyCode.PAGE_UP:
7066                      suppressKeyPress = true;
7067                      this._move( "previousPage", event );
7068                      break;
7069                  case keyCode.PAGE_DOWN:
7070                      suppressKeyPress = true;
7071                      this._move( "nextPage", event );
7072                      break;
7073                  case keyCode.UP:
7074                      suppressKeyPress = true;
7075                      this._keyEvent( "previous", event );
7076                      break;
7077                  case keyCode.DOWN:
7078                      suppressKeyPress = true;
7079                      this._keyEvent( "next", event );
7080                      break;
7081                  case keyCode.ENTER:
7082                      // when menu is open and has focus
7083                      if ( this.menu.active ) {
7084                          // #6055 - Opera still allows the keypress to occur
7085                          // which causes forms to submit
7086                          suppressKeyPress = true;
7087                          event.preventDefault();
7088                          this.menu.select( event );
7089                      }
7090                      break;
7091                  case keyCode.TAB:
7092                      if ( this.menu.active ) {
7093                          this.menu.select( event );
7094                      }
7095                      break;
7096                  case keyCode.ESCAPE:
7097                      if ( this.menu.element.is( ":visible" ) ) {
7098                          if ( !this.isMultiLine ) {
7099                              this._value( this.term );
7100                          }
7101                          this.close( event );
7102                          // Different browsers have different default behavior for escape
7103                          // Single press can mean undo or clear
7104                          // Double press in IE means clear the whole form
7105                          event.preventDefault();
7106                      }
7107                      break;
7108                  default:
7109                      suppressKeyPressRepeat = true;
7110                      // search timeout should be triggered before the input value is changed
7111                      this._searchTimeout( event );
7112                      break;
7113                  }
7114              },
7115              keypress: function( event ) {
7116                  if ( suppressKeyPress ) {
7117                      suppressKeyPress = false;
7118                      if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7119                          event.preventDefault();
7120                      }
7121                      return;
7122                  }
7123                  if ( suppressKeyPressRepeat ) {
7124                      return;
7125                  }
7126  
7127                  // replicate some key handlers to allow them to repeat in Firefox and Opera
7128                  var keyCode = $.ui.keyCode;
7129                  switch ( event.keyCode ) {
7130                  case keyCode.PAGE_UP:
7131                      this._move( "previousPage", event );
7132                      break;
7133                  case keyCode.PAGE_DOWN:
7134                      this._move( "nextPage", event );
7135                      break;
7136                  case keyCode.UP:
7137                      this._keyEvent( "previous", event );
7138                      break;
7139                  case keyCode.DOWN:
7140                      this._keyEvent( "next", event );
7141                      break;
7142                  }
7143              },
7144              input: function( event ) {
7145                  if ( suppressInput ) {
7146                      suppressInput = false;
7147                      event.preventDefault();
7148                      return;
7149                  }
7150                  this._searchTimeout( event );
7151              },
7152              focus: function() {
7153                  this.selectedItem = null;
7154                  this.previous = this._value();
7155              },
7156              blur: function( event ) {
7157                  if ( this.cancelBlur ) {
7158                      delete this.cancelBlur;
7159                      return;
7160                  }
7161  
7162                  clearTimeout( this.searching );
7163                  this.close( event );
7164                  this._change( event );
7165              }
7166          });
7167  
7168          this._initSource();
7169          this.menu = $( "<ul>" )
7170              .addClass( "ui-autocomplete ui-front" )
7171              .appendTo( this._appendTo() )
7172              .menu({
7173                  // disable ARIA support, the live region takes care of that
7174                  role: null
7175              })
7176              .hide()
7177              .menu( "instance" );
7178  
7179          this._on( this.menu.element, {
7180              mousedown: function( event ) {
7181                  // prevent moving focus out of the text field
7182                  event.preventDefault();
7183  
7184                  // IE doesn't prevent moving focus even with event.preventDefault()
7185                  // so we set a flag to know when we should ignore the blur event
7186                  this.cancelBlur = true;
7187                  this._delay(function() {
7188                      delete this.cancelBlur;
7189                  });
7190  
7191                  // clicking on the scrollbar causes focus to shift to the body
7192                  // but we can't detect a mouseup or a click immediately afterward
7193                  // so we have to track the next mousedown and close the menu if
7194                  // the user clicks somewhere outside of the autocomplete
7195                  var menuElement = this.menu.element[ 0 ];
7196                  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
7197                      this._delay(function() {
7198                          var that = this;
7199                          this.document.one( "mousedown", function( event ) {
7200                              if ( event.target !== that.element[ 0 ] &&
7201                                      event.target !== menuElement &&
7202                                      !$.contains( menuElement, event.target ) ) {
7203                                  that.close();
7204                              }
7205                          });
7206                      });
7207                  }
7208              },
7209              menufocus: function( event, ui ) {
7210                  var label, item;
7211                  // support: Firefox
7212                  // Prevent accidental activation of menu items in Firefox (#7024 #9118)
7213                  if ( this.isNewMenu ) {
7214                      this.isNewMenu = false;
7215                      if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
7216                          this.menu.blur();
7217  
7218                          this.document.one( "mousemove", function() {
7219                              $( event.target ).trigger( event.originalEvent );
7220                          });
7221  
7222                          return;
7223                      }
7224                  }
7225  
7226                  item = ui.item.data( "ui-autocomplete-item" );
7227                  if ( false !== this._trigger( "focus", event, { item: item } ) ) {
7228                      // use value to match what will end up in the input, if it was a key event
7229                      if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
7230                          this._value( item.value );
7231                      }
7232                  }
7233  
7234                  // Announce the value in the liveRegion
7235                  label = ui.item.attr( "aria-label" ) || item.value;
7236                  if ( label && $.trim( label ).length ) {
7237                      this.liveRegion.children().hide();
7238                      $( "<div>" ).text( label ).appendTo( this.liveRegion );
7239                  }
7240              },
7241              menuselect: function( event, ui ) {
7242                  var item = ui.item.data( "ui-autocomplete-item" ),
7243                      previous = this.previous;
7244  
7245                  // only trigger when focus was lost (click on menu)
7246                  if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
7247                      this.element.focus();
7248                      this.previous = previous;
7249                      // #6109 - IE triggers two focus events and the second
7250                      // is asynchronous, so we need to reset the previous
7251                      // term synchronously and asynchronously :-(
7252                      this._delay(function() {
7253                          this.previous = previous;
7254                          this.selectedItem = item;
7255                      });
7256                  }
7257  
7258                  if ( false !== this._trigger( "select", event, { item: item } ) ) {
7259                      this._value( item.value );
7260                  }
7261                  // reset the term after the select event
7262                  // this allows custom select handling to work properly
7263                  this.term = this._value();
7264  
7265                  this.close( event );
7266                  this.selectedItem = item;
7267              }
7268          });
7269  
7270          this.liveRegion = $( "<span>", {
7271                  role: "status",
7272                  "aria-live": "assertive",
7273                  "aria-relevant": "additions"
7274              })
7275              .addClass( "ui-helper-hidden-accessible" )
7276              .appendTo( this.document[ 0 ].body );
7277  
7278          // turning off autocomplete prevents the browser from remembering the
7279          // value when navigating through history, so we re-enable autocomplete
7280          // if the page is unloaded before the widget is destroyed. #7790
7281          this._on( this.window, {
7282              beforeunload: function() {
7283                  this.element.removeAttr( "autocomplete" );
7284              }
7285          });
7286      },
7287  
7288      _destroy: function() {
7289          clearTimeout( this.searching );
7290          this.element
7291              .removeClass( "ui-autocomplete-input" )
7292              .removeAttr( "autocomplete" );
7293          this.menu.element.remove();
7294          this.liveRegion.remove();
7295      },
7296  
7297      _setOption: function( key, value ) {
7298          this._super( key, value );
7299          if ( key === "source" ) {
7300              this._initSource();
7301          }
7302          if ( key === "appendTo" ) {
7303              this.menu.element.appendTo( this._appendTo() );
7304          }
7305          if ( key === "disabled" && value && this.xhr ) {
7306              this.xhr.abort();
7307          }
7308      },
7309  
7310      _appendTo: function() {
7311          var element = this.options.appendTo;
7312  
7313          if ( element ) {
7314              element = element.jquery || element.nodeType ?
7315                  $( element ) :
7316                  this.document.find( element ).eq( 0 );
7317          }
7318  
7319          if ( !element || !element[ 0 ] ) {
7320              element = this.element.closest( ".ui-front" );
7321          }
7322  
7323          if ( !element.length ) {
7324              element = this.document[ 0 ].body;
7325          }
7326  
7327          return element;
7328      },
7329  
7330      _initSource: function() {
7331          var array, url,
7332              that = this;
7333          if ( $.isArray( this.options.source ) ) {
7334              array = this.options.source;
7335              this.source = function( request, response ) {
7336                  response( $.ui.autocomplete.filter( array, request.term ) );
7337              };
7338          } else if ( typeof this.options.source === "string" ) {
7339              url = this.options.source;
7340              this.source = function( request, response ) {
7341                  if ( that.xhr ) {
7342                      that.xhr.abort();
7343                  }
7344                  that.xhr = $.ajax({
7345                      url: url,
7346                      data: request,
7347                      dataType: "json",
7348                      success: function( data ) {
7349                          response( data );
7350                      },
7351                      error: function() {
7352                          response([]);
7353                      }
7354                  });
7355              };
7356          } else {
7357              this.source = this.options.source;
7358          }
7359      },
7360  
7361      _searchTimeout: function( event ) {
7362          clearTimeout( this.searching );
7363          this.searching = this._delay(function() {
7364  
7365              // Search if the value has changed, or if the user retypes the same value (see #7434)
7366              var equalValues = this.term === this._value(),
7367                  menuVisible = this.menu.element.is( ":visible" ),
7368                  modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
7369  
7370              if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
7371                  this.selectedItem = null;
7372                  this.search( null, event );
7373              }
7374          }, this.options.delay );
7375      },
7376  
7377      search: function( value, event ) {
7378          value = value != null ? value : this._value();
7379  
7380          // always save the actual value, not the one passed as an argument
7381          this.term = this._value();
7382  
7383          if ( value.length < this.options.minLength ) {
7384              return this.close( event );
7385          }
7386  
7387          if ( this._trigger( "search", event ) === false ) {
7388              return;
7389          }
7390  
7391          return this._search( value );
7392      },
7393  
7394      _search: function( value ) {
7395          this.pending++;
7396          this.element.addClass( "ui-autocomplete-loading" );
7397          this.cancelSearch = false;
7398  
7399          this.source( { term: value }, this._response() );
7400      },
7401  
7402      _response: function() {
7403          var index = ++this.requestIndex;
7404  
7405          return $.proxy(function( content ) {
7406              if ( index === this.requestIndex ) {
7407                  this.__response( content );
7408              }
7409  
7410              this.pending--;
7411              if ( !this.pending ) {
7412                  this.element.removeClass( "ui-autocomplete-loading" );
7413              }
7414          }, this );
7415      },
7416  
7417      __response: function( content ) {
7418          if ( content ) {
7419              content = this._normalize( content );
7420          }
7421          this._trigger( "response", null, { content: content } );
7422          if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7423              this._suggest( content );
7424              this._trigger( "open" );
7425          } else {
7426              // use ._close() instead of .close() so we don't cancel future searches
7427              this._close();
7428          }
7429      },
7430  
7431      close: function( event ) {
7432          this.cancelSearch = true;
7433          this._close( event );
7434      },
7435  
7436      _close: function( event ) {
7437          if ( this.menu.element.is( ":visible" ) ) {
7438              this.menu.element.hide();
7439              this.menu.blur();
7440              this.isNewMenu = true;
7441              this._trigger( "close", event );
7442          }
7443      },
7444  
7445      _change: function( event ) {
7446          if ( this.previous !== this._value() ) {
7447              this._trigger( "change", event, { item: this.selectedItem } );
7448          }
7449      },
7450  
7451      _normalize: function( items ) {
7452          // assume all items have the right format when the first item is complete
7453          if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
7454              return items;
7455          }
7456          return $.map( items, function( item ) {
7457              if ( typeof item === "string" ) {
7458                  return {
7459                      label: item,
7460                      value: item
7461                  };
7462              }
7463              return $.extend( {}, item, {
7464                  label: item.label || item.value,
7465                  value: item.value || item.label
7466              });
7467          });
7468      },
7469  
7470      _suggest: function( items ) {
7471          var ul = this.menu.element.empty();
7472          this._renderMenu( ul, items );
7473          this.isNewMenu = true;
7474          this.menu.refresh();
7475  
7476          // size and position menu
7477          ul.show();
7478          this._resizeMenu();
7479          ul.position( $.extend({
7480              of: this.element
7481          }, this.options.position ) );
7482  
7483          if ( this.options.autoFocus ) {
7484              this.menu.next();
7485          }
7486      },
7487  
7488      _resizeMenu: function() {
7489          var ul = this.menu.element;
7490          ul.outerWidth( Math.max(
7491              // Firefox wraps long text (possibly a rounding bug)
7492              // so we add 1px to avoid the wrapping (#7513)
7493              ul.width( "" ).outerWidth() + 1,
7494              this.element.outerWidth()
7495          ) );
7496      },
7497  
7498      _renderMenu: function( ul, items ) {
7499          var that = this;
7500          $.each( items, function( index, item ) {
7501              that._renderItemData( ul, item );
7502          });
7503      },
7504  
7505      _renderItemData: function( ul, item ) {
7506          return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7507      },
7508  
7509      _renderItem: function( ul, item ) {
7510          return $( "<li>" ).text( item.label ).appendTo( ul );
7511      },
7512  
7513      _move: function( direction, event ) {
7514          if ( !this.menu.element.is( ":visible" ) ) {
7515              this.search( null, event );
7516              return;
7517          }
7518          if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7519                  this.menu.isLastItem() && /^next/.test( direction ) ) {
7520  
7521              if ( !this.isMultiLine ) {
7522                  this._value( this.term );
7523              }
7524  
7525              this.menu.blur();
7526              return;
7527          }
7528          this.menu[ direction ]( event );
7529      },
7530  
7531      widget: function() {
7532          return this.menu.element;
7533      },
7534  
7535      _value: function() {
7536          return this.valueMethod.apply( this.element, arguments );
7537      },
7538  
7539      _keyEvent: function( keyEvent, event ) {
7540          if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7541              this._move( keyEvent, event );
7542  
7543              // prevents moving cursor to beginning/end of the text field in some browsers
7544              event.preventDefault();
7545          }
7546      }
7547  });
7548  
7549  $.extend( $.ui.autocomplete, {
7550      escapeRegex: function( value ) {
7551          return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
7552      },
7553      filter: function( array, term ) {
7554          var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
7555          return $.grep( array, function( value ) {
7556              return matcher.test( value.label || value.value || value );
7557          });
7558      }
7559  });
7560  
7561  // live region extension, adding a `messages` option
7562  // NOTE: This is an experimental API. We are still investigating
7563  // a full solution for string manipulation and internationalization.
7564  $.widget( "ui.autocomplete", $.ui.autocomplete, {
7565      options: {
7566          messages: {
7567              noResults: "No search results.",
7568              results: function( amount ) {
7569                  return amount + ( amount > 1 ? " results are" : " result is" ) +
7570                      " available, use up and down arrow keys to navigate.";
7571              }
7572          }
7573      },
7574  
7575      __response: function( content ) {
7576          var message;
7577          this._superApply( arguments );
7578          if ( this.options.disabled || this.cancelSearch ) {
7579              return;
7580          }
7581          if ( content && content.length ) {
7582              message = this.options.messages.results( content.length );
7583          } else {
7584              message = this.options.messages.noResults;
7585          }
7586          this.liveRegion.children().hide();
7587          $( "<div>" ).text( message ).appendTo( this.liveRegion );
7588      }
7589  });
7590  
7591  var autocomplete = $.ui.autocomplete;
7592  
7593  
7594  /*!
7595   * jQuery UI Button 1.11.4
7596   * http://jqueryui.com
7597   *
7598   * Copyright jQuery Foundation and other contributors
7599   * Released under the MIT license.
7600   * http://jquery.org/license
7601   *
7602   * http://api.jqueryui.com/button/
7603   */
7604  
7605  
7606  var lastActive,
7607      baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7608      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",
7609      formResetHandler = function() {
7610          var form = $( this );
7611          setTimeout(function() {
7612              form.find( ":ui-button" ).button( "refresh" );
7613          }, 1 );
7614      },
7615      radioGroup = function( radio ) {
7616          var name = radio.name,
7617              form = radio.form,
7618              radios = $( [] );
7619          if ( name ) {
7620              name = name.replace( /'/g, "\\'" );
7621              if ( form ) {
7622                  radios = $( form ).find( "[name='" + name + "'][type=radio]" );
7623              } else {
7624                  radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
7625                      .filter(function() {
7626                          return !this.form;
7627                      });
7628              }
7629          }
7630          return radios;
7631      };
7632  
7633  $.widget( "ui.button", {
7634      version: "1.11.4",
7635      defaultElement: "<button>",
7636      options: {
7637          disabled: null,
7638          text: true,
7639          label: null,
7640          icons: {
7641              primary: null,
7642              secondary: null
7643          }
7644      },
7645      _create: function() {
7646          this.element.closest( "form" )
7647              .unbind( "reset" + this.eventNamespace )
7648              .bind( "reset" + this.eventNamespace, formResetHandler );
7649  
7650          if ( typeof this.options.disabled !== "boolean" ) {
7651              this.options.disabled = !!this.element.prop( "disabled" );
7652          } else {
7653              this.element.prop( "disabled", this.options.disabled );
7654          }
7655  
7656          this._determineButtonType();
7657          this.hasTitle = !!this.buttonElement.attr( "title" );
7658  
7659          var that = this,
7660              options = this.options,
7661              toggleButton = this.type === "checkbox" || this.type === "radio",
7662              activeClass = !toggleButton ? "ui-state-active" : "";
7663  
7664          if ( options.label === null ) {
7665              options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7666          }
7667  
7668          this._hoverable( this.buttonElement );
7669  
7670          this.buttonElement
7671              .addClass( baseClasses )
7672              .attr( "role", "button" )
7673              .bind( "mouseenter" + this.eventNamespace, function() {
7674                  if ( options.disabled ) {
7675                      return;
7676                  }
7677                  if ( this === lastActive ) {
7678                      $( this ).addClass( "ui-state-active" );
7679                  }
7680              })
7681              .bind( "mouseleave" + this.eventNamespace, function() {
7682                  if ( options.disabled ) {
7683                      return;
7684                  }
7685                  $( this ).removeClass( activeClass );
7686              })
7687              .bind( "click" + this.eventNamespace, function( event ) {
7688                  if ( options.disabled ) {
7689                      event.preventDefault();
7690                      event.stopImmediatePropagation();
7691                  }
7692              });
7693  
7694          // Can't use _focusable() because the element that receives focus
7695          // and the element that gets the ui-state-focus class are different
7696          this._on({
7697              focus: function() {
7698                  this.buttonElement.addClass( "ui-state-focus" );
7699              },
7700              blur: function() {
7701                  this.buttonElement.removeClass( "ui-state-focus" );
7702              }
7703          });
7704  
7705          if ( toggleButton ) {
7706              this.element.bind( "change" + this.eventNamespace, function() {
7707                  that.refresh();
7708              });
7709          }
7710  
7711          if ( this.type === "checkbox" ) {
7712              this.buttonElement.bind( "click" + this.eventNamespace, function() {
7713                  if ( options.disabled ) {
7714                      return false;
7715                  }
7716              });
7717          } else if ( this.type === "radio" ) {
7718              this.buttonElement.bind( "click" + this.eventNamespace, function() {
7719                  if ( options.disabled ) {
7720                      return false;
7721                  }
7722                  $( this ).addClass( "ui-state-active" );
7723                  that.buttonElement.attr( "aria-pressed", "true" );
7724  
7725                  var radio = that.element[ 0 ];
7726                  radioGroup( radio )
7727                      .not( radio )
7728                      .map(function() {
7729                          return $( this ).button( "widget" )[ 0 ];
7730                      })
7731                      .removeClass( "ui-state-active" )
7732                      .attr( "aria-pressed", "false" );
7733              });
7734          } else {
7735              this.buttonElement
7736                  .bind( "mousedown" + this.eventNamespace, function() {
7737                      if ( options.disabled ) {
7738                          return false;
7739                      }
7740                      $( this ).addClass( "ui-state-active" );
7741                      lastActive = this;
7742                      that.document.one( "mouseup", function() {
7743                          lastActive = null;
7744                      });
7745                  })
7746                  .bind( "mouseup" + this.eventNamespace, function() {
7747                      if ( options.disabled ) {
7748                          return false;
7749                      }
7750                      $( this ).removeClass( "ui-state-active" );
7751                  })
7752                  .bind( "keydown" + this.eventNamespace, function(event) {
7753                      if ( options.disabled ) {
7754                          return false;
7755                      }
7756                      if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7757                          $( this ).addClass( "ui-state-active" );
7758                      }
7759                  })
7760                  // see #8559, we bind to blur here in case the button element loses
7761                  // focus between keydown and keyup, it would be left in an "active" state
7762                  .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7763                      $( this ).removeClass( "ui-state-active" );
7764                  });
7765  
7766              if ( this.buttonElement.is("a") ) {
7767                  this.buttonElement.keyup(function(event) {
7768                      if ( event.keyCode === $.ui.keyCode.SPACE ) {
7769                          // TODO pass through original event correctly (just as 2nd argument doesn't work)
7770                          $( this ).click();
7771                      }
7772                  });
7773              }
7774          }
7775  
7776          this._setOption( "disabled", options.disabled );
7777          this._resetButton();
7778      },
7779  
7780      _determineButtonType: function() {
7781          var ancestor, labelSelector, checked;
7782  
7783          if ( this.element.is("[type=checkbox]") ) {
7784              this.type = "checkbox";
7785          } else if ( this.element.is("[type=radio]") ) {
7786              this.type = "radio";
7787          } else if ( this.element.is("input") ) {
7788              this.type = "input";
7789          } else {
7790              this.type = "button";
7791          }
7792  
7793          if ( this.type === "checkbox" || this.type === "radio" ) {
7794              // we don't search against the document in case the element
7795              // is disconnected from the DOM
7796              ancestor = this.element.parents().last();
7797              labelSelector = "label[for='" + this.element.attr("id") + "']";
7798              this.buttonElement = ancestor.find( labelSelector );
7799              if ( !this.buttonElement.length ) {
7800                  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7801                  this.buttonElement = ancestor.filter( labelSelector );
7802                  if ( !this.buttonElement.length ) {
7803                      this.buttonElement = ancestor.find( labelSelector );
7804                  }
7805              }
7806              this.element.addClass( "ui-helper-hidden-accessible" );
7807  
7808              checked = this.element.is( ":checked" );
7809              if ( checked ) {
7810                  this.buttonElement.addClass( "ui-state-active" );
7811              }
7812              this.buttonElement.prop( "aria-pressed", checked );
7813          } else {
7814              this.buttonElement = this.element;
7815          }
7816      },
7817  
7818      widget: function() {
7819          return this.buttonElement;
7820      },
7821  
7822      _destroy: function() {
7823          this.element
7824              .removeClass( "ui-helper-hidden-accessible" );
7825          this.buttonElement
7826              .removeClass( baseClasses + " ui-state-active " + typeClasses )
7827              .removeAttr( "role" )
7828              .removeAttr( "aria-pressed" )
7829              .html( this.buttonElement.find(".ui-button-text").html() );
7830  
7831          if ( !this.hasTitle ) {
7832              this.buttonElement.removeAttr( "title" );
7833          }
7834      },
7835  
7836      _setOption: function( key, value ) {
7837          this._super( key, value );
7838          if ( key === "disabled" ) {
7839              this.widget().toggleClass( "ui-state-disabled", !!value );
7840              this.element.prop( "disabled", !!value );
7841              if ( value ) {
7842                  if ( this.type === "checkbox" || this.type === "radio" ) {
7843                      this.buttonElement.removeClass( "ui-state-focus" );
7844                  } else {
7845                      this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
7846                  }
7847              }
7848              return;
7849          }
7850          this._resetButton();
7851      },
7852  
7853      refresh: function() {
7854          //See #8237 & #8828
7855          var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7856  
7857          if ( isDisabled !== this.options.disabled ) {
7858              this._setOption( "disabled", isDisabled );
7859          }
7860          if ( this.type === "radio" ) {
7861              radioGroup( this.element[0] ).each(function() {
7862                  if ( $( this ).is( ":checked" ) ) {
7863                      $( this ).button( "widget" )
7864                          .addClass( "ui-state-active" )
7865                          .attr( "aria-pressed", "true" );
7866                  } else {
7867                      $( this ).button( "widget" )
7868                          .removeClass( "ui-state-active" )
7869                          .attr( "aria-pressed", "false" );
7870                  }
7871              });
7872          } else if ( this.type === "checkbox" ) {
7873              if ( this.element.is( ":checked" ) ) {
7874                  this.buttonElement
7875                      .addClass( "ui-state-active" )
7876                      .attr( "aria-pressed", "true" );
7877              } else {
7878                  this.buttonElement
7879                      .removeClass( "ui-state-active" )
7880                      .attr( "aria-pressed", "false" );
7881              }
7882          }
7883      },
7884  
7885      _resetButton: function() {
7886          if ( this.type === "input" ) {
7887              if ( this.options.label ) {
7888                  this.element.val( this.options.label );
7889              }
7890              return;
7891          }
7892          var buttonElement = this.buttonElement.removeClass( typeClasses ),
7893              buttonText = $( "<span></span>", this.document[0] )
7894                  .addClass( "ui-button-text" )
7895                  .html( this.options.label )
7896                  .appendTo( buttonElement.empty() )
7897                  .text(),
7898              icons = this.options.icons,
7899              multipleIcons = icons.primary && icons.secondary,
7900              buttonClasses = [];
7901  
7902          if ( icons.primary || icons.secondary ) {
7903              if ( this.options.text ) {
7904                  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7905              }
7906  
7907              if ( icons.primary ) {
7908                  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7909              }
7910  
7911              if ( icons.secondary ) {
7912                  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7913              }
7914  
7915              if ( !this.options.text ) {
7916                  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7917  
7918                  if ( !this.hasTitle ) {
7919                      buttonElement.attr( "title", $.trim( buttonText ) );
7920                  }
7921              }
7922          } else {
7923              buttonClasses.push( "ui-button-text-only" );
7924          }
7925          buttonElement.addClass( buttonClasses.join( " " ) );
7926      }
7927  });
7928  
7929  $.widget( "ui.buttonset", {
7930      version: "1.11.4",
7931      options: {
7932          items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7933      },
7934  
7935      _create: function() {
7936          this.element.addClass( "ui-buttonset" );
7937      },
7938  
7939      _init: function() {
7940          this.refresh();
7941      },
7942  
7943      _setOption: function( key, value ) {
7944          if ( key === "disabled" ) {
7945              this.buttons.button( "option", key, value );
7946          }
7947  
7948          this._super( key, value );
7949      },
7950  
7951      refresh: function() {
7952          var rtl = this.element.css( "direction" ) === "rtl",
7953              allButtons = this.element.find( this.options.items ),
7954              existingButtons = allButtons.filter( ":ui-button" );
7955  
7956          // Initialize new buttons
7957          allButtons.not( ":ui-button" ).button();
7958  
7959          // Refresh existing buttons
7960          existingButtons.button( "refresh" );
7961  
7962          this.buttons = allButtons
7963              .map(function() {
7964                  return $( this ).button( "widget" )[ 0 ];
7965              })
7966                  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7967                  .filter( ":first" )
7968                      .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7969                  .end()
7970                  .filter( ":last" )
7971                      .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7972                  .end()
7973              .end();
7974      },
7975  
7976      _destroy: function() {
7977          this.element.removeClass( "ui-buttonset" );
7978          this.buttons
7979              .map(function() {
7980                  return $( this ).button( "widget" )[ 0 ];
7981              })
7982                  .removeClass( "ui-corner-left ui-corner-right" )
7983              .end()
7984              .button( "destroy" );
7985      }
7986  });
7987  
7988  var button = $.ui.button;
7989  
7990  
7991  /*!
7992   * jQuery UI Datepicker 1.11.4
7993   * http://jqueryui.com
7994   *
7995   * Copyright jQuery Foundation and other contributors
7996   * Released under the MIT license.
7997   * http://jquery.org/license
7998   *
7999   * http://api.jqueryui.com/datepicker/
8000   */
8001  
8002  
8003  $.extend($.ui, { datepicker: { version: "1.11.4" } });
8004  
8005  var datepicker_instActive;
8006  
8007  function datepicker_getZindex( elem ) {
8008      var position, value;
8009      while ( elem.length && elem[ 0 ] !== document ) {
8010          // Ignore z-index if position is set to a value where z-index is ignored by the browser
8011          // This makes behavior of this function consistent across browsers
8012          // WebKit always returns auto if the element is positioned
8013          position = elem.css( "position" );
8014          if ( position === "absolute" || position === "relative" || position === "fixed" ) {
8015              // IE returns 0 when zIndex is not specified
8016              // other browsers return a string
8017              // we ignore the case of nested elements with an explicit value of 0
8018              // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
8019              value = parseInt( elem.css( "zIndex" ), 10 );
8020              if ( !isNaN( value ) && value !== 0 ) {
8021                  return value;
8022              }
8023          }
8024          elem = elem.parent();
8025      }
8026  
8027      return 0;
8028  }
8029  /* Date picker manager.
8030     Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8031     Settings for (groups of) date pickers are maintained in an instance object,
8032     allowing multiple different settings on the same page. */
8033  
8034  function Datepicker() {
8035      this._curInst = null; // The current instance in use
8036      this._keyEvent = false; // If the last event was a key event
8037      this._disabledInputs = []; // List of date picker inputs that have been disabled
8038      this._datepickerShowing = false; // True if the popup picker is showing , false if not
8039      this._inDialog = false; // True if showing within a "dialog", false if not
8040      this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
8041      this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
8042      this._appendClass = "ui-datepicker-append"; // The name of the append marker class
8043      this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
8044      this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
8045      this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
8046      this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
8047      this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
8048      this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
8049      this.regional = []; // Available regional settings, indexed by language code
8050      this.regional[""] = { // Default regional settings
8051          closeText: "Done", // Display text for close link
8052          prevText: "Prev", // Display text for previous month link
8053          nextText: "Next", // Display text for next month link
8054          currentText: "Today", // Display text for current month link
8055          monthNames: ["January","February","March","April","May","June",
8056              "July","August","September","October","November","December"], // Names of months for drop-down and formatting
8057          monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
8058          dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
8059          dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
8060          dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
8061          weekHeader: "Wk", // Column header for week of the year
8062          dateFormat: "mm/dd/yy", // See format options on parseDate
8063          firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8064          isRTL: false, // True if right-to-left language, false if left-to-right
8065          showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8066          yearSuffix: "" // Additional text to append to the year in the month headers
8067      };
8068      this._defaults = { // Global defaults for all the date picker instances
8069          showOn: "focus", // "focus" for popup on focus,
8070              // "button" for trigger button, or "both" for either
8071          showAnim: "fadeIn", // Name of jQuery animation for popup
8072          showOptions: {}, // Options for enhanced animations
8073          defaultDate: null, // Used when field is blank: actual date,
8074              // +/-number for offset from today, null for today
8075          appendText: "", // Display text following the input box, e.g. showing the format
8076          buttonText: "...", // Text for trigger button
8077          buttonImage: "", // URL for trigger button image
8078          buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8079          hideIfNoPrevNext: false, // True to hide next/previous month links
8080              // if not applicable, false to just disable them
8081          navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8082          gotoCurrent: false, // True if today link goes back to current selection instead
8083          changeMonth: false, // True if month can be selected directly, false if only prev/next
8084          changeYear: false, // True if year can be selected directly, false if only prev/next
8085          yearRange: "c-10:c+10", // Range of years to display in drop-down,
8086              // either relative to today's year (-nn:+nn), relative to currently displayed year
8087              // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8088          showOtherMonths: false, // True to show dates in other months, false to leave blank
8089          selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8090          showWeek: false, // True to show week of the year, false to not show it
8091          calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8092              // takes a Date and returns the number of the week for it
8093          shortYearCutoff: "+10", // Short year values < this are in the current century,
8094              // > this are in the previous century,
8095              // string value starting with "+" for current year + value
8096          minDate: null, // The earliest selectable date, or null for no limit
8097          maxDate: null, // The latest selectable date, or null for no limit
8098          duration: "fast", // Duration of display/closure
8099          beforeShowDay: null, // Function that takes a date and returns an array with
8100              // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
8101              // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8102          beforeShow: null, // Function that takes an input field and
8103              // returns a set of custom settings for the date picker
8104          onSelect: null, // Define a callback function when a date is selected
8105          onChangeMonthYear: null, // Define a callback function when the month or year is changed
8106          onClose: null, // Define a callback function when the datepicker is closed
8107          numberOfMonths: 1, // Number of months to show at a time
8108          showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8109          stepMonths: 1, // Number of months to step back/forward
8110          stepBigMonths: 12, // Number of months to step back/forward for the big links
8111          altField: "", // Selector for an alternate field to store selected dates into
8112          altFormat: "", // The date format to use for the alternate field
8113          constrainInput: true, // The input is constrained by the current date format
8114          showButtonPanel: false, // True to show button panel, false to not show it
8115          autoSize: false, // True to size the input for the date format, false to leave as is
8116          disabled: false // The initial disabled state
8117      };
8118      $.extend(this._defaults, this.regional[""]);
8119      this.regional.en = $.extend( true, {}, this.regional[ "" ]);
8120      this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
8121      this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
8122  }
8123  
8124  $.extend(Datepicker.prototype, {
8125      /* Class name added to elements to indicate already configured with a date picker. */
8126      markerClassName: "hasDatepicker",
8127  
8128      //Keep track of the maximum number of rows displayed (see #7043)
8129      maxRows: 4,
8130  
8131      // TODO rename to "widget" when switching to widget factory
8132      _widgetDatepicker: function() {
8133          return this.dpDiv;
8134      },
8135  
8136      /* Override the default settings for all instances of the date picker.
8137       * @param  settings  object - the new settings to use as defaults (anonymous object)
8138       * @return the manager object
8139       */
8140      setDefaults: function(settings) {
8141          datepicker_extendRemove(this._defaults, settings || {});
8142          return this;
8143      },
8144  
8145      /* Attach the date picker to a jQuery selection.
8146       * @param  target    element - the target input field or division or span
8147       * @param  settings  object - the new settings to use for this date picker instance (anonymous)
8148       */
8149      _attachDatepicker: function(target, settings) {
8150          var nodeName, inline, inst;
8151          nodeName = target.nodeName.toLowerCase();
8152          inline = (nodeName === "div" || nodeName === "span");
8153          if (!target.id) {
8154              this.uuid += 1;
8155              target.id = "dp" + this.uuid;
8156          }
8157          inst = this._newInst($(target), inline);
8158          inst.settings = $.extend({}, settings || {});
8159          if (nodeName === "input") {
8160              this._connectDatepicker(target, inst);
8161          } else if (inline) {
8162              this._inlineDatepicker(target, inst);
8163          }
8164      },
8165  
8166      /* Create a new instance object. */
8167      _newInst: function(target, inline) {
8168          var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
8169          return {id: id, input: target, // associated target
8170              selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8171              drawMonth: 0, drawYear: 0, // month being drawn
8172              inline: inline, // is datepicker inline or not
8173              dpDiv: (!inline ? this.dpDiv : // presentation div
8174              datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
8175      },
8176  
8177      /* Attach the date picker to an input field. */
8178      _connectDatepicker: function(target, inst) {
8179          var input = $(target);
8180          inst.append = $([]);
8181          inst.trigger = $([]);
8182          if (input.hasClass(this.markerClassName)) {
8183              return;
8184          }
8185          this._attachments(input, inst);
8186          input.addClass(this.markerClassName).keydown(this._doKeyDown).
8187              keypress(this._doKeyPress).keyup(this._doKeyUp);
8188          this._autoSize(inst);
8189          $.data(target, "datepicker", inst);
8190          //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8191          if( inst.settings.disabled ) {
8192              this._disableDatepicker( target );
8193          }
8194      },
8195  
8196      /* Make attachments based on settings. */
8197      _attachments: function(input, inst) {
8198          var showOn, buttonText, buttonImage,
8199              appendText = this._get(inst, "appendText"),
8200              isRTL = this._get(inst, "isRTL");
8201  
8202          if (inst.append) {
8203              inst.append.remove();
8204          }
8205          if (appendText) {
8206              inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
8207              input[isRTL ? "before" : "after"](inst.append);
8208          }
8209  
8210          input.unbind("focus", this._showDatepicker);
8211  
8212          if (inst.trigger) {
8213              inst.trigger.remove();
8214          }
8215  
8216          showOn = this._get(inst, "showOn");
8217          if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
8218              input.focus(this._showDatepicker);
8219          }
8220          if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
8221              buttonText = this._get(inst, "buttonText");
8222              buttonImage = this._get(inst, "buttonImage");
8223              inst.trigger = $(this._get(inst, "buttonImageOnly") ?
8224                  $("<img/>").addClass(this._triggerClass).
8225                      attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8226                  $("<button type='button'></button>").addClass(this._triggerClass).
8227                      html(!buttonImage ? buttonText : $("<img/>").attr(
8228                      { src:buttonImage, alt:buttonText, title:buttonText })));
8229              input[isRTL ? "before" : "after"](inst.trigger);
8230              inst.trigger.click(function() {
8231                  if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
8232                      $.datepicker._hideDatepicker();
8233                  } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
8234                      $.datepicker._hideDatepicker();
8235                      $.datepicker._showDatepicker(input[0]);
8236                  } else {
8237                      $.datepicker._showDatepicker(input[0]);
8238                  }
8239                  return false;
8240              });
8241          }
8242      },
8243  
8244      /* Apply the maximum length for the date format. */
8245      _autoSize: function(inst) {
8246          if (this._get(inst, "autoSize") && !inst.inline) {
8247              var findMax, max, maxI, i,
8248                  date = new Date(2009, 12 - 1, 20), // Ensure double digits
8249                  dateFormat = this._get(inst, "dateFormat");
8250  
8251              if (dateFormat.match(/[DM]/)) {
8252                  findMax = function(names) {
8253                      max = 0;
8254                      maxI = 0;
8255                      for (i = 0; i < names.length; i++) {
8256                          if (names[i].length > max) {
8257                              max = names[i].length;
8258                              maxI = i;
8259                          }
8260                      }
8261                      return maxI;
8262                  };
8263                  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8264                      "monthNames" : "monthNamesShort"))));
8265                  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8266                      "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
8267              }
8268              inst.input.attr("size", this._formatDate(inst, date).length);
8269          }
8270      },
8271  
8272      /* Attach an inline date picker to a div. */
8273      _inlineDatepicker: function(target, inst) {
8274          var divSpan = $(target);
8275          if (divSpan.hasClass(this.markerClassName)) {
8276              return;
8277          }
8278          divSpan.addClass(this.markerClassName).append(inst.dpDiv);
8279          $.data(target, "datepicker", inst);
8280          this._setDate(inst, this._getDefaultDate(inst), true);
8281          this._updateDatepicker(inst);
8282          this._updateAlternate(inst);
8283          //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8284          if( inst.settings.disabled ) {
8285              this._disableDatepicker( target );
8286          }
8287          // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8288          // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8289          inst.dpDiv.css( "display", "block" );
8290      },
8291  
8292      /* Pop-up the date picker in a "dialog" box.
8293       * @param  input element - ignored
8294       * @param  date    string or Date - the initial date to display
8295       * @param  onSelect  function - the function to call when a date is selected
8296       * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
8297       * @param  pos int[2] - coordinates for the dialog's position within the screen or
8298       *                    event - with x/y coordinates or
8299       *                    leave empty for default (screen centre)
8300       * @return the manager object
8301       */
8302      _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8303          var id, browserWidth, browserHeight, scrollX, scrollY,
8304              inst = this._dialogInst; // internal instance
8305  
8306          if (!inst) {
8307              this.uuid += 1;
8308              id = "dp" + this.uuid;
8309              this._dialogInput = $("<input type='text' id='" + id +
8310                  "' style='position: absolute; top: -100px; width: 0px;'/>");
8311              this._dialogInput.keydown(this._doKeyDown);
8312              $("body").append(this._dialogInput);
8313              inst = this._dialogInst = this._newInst(this._dialogInput, false);
8314              inst.settings = {};
8315              $.data(this._dialogInput[0], "datepicker", inst);
8316          }
8317          datepicker_extendRemove(inst.settings, settings || {});
8318          date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
8319          this._dialogInput.val(date);
8320  
8321          this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8322          if (!this._pos) {
8323              browserWidth = document.documentElement.clientWidth;
8324              browserHeight = document.documentElement.clientHeight;
8325              scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8326              scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8327              this._pos = // should use actual width/height below
8328                  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8329          }
8330  
8331          // move input on screen for focus, but hidden behind dialog
8332          this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
8333          inst.settings.onSelect = onSelect;
8334          this._inDialog = true;
8335          this.dpDiv.addClass(this._dialogClass);
8336          this._showDatepicker(this._dialogInput[0]);
8337          if ($.blockUI) {
8338              $.blockUI(this.dpDiv);
8339          }
8340          $.data(this._dialogInput[0], "datepicker", inst);
8341          return this;
8342      },
8343  
8344      /* Detach a datepicker from its control.
8345       * @param  target    element - the target input field or division or span
8346       */
8347      _destroyDatepicker: function(target) {
8348          var nodeName,
8349              $target = $(target),
8350              inst = $.data(target, "datepicker");
8351  
8352          if (!$target.hasClass(this.markerClassName)) {
8353              return;
8354          }
8355  
8356          nodeName = target.nodeName.toLowerCase();
8357          $.removeData(target, "datepicker");
8358          if (nodeName === "input") {
8359              inst.append.remove();
8360              inst.trigger.remove();
8361              $target.removeClass(this.markerClassName).
8362                  unbind("focus", this._showDatepicker).
8363                  unbind("keydown", this._doKeyDown).
8364                  unbind("keypress", this._doKeyPress).
8365                  unbind("keyup", this._doKeyUp);
8366          } else if (nodeName === "div" || nodeName === "span") {
8367              $target.removeClass(this.markerClassName).empty();
8368          }
8369  
8370          if ( datepicker_instActive === inst ) {
8371              datepicker_instActive = null;
8372          }
8373      },
8374  
8375      /* Enable the date picker to a jQuery selection.
8376       * @param  target    element - the target input field or division or span
8377       */
8378      _enableDatepicker: function(target) {
8379          var nodeName, inline,
8380              $target = $(target),
8381              inst = $.data(target, "datepicker");
8382  
8383          if (!$target.hasClass(this.markerClassName)) {
8384              return;
8385          }
8386  
8387          nodeName = target.nodeName.toLowerCase();
8388          if (nodeName === "input") {
8389              target.disabled = false;
8390              inst.trigger.filter("button").
8391                  each(function() { this.disabled = false; }).end().
8392                  filter("img").css({opacity: "1.0", cursor: ""});
8393          } else if (nodeName === "div" || nodeName === "span") {
8394              inline = $target.children("." + this._inlineClass);
8395              inline.children().removeClass("ui-state-disabled");
8396              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8397                  prop("disabled", false);
8398          }
8399          this._disabledInputs = $.map(this._disabledInputs,
8400              function(value) { return (value === target ? null : value); }); // delete entry
8401      },
8402  
8403      /* Disable the date picker to a jQuery selection.
8404       * @param  target    element - the target input field or division or span
8405       */
8406      _disableDatepicker: function(target) {
8407          var nodeName, inline,
8408              $target = $(target),
8409              inst = $.data(target, "datepicker");
8410  
8411          if (!$target.hasClass(this.markerClassName)) {
8412              return;
8413          }
8414  
8415          nodeName = target.nodeName.toLowerCase();
8416          if (nodeName === "input") {
8417              target.disabled = true;
8418              inst.trigger.filter("button").
8419                  each(function() { this.disabled = true; }).end().
8420                  filter("img").css({opacity: "0.5", cursor: "default"});
8421          } else if (nodeName === "div" || nodeName === "span") {
8422              inline = $target.children("." + this._inlineClass);
8423              inline.children().addClass("ui-state-disabled");
8424              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8425                  prop("disabled", true);
8426          }
8427          this._disabledInputs = $.map(this._disabledInputs,
8428              function(value) { return (value === target ? null : value); }); // delete entry
8429          this._disabledInputs[this._disabledInputs.length] = target;
8430      },
8431  
8432      /* Is the first field in a jQuery collection disabled as a datepicker?
8433       * @param  target    element - the target input field or division or span
8434       * @return boolean - true if disabled, false if enabled
8435       */
8436      _isDisabledDatepicker: function(target) {
8437          if (!target) {
8438              return false;
8439          }
8440          for (var i = 0; i < this._disabledInputs.length; i++) {
8441              if (this._disabledInputs[i] === target) {
8442                  return true;
8443              }
8444          }
8445          return false;
8446      },
8447  
8448      /* Retrieve the instance data for the target control.
8449       * @param  target  element - the target input field or division or span
8450       * @return  object - the associated instance data
8451       * @throws  error if a jQuery problem getting data
8452       */
8453      _getInst: function(target) {
8454          try {
8455              return $.data(target, "datepicker");
8456          }
8457          catch (err) {
8458              throw "Missing instance data for this datepicker";
8459          }
8460      },
8461  
8462      /* Update or retrieve the settings for a date picker attached to an input field or division.
8463       * @param  target  element - the target input field or division or span
8464       * @param  name    object - the new settings to update or
8465       *                string - the name of the setting to change or retrieve,
8466       *                when retrieving also "all" for all instance settings or
8467       *                "defaults" for all global defaults
8468       * @param  value   any - the new value for the setting
8469       *                (omit if above is an object or to retrieve a value)
8470       */
8471      _optionDatepicker: function(target, name, value) {
8472          var settings, date, minDate, maxDate,
8473              inst = this._getInst(target);
8474  
8475          if (arguments.length === 2 && typeof name === "string") {
8476              return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8477                  (inst ? (name === "all" ? $.extend({}, inst.settings) :
8478                  this._get(inst, name)) : null));
8479          }
8480  
8481          settings = name || {};
8482          if (typeof name === "string") {
8483              settings = {};
8484              settings[name] = value;
8485          }
8486  
8487          if (inst) {
8488              if (this._curInst === inst) {
8489                  this._hideDatepicker();
8490              }
8491  
8492              date = this._getDateDatepicker(target, true);
8493              minDate = this._getMinMaxDate(inst, "min");
8494              maxDate = this._getMinMaxDate(inst, "max");
8495              datepicker_extendRemove(inst.settings, settings);
8496              // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8497              if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8498                  inst.settings.minDate = this._formatDate(inst, minDate);
8499              }
8500              if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8501                  inst.settings.maxDate = this._formatDate(inst, maxDate);
8502              }
8503              if ( "disabled" in settings ) {
8504                  if ( settings.disabled ) {
8505                      this._disableDatepicker(target);
8506                  } else {
8507                      this._enableDatepicker(target);
8508                  }
8509              }
8510              this._attachments($(target), inst);
8511              this._autoSize(inst);
8512              this._setDate(inst, date);
8513              this._updateAlternate(inst);
8514              this._updateDatepicker(inst);
8515          }
8516      },
8517  
8518      // change method deprecated
8519      _changeDatepicker: function(target, name, value) {
8520          this._optionDatepicker(target, name, value);
8521      },
8522  
8523      /* Redraw the date picker attached to an input field or division.
8524       * @param  target  element - the target input field or division or span
8525       */
8526      _refreshDatepicker: function(target) {
8527          var inst = this._getInst(target);
8528          if (inst) {
8529              this._updateDatepicker(inst);
8530          }
8531      },
8532  
8533      /* Set the dates for a jQuery selection.
8534       * @param  target element - the target input field or division or span
8535       * @param  date    Date - the new date
8536       */
8537      _setDateDatepicker: function(target, date) {
8538          var inst = this._getInst(target);
8539          if (inst) {
8540              this._setDate(inst, date);
8541              this._updateDatepicker(inst);
8542              this._updateAlternate(inst);
8543          }
8544      },
8545  
8546      /* Get the date(s) for the first entry in a jQuery selection.
8547       * @param  target element - the target input field or division or span
8548       * @param  noDefault boolean - true if no default date is to be used
8549       * @return Date - the current date
8550       */
8551      _getDateDatepicker: function(target, noDefault) {
8552          var inst = this._getInst(target);
8553          if (inst && !inst.inline) {
8554              this._setDateFromField(inst, noDefault);
8555          }
8556          return (inst ? this._getDate(inst) : null);
8557      },
8558  
8559      /* Handle keystrokes. */
8560      _doKeyDown: function(event) {
8561          var onSelect, dateStr, sel,
8562              inst = $.datepicker._getInst(event.target),
8563              handled = true,
8564              isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8565  
8566          inst._keyEvent = true;
8567          if ($.datepicker._datepickerShowing) {
8568              switch (event.keyCode) {
8569                  case 9: $.datepicker._hideDatepicker();
8570                          handled = false;
8571                          break; // hide on tab out
8572                  case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8573                                      $.datepicker._currentClass + ")", inst.dpDiv);
8574                          if (sel[0]) {
8575                              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8576                          }
8577  
8578                          onSelect = $.datepicker._get(inst, "onSelect");
8579                          if (onSelect) {
8580                              dateStr = $.datepicker._formatDate(inst);
8581  
8582                              // trigger custom callback
8583                              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8584                          } else {
8585                              $.datepicker._hideDatepicker();
8586                          }
8587  
8588                          return false; // don't submit the form
8589                  case 27: $.datepicker._hideDatepicker();
8590                          break; // hide on escape
8591                  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8592                              -$.datepicker._get(inst, "stepBigMonths") :
8593                              -$.datepicker._get(inst, "stepMonths")), "M");
8594                          break; // previous month/year on page up/+ ctrl
8595                  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8596                              +$.datepicker._get(inst, "stepBigMonths") :
8597                              +$.datepicker._get(inst, "stepMonths")), "M");
8598                          break; // next month/year on page down/+ ctrl
8599                  case 35: if (event.ctrlKey || event.metaKey) {
8600                              $.datepicker._clearDate(event.target);
8601                          }
8602                          handled = event.ctrlKey || event.metaKey;
8603                          break; // clear on ctrl or command +end
8604                  case 36: if (event.ctrlKey || event.metaKey) {
8605                              $.datepicker._gotoToday(event.target);
8606                          }
8607                          handled = event.ctrlKey || event.metaKey;
8608                          break; // current on ctrl or command +home
8609                  case 37: if (event.ctrlKey || event.metaKey) {
8610                              $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8611                          }
8612                          handled = event.ctrlKey || event.metaKey;
8613                          // -1 day on ctrl or command +left
8614                          if (event.originalEvent.altKey) {
8615                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8616                                  -$.datepicker._get(inst, "stepBigMonths") :
8617                                  -$.datepicker._get(inst, "stepMonths")), "M");
8618                          }
8619                          // next month/year on alt +left on Mac
8620                          break;
8621                  case 38: if (event.ctrlKey || event.metaKey) {
8622                              $.datepicker._adjustDate(event.target, -7, "D");
8623                          }
8624                          handled = event.ctrlKey || event.metaKey;
8625                          break; // -1 week on ctrl or command +up
8626                  case 39: if (event.ctrlKey || event.metaKey) {
8627                              $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8628                          }
8629                          handled = event.ctrlKey || event.metaKey;
8630                          // +1 day on ctrl or command +right
8631                          if (event.originalEvent.altKey) {
8632                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8633                                  +$.datepicker._get(inst, "stepBigMonths") :
8634                                  +$.datepicker._get(inst, "stepMonths")), "M");
8635                          }
8636                          // next month/year on alt +right
8637                          break;
8638                  case 40: if (event.ctrlKey || event.metaKey) {
8639                              $.datepicker._adjustDate(event.target, +7, "D");
8640                          }
8641                          handled = event.ctrlKey || event.metaKey;
8642                          break; // +1 week on ctrl or command +down
8643                  default: handled = false;
8644              }
8645          } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8646              $.datepicker._showDatepicker(this);
8647          } else {
8648              handled = false;
8649          }
8650  
8651          if (handled) {
8652              event.preventDefault();
8653              event.stopPropagation();
8654          }
8655      },
8656  
8657      /* Filter entered characters - based on date format. */
8658      _doKeyPress: function(event) {
8659          var chars, chr,
8660              inst = $.datepicker._getInst(event.target);
8661  
8662          if ($.datepicker._get(inst, "constrainInput")) {
8663              chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8664              chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8665              return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8666          }
8667      },
8668  
8669      /* Synchronise manual entry and field/alternate field. */
8670      _doKeyUp: function(event) {
8671          var date,
8672              inst = $.datepicker._getInst(event.target);
8673  
8674          if (inst.input.val() !== inst.lastVal) {
8675              try {
8676                  date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8677                      (inst.input ? inst.input.val() : null),
8678                      $.datepicker._getFormatConfig(inst));
8679  
8680                  if (date) { // only if valid
8681                      $.datepicker._setDateFromField(inst);
8682                      $.datepicker._updateAlternate(inst);
8683                      $.datepicker._updateDatepicker(inst);
8684                  }
8685              }
8686              catch (err) {
8687              }
8688          }
8689          return true;
8690      },
8691  
8692      /* Pop-up the date picker for a given input field.
8693       * If false returned from beforeShow event handler do not show.
8694       * @param  input  element - the input field attached to the date picker or
8695       *                    event - if triggered by focus
8696       */
8697      _showDatepicker: function(input) {
8698          input = input.target || input;
8699          if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8700              input = $("input", input.parentNode)[0];
8701          }
8702  
8703          if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8704              return;
8705          }
8706  
8707          var inst, beforeShow, beforeShowSettings, isFixed,
8708              offset, showAnim, duration;
8709  
8710          inst = $.datepicker._getInst(input);
8711          if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8712              $.datepicker._curInst.dpDiv.stop(true, true);
8713              if ( inst && $.datepicker._datepickerShowing ) {
8714                  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8715              }
8716          }
8717  
8718          beforeShow = $.datepicker._get(inst, "beforeShow");
8719          beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8720          if(beforeShowSettings === false){
8721              return;
8722          }
8723          datepicker_extendRemove(inst.settings, beforeShowSettings);
8724  
8725          inst.lastVal = null;
8726          $.datepicker._lastInput = input;
8727          $.datepicker._setDateFromField(inst);
8728  
8729          if ($.datepicker._inDialog) { // hide cursor
8730              input.value = "";
8731          }
8732          if (!$.datepicker._pos) { // position below input
8733              $.datepicker._pos = $.datepicker._findPos(input);
8734              $.datepicker._pos[1] += input.offsetHeight; // add the height
8735          }
8736  
8737          isFixed = false;
8738          $(input).parents().each(function() {
8739              isFixed |= $(this).css("position") === "fixed";
8740              return !isFixed;
8741          });
8742  
8743          offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8744          $.datepicker._pos = null;
8745          //to avoid flashes on Firefox
8746          inst.dpDiv.empty();
8747          // determine sizing offscreen
8748          inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8749          $.datepicker._updateDatepicker(inst);
8750          // fix width for dynamic number of date pickers
8751          // and adjust position before showing
8752          offset = $.datepicker._checkOffset(inst, offset, isFixed);
8753          inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8754              "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8755              left: offset.left + "px", top: offset.top + "px"});
8756  
8757          if (!inst.inline) {
8758              showAnim = $.datepicker._get(inst, "showAnim");
8759              duration = $.datepicker._get(inst, "duration");
8760              inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
8761              $.datepicker._datepickerShowing = true;
8762  
8763              if ( $.effects && $.effects.effect[ showAnim ] ) {
8764                  inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8765              } else {
8766                  inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8767              }
8768  
8769              if ( $.datepicker._shouldFocusInput( inst ) ) {
8770                  inst.input.focus();
8771              }
8772  
8773              $.datepicker._curInst = inst;
8774          }
8775      },
8776  
8777      /* Generate the date picker content. */
8778      _updateDatepicker: function(inst) {
8779          this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8780          datepicker_instActive = inst; // for delegate hover events
8781          inst.dpDiv.empty().append(this._generateHTML(inst));
8782          this._attachHandlers(inst);
8783  
8784          var origyearshtml,
8785              numMonths = this._getNumberOfMonths(inst),
8786              cols = numMonths[1],
8787              width = 17,
8788              activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
8789  
8790          if ( activeCell.length > 0 ) {
8791              datepicker_handleMouseover.apply( activeCell.get( 0 ) );
8792          }
8793  
8794          inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8795          if (cols > 1) {
8796              inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8797          }
8798          inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8799              "Class"]("ui-datepicker-multi");
8800          inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8801              "Class"]("ui-datepicker-rtl");
8802  
8803          if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8804              inst.input.focus();
8805          }
8806  
8807          // deffered render of the years select (to avoid flashes on Firefox)
8808          if( inst.yearshtml ){
8809              origyearshtml = inst.yearshtml;
8810              setTimeout(function(){
8811                  //assure that inst.yearshtml didn't change.
8812                  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8813                      inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8814                  }
8815                  origyearshtml = inst.yearshtml = null;
8816              }, 0);
8817          }
8818      },
8819  
8820      // #6694 - don't focus the input if it's already focused
8821      // this breaks the change event in IE
8822      // Support: IE and jQuery <1.9
8823      _shouldFocusInput: function( inst ) {
8824          return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8825      },
8826  
8827      /* Check positioning to remain on screen. */
8828      _checkOffset: function(inst, offset, isFixed) {
8829          var dpWidth = inst.dpDiv.outerWidth(),
8830              dpHeight = inst.dpDiv.outerHeight(),
8831              inputWidth = inst.input ? inst.input.outerWidth() : 0,
8832              inputHeight = inst.input ? inst.input.outerHeight() : 0,
8833              viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8834              viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8835  
8836          offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8837          offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8838          offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8839  
8840          // now check if datepicker is showing outside window viewport - move to a better place if so.
8841          offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8842              Math.abs(offset.left + dpWidth - viewWidth) : 0);
8843          offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8844              Math.abs(dpHeight + inputHeight) : 0);
8845  
8846          return offset;
8847      },
8848  
8849      /* Find an object's position on the screen. */
8850      _findPos: function(obj) {
8851          var position,
8852              inst = this._getInst(obj),
8853              isRTL = this._get(inst, "isRTL");
8854  
8855          while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8856              obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8857          }
8858  
8859          position = $(obj).offset();
8860          return [position.left, position.top];
8861      },
8862  
8863      /* Hide the date picker from view.
8864       * @param  input  element - the input field attached to the date picker
8865       */
8866      _hideDatepicker: function(input) {
8867          var showAnim, duration, postProcess, onClose,
8868              inst = this._curInst;
8869  
8870          if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8871              return;
8872          }
8873  
8874          if (this._datepickerShowing) {
8875              showAnim = this._get(inst, "showAnim");
8876              duration = this._get(inst, "duration");
8877              postProcess = function() {
8878                  $.datepicker._tidyDialog(inst);
8879              };
8880  
8881              // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8882              if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8883                  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8884              } else {
8885                  inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8886                      (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8887              }
8888  
8889              if (!showAnim) {
8890                  postProcess();
8891              }
8892              this._datepickerShowing = false;
8893  
8894              onClose = this._get(inst, "onClose");
8895              if (onClose) {
8896                  onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8897              }
8898  
8899              this._lastInput = null;
8900              if (this._inDialog) {
8901                  this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8902                  if ($.blockUI) {
8903                      $.unblockUI();
8904                      $("body").append(this.dpDiv);
8905                  }
8906              }
8907              this._inDialog = false;
8908          }
8909      },
8910  
8911      /* Tidy up after a dialog display. */
8912      _tidyDialog: function(inst) {
8913          inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8914      },
8915  
8916      /* Close date picker if clicked elsewhere. */
8917      _checkExternalClick: function(event) {
8918          if (!$.datepicker._curInst) {
8919              return;
8920          }
8921  
8922          var $target = $(event.target),
8923              inst = $.datepicker._getInst($target[0]);
8924  
8925          if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8926                  $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8927                  !$target.hasClass($.datepicker.markerClassName) &&
8928                  !$target.closest("." + $.datepicker._triggerClass).length &&
8929                  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8930              ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8931                  $.datepicker._hideDatepicker();
8932          }
8933      },
8934  
8935      /* Adjust one of the date sub-fields. */
8936      _adjustDate: function(id, offset, period) {
8937          var target = $(id),
8938              inst = this._getInst(target[0]);
8939  
8940          if (this._isDisabledDatepicker(target[0])) {
8941              return;
8942          }
8943          this._adjustInstDate(inst, offset +
8944              (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8945              period);
8946          this._updateDatepicker(inst);
8947      },
8948  
8949      /* Action for current link. */
8950      _gotoToday: function(id) {
8951          var date,
8952              target = $(id),
8953              inst = this._getInst(target[0]);
8954  
8955          if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8956              inst.selectedDay = inst.currentDay;
8957              inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8958              inst.drawYear = inst.selectedYear = inst.currentYear;
8959          } else {
8960              date = new Date();
8961              inst.selectedDay = date.getDate();
8962              inst.drawMonth = inst.selectedMonth = date.getMonth();
8963              inst.drawYear = inst.selectedYear = date.getFullYear();
8964          }
8965          this._notifyChange(inst);
8966          this._adjustDate(target);
8967      },
8968  
8969      /* Action for selecting a new month/year. */
8970      _selectMonthYear: function(id, select, period) {
8971          var target = $(id),
8972              inst = this._getInst(target[0]);
8973  
8974          inst["selected" + (period === "M" ? "Month" : "Year")] =
8975          inst["draw" + (period === "M" ? "Month" : "Year")] =
8976              parseInt(select.options[select.selectedIndex].value,10);
8977  
8978          this._notifyChange(inst);
8979          this._adjustDate(target);
8980      },
8981  
8982      /* Action for selecting a day. */
8983      _selectDay: function(id, month, year, td) {
8984          var inst,
8985              target = $(id);
8986  
8987          if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8988              return;
8989          }
8990  
8991          inst = this._getInst(target[0]);
8992          inst.selectedDay = inst.currentDay = $("a", td).html();
8993          inst.selectedMonth = inst.currentMonth = month;
8994          inst.selectedYear = inst.currentYear = year;
8995          this._selectDate(id, this._formatDate(inst,
8996              inst.currentDay, inst.currentMonth, inst.currentYear));
8997      },
8998  
8999      /* Erase the input field and hide the date picker. */
9000      _clearDate: function(id) {
9001          var target = $(id);
9002          this._selectDate(target, "");
9003      },
9004  
9005      /* Update the input field with the selected date. */
9006      _selectDate: function(id, dateStr) {
9007          var onSelect,
9008              target = $(id),
9009              inst = this._getInst(target[0]);
9010  
9011          dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9012          if (inst.input) {
9013              inst.input.val(dateStr);
9014          }
9015          this._updateAlternate(inst);
9016  
9017          onSelect = this._get(inst, "onSelect");
9018          if (onSelect) {
9019              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
9020          } else if (inst.input) {
9021              inst.input.trigger("change"); // fire the change event
9022          }
9023  
9024          if (inst.inline){
9025              this._updateDatepicker(inst);
9026          } else {
9027              this._hideDatepicker();
9028              this._lastInput = inst.input[0];
9029              if (typeof(inst.input[0]) !== "object") {
9030                  inst.input.focus(); // restore focus
9031              }
9032              this._lastInput = null;
9033          }
9034      },
9035  
9036      /* Update any alternate field to synchronise with the main field. */
9037      _updateAlternate: function(inst) {
9038          var altFormat, date, dateStr,
9039              altField = this._get(inst, "altField");
9040  
9041          if (altField) { // update alternate field too
9042              altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
9043              date = this._getDate(inst);
9044              dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9045              $(altField).each(function() { $(this).val(dateStr); });
9046          }
9047      },
9048  
9049      /* Set as beforeShowDay function to prevent selection of weekends.
9050       * @param  date  Date - the date to customise
9051       * @return [boolean, string] - is this date selectable?, what is its CSS class?
9052       */
9053      noWeekends: function(date) {
9054          var day = date.getDay();
9055          return [(day > 0 && day < 6), ""];
9056      },
9057  
9058      /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9059       * @param  date  Date - the date to get the week for
9060       * @return  number - the number of the week within the year that contains this date
9061       */
9062      iso8601Week: function(date) {
9063          var time,
9064              checkDate = new Date(date.getTime());
9065  
9066          // Find Thursday of this week starting on Monday
9067          checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9068  
9069          time = checkDate.getTime();
9070          checkDate.setMonth(0); // Compare with Jan 1
9071          checkDate.setDate(1);
9072          return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9073      },
9074  
9075      /* Parse a string value into a date object.
9076       * See formatDate below for the possible formats.
9077       *
9078       * @param  format string - the expected format of the date
9079       * @param  value string - the date in the above format
9080       * @param  settings Object - attributes include:
9081       *                    shortYearCutoff  number - the cutoff year for determining the century (optional)
9082       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9083       *                    dayNames        string[7] - names of the days from Sunday (optional)
9084       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
9085       *                    monthNames        string[12] - names of the months (optional)
9086       * @return  Date - the extracted date value or null if value is blank
9087       */
9088      parseDate: function (format, value, settings) {
9089          if (format == null || value == null) {
9090              throw "Invalid arguments";
9091          }
9092  
9093          value = (typeof value === "object" ? value.toString() : value + "");
9094          if (value === "") {
9095              return null;
9096          }
9097  
9098          var iFormat, dim, extra,
9099              iValue = 0,
9100              shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
9101              shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
9102                  new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
9103              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9104              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9105              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9106              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9107              year = -1,
9108              month = -1,
9109              day = -1,
9110              doy = -1,
9111              literal = false,
9112              date,
9113              // Check whether a format character is doubled
9114              lookAhead = function(match) {
9115                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9116                  if (matches) {
9117                      iFormat++;
9118                  }
9119                  return matches;
9120              },
9121              // Extract a number from the string value
9122              getNumber = function(match) {
9123                  var isDoubled = lookAhead(match),
9124                      size = (match === "@" ? 14 : (match === "!" ? 20 :
9125                      (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
9126                      minSize = (match === "y" ? size : 1),
9127                      digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
9128                      num = value.substring(iValue).match(digits);
9129                  if (!num) {
9130                      throw "Missing number at position " + iValue;
9131                  }
9132                  iValue += num[0].length;
9133                  return parseInt(num[0], 10);
9134              },
9135              // Extract a name from the string value and convert to an index
9136              getName = function(match, shortNames, longNames) {
9137                  var index = -1,
9138                      names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9139                          return [ [k, v] ];
9140                      }).sort(function (a, b) {
9141                          return -(a[1].length - b[1].length);
9142                      });
9143  
9144                  $.each(names, function (i, pair) {
9145                      var name = pair[1];
9146                      if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
9147                          index = pair[0];
9148                          iValue += name.length;
9149                          return false;
9150                      }
9151                  });
9152                  if (index !== -1) {
9153                      return index + 1;
9154                  } else {
9155                      throw "Unknown name at position " + iValue;
9156                  }
9157              },
9158              // Confirm that a literal character matches the string value
9159              checkLiteral = function() {
9160                  if (value.charAt(iValue) !== format.charAt(iFormat)) {
9161                      throw "Unexpected literal at position " + iValue;
9162                  }
9163                  iValue++;
9164              };
9165  
9166          for (iFormat = 0; iFormat < format.length; iFormat++) {
9167              if (literal) {
9168                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9169                      literal = false;
9170                  } else {
9171                      checkLiteral();
9172                  }
9173              } else {
9174                  switch (format.charAt(iFormat)) {
9175                      case "d":
9176                          day = getNumber("d");
9177                          break;
9178                      case "D":
9179                          getName("D", dayNamesShort, dayNames);
9180                          break;
9181                      case "o":
9182                          doy = getNumber("o");
9183                          break;
9184                      case "m":
9185                          month = getNumber("m");
9186                          break;
9187                      case "M":
9188                          month = getName("M", monthNamesShort, monthNames);
9189                          break;
9190                      case "y":
9191                          year = getNumber("y");
9192                          break;
9193                      case "@":
9194                          date = new Date(getNumber("@"));
9195                          year = date.getFullYear();
9196                          month = date.getMonth() + 1;
9197                          day = date.getDate();
9198                          break;
9199                      case "!":
9200                          date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
9201                          year = date.getFullYear();
9202                          month = date.getMonth() + 1;
9203                          day = date.getDate();
9204                          break;
9205                      case "'":
9206                          if (lookAhead("'")){
9207                              checkLiteral();
9208                          } else {
9209                              literal = true;
9210                          }
9211                          break;
9212                      default:
9213                          checkLiteral();
9214                  }
9215              }
9216          }
9217  
9218          if (iValue < value.length){
9219              extra = value.substr(iValue);
9220              if (!/^\s+/.test(extra)) {
9221                  throw "Extra/unparsed characters found in date: " + extra;
9222              }
9223          }
9224  
9225          if (year === -1) {
9226              year = new Date().getFullYear();
9227          } else if (year < 100) {
9228              year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9229                  (year <= shortYearCutoff ? 0 : -100);
9230          }
9231  
9232          if (doy > -1) {
9233              month = 1;
9234              day = doy;
9235              do {
9236                  dim = this._getDaysInMonth(year, month - 1);
9237                  if (day <= dim) {
9238                      break;
9239                  }
9240                  month++;
9241                  day -= dim;
9242              } while (true);
9243          }
9244  
9245          date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9246          if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
9247              throw "Invalid date"; // E.g. 31/02/00
9248          }
9249          return date;
9250      },
9251  
9252      /* Standard date formats. */
9253      ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
9254      COOKIE: "D, dd M yy",
9255      ISO_8601: "yy-mm-dd",
9256      RFC_822: "D, d M y",
9257      RFC_850: "DD, dd-M-y",
9258      RFC_1036: "D, d M y",
9259      RFC_1123: "D, d M yy",
9260      RFC_2822: "D, d M yy",
9261      RSS: "D, d M y", // RFC 822
9262      TICKS: "!",
9263      TIMESTAMP: "@",
9264      W3C: "yy-mm-dd", // ISO 8601
9265  
9266      _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9267          Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9268  
9269      /* Format a date object into a string value.
9270       * The format can be combinations of the following:
9271       * d  - day of month (no leading zero)
9272       * dd - day of month (two digit)
9273       * o  - day of year (no leading zeros)
9274       * oo - day of year (three digit)
9275       * D  - day name short
9276       * DD - day name long
9277       * m  - month of year (no leading zero)
9278       * mm - month of year (two digit)
9279       * M  - month name short
9280       * MM - month name long
9281       * y  - year (two digit)
9282       * yy - year (four digit)
9283       * @ - Unix timestamp (ms since 01/01/1970)
9284       * ! - Windows ticks (100ns since 01/01/0001)
9285       * "..." - literal text
9286       * '' - single quote
9287       *
9288       * @param  format string - the desired format of the date
9289       * @param  date Date - the date value to format
9290       * @param  settings Object - attributes include:
9291       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9292       *                    dayNames        string[7] - names of the days from Sunday (optional)
9293       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
9294       *                    monthNames        string[12] - names of the months (optional)
9295       * @return  string - the date in the above format
9296       */
9297      formatDate: function (format, date, settings) {
9298          if (!date) {
9299              return "";
9300          }
9301  
9302          var iFormat,
9303              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
9304              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
9305              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
9306              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
9307              // Check whether a format character is doubled
9308              lookAhead = function(match) {
9309                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9310                  if (matches) {
9311                      iFormat++;
9312                  }
9313                  return matches;
9314              },
9315              // Format a number, with leading zero if necessary
9316              formatNumber = function(match, value, len) {
9317                  var num = "" + value;
9318                  if (lookAhead(match)) {
9319                      while (num.length < len) {
9320                          num = "0" + num;
9321                      }
9322                  }
9323                  return num;
9324              },
9325              // Format a name, short or long as requested
9326              formatName = function(match, value, shortNames, longNames) {
9327                  return (lookAhead(match) ? longNames[value] : shortNames[value]);
9328              },
9329              output = "",
9330              literal = false;
9331  
9332          if (date) {
9333              for (iFormat = 0; iFormat < format.length; iFormat++) {
9334                  if (literal) {
9335                      if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9336                          literal = false;
9337                      } else {
9338                          output += format.charAt(iFormat);
9339                      }
9340                  } else {
9341                      switch (format.charAt(iFormat)) {
9342                          case "d":
9343                              output += formatNumber("d", date.getDate(), 2);
9344                              break;
9345                          case "D":
9346                              output += formatName("D", date.getDay(), dayNamesShort, dayNames);
9347                              break;
9348                          case "o":
9349                              output += formatNumber("o",
9350                                  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9351                              break;
9352                          case "m":
9353                              output += formatNumber("m", date.getMonth() + 1, 2);
9354                              break;
9355                          case "M":
9356                              output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
9357                              break;
9358                          case "y":
9359                              output += (lookAhead("y") ? date.getFullYear() :
9360                                  (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
9361                              break;
9362                          case "@":
9363                              output += date.getTime();
9364                              break;
9365                          case "!":
9366                              output += date.getTime() * 10000 + this._ticksTo1970;
9367                              break;
9368                          case "'":
9369                              if (lookAhead("'")) {
9370                                  output += "'";
9371                              } else {
9372                                  literal = true;
9373                              }
9374                              break;
9375                          default:
9376                              output += format.charAt(iFormat);
9377                      }
9378                  }
9379              }
9380          }
9381          return output;
9382      },
9383  
9384      /* Extract all possible characters from the date format. */
9385      _possibleChars: function (format) {
9386          var iFormat,
9387              chars = "",
9388              literal = false,
9389              // Check whether a format character is doubled
9390              lookAhead = function(match) {
9391                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
9392                  if (matches) {
9393                      iFormat++;
9394                  }
9395                  return matches;
9396              };
9397  
9398          for (iFormat = 0; iFormat < format.length; iFormat++) {
9399              if (literal) {
9400                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
9401                      literal = false;
9402                  } else {
9403                      chars += format.charAt(iFormat);
9404                  }
9405              } else {
9406                  switch (format.charAt(iFormat)) {
9407                      case "d": case "m": case "y": case "@":
9408                          chars += "0123456789";
9409                          break;
9410                      case "D": case "M":
9411                          return null; // Accept anything
9412                      case "'":
9413                          if (lookAhead("'")) {
9414                              chars += "'";
9415                          } else {
9416                              literal = true;
9417                          }
9418                          break;
9419                      default:
9420                          chars += format.charAt(iFormat);
9421                  }
9422              }
9423          }
9424          return chars;
9425      },
9426  
9427      /* Get a setting value, defaulting if necessary. */
9428      _get: function(inst, name) {
9429          return inst.settings[name] !== undefined ?
9430              inst.settings[name] : this._defaults[name];
9431      },
9432  
9433      /* Parse existing date and initialise date picker. */
9434      _setDateFromField: function(inst, noDefault) {
9435          if (inst.input.val() === inst.lastVal) {
9436              return;
9437          }
9438  
9439          var dateFormat = this._get(inst, "dateFormat"),
9440              dates = inst.lastVal = inst.input ? inst.input.val() : null,
9441              defaultDate = this._getDefaultDate(inst),
9442              date = defaultDate,
9443              settings = this._getFormatConfig(inst);
9444  
9445          try {
9446              date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9447          } catch (event) {
9448              dates = (noDefault ? "" : dates);
9449          }
9450          inst.selectedDay = date.getDate();
9451          inst.drawMonth = inst.selectedMonth = date.getMonth();
9452          inst.drawYear = inst.selectedYear = date.getFullYear();
9453          inst.currentDay = (dates ? date.getDate() : 0);
9454          inst.currentMonth = (dates ? date.getMonth() : 0);
9455          inst.currentYear = (dates ? date.getFullYear() : 0);
9456          this._adjustInstDate(inst);
9457      },
9458  
9459      /* Retrieve the default date shown on opening. */
9460      _getDefaultDate: function(inst) {
9461          return this._restrictMinMax(inst,
9462              this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9463      },
9464  
9465      /* A date may be specified as an exact value or a relative one. */
9466      _determineDate: function(inst, date, defaultDate) {
9467          var offsetNumeric = function(offset) {
9468                  var date = new Date();
9469                  date.setDate(date.getDate() + offset);
9470                  return date;
9471              },
9472              offsetString = function(offset) {
9473                  try {
9474                      return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9475                          offset, $.datepicker._getFormatConfig(inst));
9476                  }
9477                  catch (e) {
9478                      // Ignore
9479                  }
9480  
9481                  var date = (offset.toLowerCase().match(/^c/) ?
9482                      $.datepicker._getDate(inst) : null) || new Date(),
9483                      year = date.getFullYear(),
9484                      month = date.getMonth(),
9485                      day = date.getDate(),
9486                      pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9487                      matches = pattern.exec(offset);
9488  
9489                  while (matches) {
9490                      switch (matches[2] || "d") {
9491                          case "d" : case "D" :
9492                              day += parseInt(matches[1],10); break;
9493                          case "w" : case "W" :
9494                              day += parseInt(matches[1],10) * 7; break;
9495                          case "m" : case "M" :
9496                              month += parseInt(matches[1],10);
9497                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9498                              break;
9499                          case "y": case "Y" :
9500                              year += parseInt(matches[1],10);
9501                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9502                              break;
9503                      }
9504                      matches = pattern.exec(offset);
9505                  }
9506                  return new Date(year, month, day);
9507              },
9508              newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9509                  (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9510  
9511          newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9512          if (newDate) {
9513              newDate.setHours(0);
9514              newDate.setMinutes(0);
9515              newDate.setSeconds(0);
9516              newDate.setMilliseconds(0);
9517          }
9518          return this._daylightSavingAdjust(newDate);
9519      },
9520  
9521      /* Handle switch to/from daylight saving.
9522       * Hours may be non-zero on daylight saving cut-over:
9523       * > 12 when midnight changeover, but then cannot generate
9524       * midnight datetime, so jump to 1AM, otherwise reset.
9525       * @param  date  (Date) the date to check
9526       * @return  (Date) the corrected date
9527       */
9528      _daylightSavingAdjust: function(date) {
9529          if (!date) {
9530              return null;
9531          }
9532          date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9533          return date;
9534      },
9535  
9536      /* Set the date(s) directly. */
9537      _setDate: function(inst, date, noChange) {
9538          var clear = !date,
9539              origMonth = inst.selectedMonth,
9540              origYear = inst.selectedYear,
9541              newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9542  
9543          inst.selectedDay = inst.currentDay = newDate.getDate();
9544          inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9545          inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9546          if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9547              this._notifyChange(inst);
9548          }
9549          this._adjustInstDate(inst);
9550          if (inst.input) {
9551              inst.input.val(clear ? "" : this._formatDate(inst));
9552          }
9553      },
9554  
9555      /* Retrieve the date(s) directly. */
9556      _getDate: function(inst) {
9557          var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9558              this._daylightSavingAdjust(new Date(
9559              inst.currentYear, inst.currentMonth, inst.currentDay)));
9560              return startDate;
9561      },
9562  
9563      /* Attach the onxxx handlers.  These are declared statically so
9564       * they work with static code transformers like Caja.
9565       */
9566      _attachHandlers: function(inst) {
9567          var stepMonths = this._get(inst, "stepMonths"),
9568              id = "#" + inst.id.replace( /\\\\/g, "\\" );
9569          inst.dpDiv.find("[data-handler]").map(function () {
9570              var handler = {
9571                  prev: function () {
9572                      $.datepicker._adjustDate(id, -stepMonths, "M");
9573                  },
9574                  next: function () {
9575                      $.datepicker._adjustDate(id, +stepMonths, "M");
9576                  },
9577                  hide: function () {
9578                      $.datepicker._hideDatepicker();
9579                  },
9580                  today: function () {
9581                      $.datepicker._gotoToday(id);
9582                  },
9583                  selectDay: function () {
9584                      $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9585                      return false;
9586                  },
9587                  selectMonth: function () {
9588                      $.datepicker._selectMonthYear(id, this, "M");
9589                      return false;
9590                  },
9591                  selectYear: function () {
9592                      $.datepicker._selectMonthYear(id, this, "Y");
9593                      return false;
9594                  }
9595              };
9596              $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9597          });
9598      },
9599  
9600      /* Generate the HTML for the current state of the date picker. */
9601      _generateHTML: function(inst) {
9602          var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9603              controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9604              monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9605              selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9606              cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9607              printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9608              tempDate = new Date(),
9609              today = this._daylightSavingAdjust(
9610                  new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9611              isRTL = this._get(inst, "isRTL"),
9612              showButtonPanel = this._get(inst, "showButtonPanel"),
9613              hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9614              navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9615              numMonths = this._getNumberOfMonths(inst),
9616              showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9617              stepMonths = this._get(inst, "stepMonths"),
9618              isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9619              currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9620                  new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9621              minDate = this._getMinMaxDate(inst, "min"),
9622              maxDate = this._getMinMaxDate(inst, "max"),
9623              drawMonth = inst.drawMonth - showCurrentAtPos,
9624              drawYear = inst.drawYear;
9625  
9626          if (drawMonth < 0) {
9627              drawMonth += 12;
9628              drawYear--;
9629          }
9630          if (maxDate) {
9631              maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9632                  maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9633              maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9634              while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9635                  drawMonth--;
9636                  if (drawMonth < 0) {
9637                      drawMonth = 11;
9638                      drawYear--;
9639                  }
9640              }
9641          }
9642          inst.drawMonth = drawMonth;
9643          inst.drawYear = drawYear;
9644  
9645          prevText = this._get(inst, "prevText");
9646          prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9647              this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9648              this._getFormatConfig(inst)));
9649  
9650          prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9651              "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9652              " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9653              (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>"));
9654  
9655          nextText = this._get(inst, "nextText");
9656          nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9657              this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9658              this._getFormatConfig(inst)));
9659  
9660          next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9661              "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9662              " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9663              (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>"));
9664  
9665          currentText = this._get(inst, "currentText");
9666          gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9667          currentText = (!navigationAsDateFormat ? currentText :
9668              this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9669  
9670          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'>" +
9671              this._get(inst, "closeText") + "</button>" : "");
9672  
9673          buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9674              (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'" +
9675              ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9676  
9677          firstDay = parseInt(this._get(inst, "firstDay"),10);
9678          firstDay = (isNaN(firstDay) ? 0 : firstDay);
9679  
9680          showWeek = this._get(inst, "showWeek");
9681          dayNames = this._get(inst, "dayNames");
9682          dayNamesMin = this._get(inst, "dayNamesMin");
9683          monthNames = this._get(inst, "monthNames");
9684          monthNamesShort = this._get(inst, "monthNamesShort");
9685          beforeShowDay = this._get(inst, "beforeShowDay");
9686          showOtherMonths = this._get(inst, "showOtherMonths");
9687          selectOtherMonths = this._get(inst, "selectOtherMonths");
9688          defaultDate = this._getDefaultDate(inst);
9689          html = "";
9690          dow;
9691          for (row = 0; row < numMonths[0]; row++) {
9692              group = "";
9693              this.maxRows = 4;
9694              for (col = 0; col < numMonths[1]; col++) {
9695                  selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9696                  cornerClass = " ui-corner-all";
9697                  calender = "";
9698                  if (isMultiMonth) {
9699                      calender += "<div class='ui-datepicker-group";
9700                      if (numMonths[1] > 1) {
9701                          switch (col) {
9702                              case 0: calender += " ui-datepicker-group-first";
9703                                  cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9704                              case numMonths[1]-1: calender += " ui-datepicker-group-last";
9705                                  cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9706                              default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9707                          }
9708                      }
9709                      calender += "'>";
9710                  }
9711                  calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9712                      (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9713                      (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9714                      this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9715                      row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9716                      "</div><table class='ui-datepicker-calendar'><thead>" +
9717                      "<tr>";
9718                  thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9719                  for (dow = 0; dow < 7; dow++) { // days of the week
9720                      day = (dow + firstDay) % 7;
9721                      thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9722                          "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9723                  }
9724                  calender += thead + "</tr></thead><tbody>";
9725                  daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9726                  if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9727                      inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9728                  }
9729                  leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9730                  curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9731                  numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9732                  this.maxRows = numRows;
9733                  printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9734                  for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9735                      calender += "<tr>";
9736                      tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9737                          this._get(inst, "calculateWeek")(printDate) + "</td>");
9738                      for (dow = 0; dow < 7; dow++) { // create date picker days
9739                          daySettings = (beforeShowDay ?
9740                              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9741                          otherMonth = (printDate.getMonth() !== drawMonth);
9742                          unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9743                              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9744                          tbody += "<td class='" +
9745                              ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9746                              (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9747                              ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9748                              (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9749                              // or defaultDate is current printedDate and defaultDate is selectedDate
9750                              " " + this._dayOverClass : "") + // highlight selected day
9751                              (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
9752                              (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9753                              (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9754                              (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9755                              ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9756                              (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9757                              (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9758                              (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9759                              (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9760                              (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9761                              (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9762                              "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9763                          printDate.setDate(printDate.getDate() + 1);
9764                          printDate = this._daylightSavingAdjust(printDate);
9765                      }
9766                      calender += tbody + "</tr>";
9767                  }
9768                  drawMonth++;
9769                  if (drawMonth > 11) {
9770                      drawMonth = 0;
9771                      drawYear++;
9772                  }
9773                  calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9774                              ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9775                  group += calender;
9776              }
9777              html += group;
9778          }
9779          html += buttonPanel;
9780          inst._keyEvent = false;
9781          return html;
9782      },
9783  
9784      /* Generate the month and year header. */
9785      _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9786              secondary, monthNames, monthNamesShort) {
9787  
9788          var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9789              changeMonth = this._get(inst, "changeMonth"),
9790              changeYear = this._get(inst, "changeYear"),
9791              showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9792              html = "<div class='ui-datepicker-title'>",
9793              monthHtml = "";
9794  
9795          // month selection
9796          if (secondary || !changeMonth) {
9797              monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9798          } else {
9799              inMinYear = (minDate && minDate.getFullYear() === drawYear);
9800              inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9801              monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9802              for ( month = 0; month < 12; month++) {
9803                  if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9804                      monthHtml += "<option value='" + month + "'" +
9805                          (month === drawMonth ? " selected='selected'" : "") +
9806                          ">" + monthNamesShort[month] + "</option>";
9807                  }
9808              }
9809              monthHtml += "</select>";
9810          }
9811  
9812          if (!showMonthAfterYear) {
9813              html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9814          }
9815  
9816          // year selection
9817          if ( !inst.yearshtml ) {
9818              inst.yearshtml = "";
9819              if (secondary || !changeYear) {
9820                  html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9821              } else {
9822                  // determine range of years to display
9823                  years = this._get(inst, "yearRange").split(":");
9824                  thisYear = new Date().getFullYear();
9825                  determineYear = function(value) {
9826                      var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9827                          (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9828                          parseInt(value, 10)));
9829                      return (isNaN(year) ? thisYear : year);
9830                  };
9831                  year = determineYear(years[0]);
9832                  endYear = Math.max(year, determineYear(years[1] || ""));
9833                  year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9834                  endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9835                  inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9836                  for (; year <= endYear; year++) {
9837                      inst.yearshtml += "<option value='" + year + "'" +
9838                          (year === drawYear ? " selected='selected'" : "") +
9839                          ">" + year + "</option>";
9840                  }
9841                  inst.yearshtml += "</select>";
9842  
9843                  html += inst.yearshtml;
9844                  inst.yearshtml = null;
9845              }
9846          }
9847  
9848          html += this._get(inst, "yearSuffix");
9849          if (showMonthAfterYear) {
9850              html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9851          }
9852          html += "</div>"; // Close datepicker_header
9853          return html;
9854      },
9855  
9856      /* Adjust one of the date sub-fields. */
9857      _adjustInstDate: function(inst, offset, period) {
9858          var year = inst.drawYear + (period === "Y" ? offset : 0),
9859              month = inst.drawMonth + (period === "M" ? offset : 0),
9860              day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9861              date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9862  
9863          inst.selectedDay = date.getDate();
9864          inst.drawMonth = inst.selectedMonth = date.getMonth();
9865          inst.drawYear = inst.selectedYear = date.getFullYear();
9866          if (period === "M" || period === "Y") {
9867              this._notifyChange(inst);
9868          }
9869      },
9870  
9871      /* Ensure a date is within any min/max bounds. */
9872      _restrictMinMax: function(inst, date) {
9873          var minDate = this._getMinMaxDate(inst, "min"),
9874              maxDate = this._getMinMaxDate(inst, "max"),
9875              newDate = (minDate && date < minDate ? minDate : date);
9876          return (maxDate && newDate > maxDate ? maxDate : newDate);
9877      },
9878  
9879      /* Notify change of month/year. */
9880      _notifyChange: function(inst) {
9881          var onChange = this._get(inst, "onChangeMonthYear");
9882          if (onChange) {
9883              onChange.apply((inst.input ? inst.input[0] : null),
9884                  [inst.selectedYear, inst.selectedMonth + 1, inst]);
9885          }
9886      },
9887  
9888      /* Determine the number of months to show. */
9889      _getNumberOfMonths: function(inst) {
9890          var numMonths = this._get(inst, "numberOfMonths");
9891          return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9892      },
9893  
9894      /* Determine the current maximum date - ensure no time components are set. */
9895      _getMinMaxDate: function(inst, minMax) {
9896          return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9897      },
9898  
9899      /* Find the number of days in a given month. */
9900      _getDaysInMonth: function(year, month) {
9901          return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9902      },
9903  
9904      /* Find the day of the week of the first of a month. */
9905      _getFirstDayOfMonth: function(year, month) {
9906          return new Date(year, month, 1).getDay();
9907      },
9908  
9909      /* Determines if we should allow a "next/prev" month display change. */
9910      _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9911          var numMonths = this._getNumberOfMonths(inst),
9912              date = this._daylightSavingAdjust(new Date(curYear,
9913              curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9914  
9915          if (offset < 0) {
9916              date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9917          }
9918          return this._isInRange(inst, date);
9919      },
9920  
9921      /* Is the given date in the accepted range? */
9922      _isInRange: function(inst, date) {
9923          var yearSplit, currentYear,
9924              minDate = this._getMinMaxDate(inst, "min"),
9925              maxDate = this._getMinMaxDate(inst, "max"),
9926              minYear = null,
9927              maxYear = null,
9928              years = this._get(inst, "yearRange");
9929              if (years){
9930                  yearSplit = years.split(":");
9931                  currentYear = new Date().getFullYear();
9932                  minYear = parseInt(yearSplit[0], 10);
9933                  maxYear = parseInt(yearSplit[1], 10);
9934                  if ( yearSplit[0].match(/[+\-].*/) ) {
9935                      minYear += currentYear;
9936                  }
9937                  if ( yearSplit[1].match(/[+\-].*/) ) {
9938                      maxYear += currentYear;
9939                  }
9940              }
9941  
9942          return ((!minDate || date.getTime() >= minDate.getTime()) &&
9943              (!maxDate || date.getTime() <= maxDate.getTime()) &&
9944              (!minYear || date.getFullYear() >= minYear) &&
9945              (!maxYear || date.getFullYear() <= maxYear));
9946      },
9947  
9948      /* Provide the configuration settings for formatting/parsing. */
9949      _getFormatConfig: function(inst) {
9950          var shortYearCutoff = this._get(inst, "shortYearCutoff");
9951          shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9952              new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9953          return {shortYearCutoff: shortYearCutoff,
9954              dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9955              monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9956      },
9957  
9958      /* Format the given date for display. */
9959      _formatDate: function(inst, day, month, year) {
9960          if (!day) {
9961              inst.currentDay = inst.selectedDay;
9962              inst.currentMonth = inst.selectedMonth;
9963              inst.currentYear = inst.selectedYear;
9964          }
9965          var date = (day ? (typeof day === "object" ? day :
9966              this._daylightSavingAdjust(new Date(year, month, day))) :
9967              this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9968          return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9969      }
9970  });
9971  
9972  /*
9973   * Bind hover events for datepicker elements.
9974   * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9975   * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9976   */
9977  function datepicker_bindHover(dpDiv) {
9978      var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9979      return dpDiv.delegate(selector, "mouseout", function() {
9980              $(this).removeClass("ui-state-hover");
9981              if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9982                  $(this).removeClass("ui-datepicker-prev-hover");
9983              }
9984              if (this.className.indexOf("ui-datepicker-next") !== -1) {
9985                  $(this).removeClass("ui-datepicker-next-hover");
9986              }
9987          })
9988          .delegate( selector, "mouseover", datepicker_handleMouseover );
9989  }
9990  
9991  function datepicker_handleMouseover() {
9992      if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
9993          $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9994          $(this).addClass("ui-state-hover");
9995          if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9996              $(this).addClass("ui-datepicker-prev-hover");
9997          }
9998          if (this.className.indexOf("ui-datepicker-next") !== -1) {
9999              $(this).addClass("ui-datepicker-next-hover");
10000          }
10001      }
10002  }
10003  
10004  /* jQuery extend now ignores nulls! */
10005  function datepicker_extendRemove(target, props) {
10006      $.extend(target, props);
10007      for (var name in props) {
10008          if (props[name] == null) {
10009              target[name] = props[name];
10010          }
10011      }
10012      return target;
10013  }
10014  
10015  /* Invoke the datepicker functionality.
10016     @param  options  string - a command, optionally followed by additional parameters or
10017                      Object - settings for attaching new datepicker functionality
10018     @return  jQuery object */
10019  $.fn.datepicker = function(options){
10020  
10021      /* Verify an empty collection wasn't passed - Fixes #6976 */
10022      if ( !this.length ) {
10023          return this;
10024      }
10025  
10026      /* Initialise the date picker. */
10027      if (!$.datepicker.initialized) {
10028          $(document).mousedown($.datepicker._checkExternalClick);
10029          $.datepicker.initialized = true;
10030      }
10031  
10032      /* Append datepicker main container to body if not exist. */
10033      if ($("#"+$.datepicker._mainDivId).length === 0) {
10034          $("body").append($.datepicker.dpDiv);
10035      }
10036  
10037      var otherArgs = Array.prototype.slice.call(arguments, 1);
10038      if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
10039          return $.datepicker["_" + options + "Datepicker"].
10040              apply($.datepicker, [this[0]].concat(otherArgs));
10041      }
10042      if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
10043          return $.datepicker["_" + options + "Datepicker"].
10044              apply($.datepicker, [this[0]].concat(otherArgs));
10045      }
10046      return this.each(function() {
10047          typeof options === "string" ?
10048              $.datepicker["_" + options + "Datepicker"].
10049                  apply($.datepicker, [this].concat(otherArgs)) :
10050              $.datepicker._attachDatepicker(this, options);
10051      });
10052  };
10053  
10054  $.datepicker = new Datepicker(); // singleton instance
10055  $.datepicker.initialized = false;
10056  $.datepicker.uuid = new Date().getTime();
10057  $.datepicker.version = "1.11.4";
10058  
10059  var datepicker = $.datepicker;
10060  
10061  
10062  /*!
10063   * jQuery UI Dialog 1.11.4
10064   * http://jqueryui.com
10065   *
10066   * Copyright jQuery Foundation and other contributors
10067   * Released under the MIT license.
10068   * http://jquery.org/license
10069   *
10070   * http://api.jqueryui.com/dialog/
10071   */
10072  
10073  
10074  var dialog = $.widget( "ui.dialog", {
10075      version: "1.11.4",
10076      options: {
10077          appendTo: "body",
10078          autoOpen: true,
10079          buttons: [],
10080          closeOnEscape: true,
10081          closeText: "Close",
10082          dialogClass: "",
10083          draggable: true,
10084          hide: null,
10085          height: "auto",
10086          maxHeight: null,
10087          maxWidth: null,
10088          minHeight: 150,
10089          minWidth: 150,
10090          modal: false,
10091          position: {
10092              my: "center",
10093              at: "center",
10094              of: window,
10095              collision: "fit",
10096              // Ensure the titlebar is always visible
10097              using: function( pos ) {
10098                  var topOffset = $( this ).css( pos ).offset().top;
10099                  if ( topOffset < 0 ) {
10100                      $( this ).css( "top", pos.top - topOffset );
10101                  }
10102              }
10103          },
10104          resizable: true,
10105          show: null,
10106          title: null,
10107          width: 300,
10108  
10109          // callbacks
10110          beforeClose: null,
10111          close: null,
10112          drag: null,
10113          dragStart: null,
10114          dragStop: null,
10115          focus: null,
10116          open: null,
10117          resize: null,
10118          resizeStart: null,
10119          resizeStop: null
10120      },
10121  
10122      sizeRelatedOptions: {
10123          buttons: true,
10124          height: true,
10125          maxHeight: true,
10126          maxWidth: true,
10127          minHeight: true,
10128          minWidth: true,
10129          width: true
10130      },
10131  
10132      resizableRelatedOptions: {
10133          maxHeight: true,
10134          maxWidth: true,
10135          minHeight: true,
10136          minWidth: true
10137      },
10138  
10139      _create: function() {
10140          this.originalCss = {
10141              display: this.element[ 0 ].style.display,
10142              width: this.element[ 0 ].style.width,
10143              minHeight: this.element[ 0 ].style.minHeight,
10144              maxHeight: this.element[ 0 ].style.maxHeight,
10145              height: this.element[ 0 ].style.height
10146          };
10147          this.originalPosition = {
10148              parent: this.element.parent(),
10149              index: this.element.parent().children().index( this.element )
10150          };
10151          this.originalTitle = this.element.attr( "title" );
10152          this.options.title = this.options.title || this.originalTitle;
10153  
10154          this._createWrapper();
10155  
10156          this.element
10157              .show()
10158              .removeAttr( "title" )
10159              .addClass( "ui-dialog-content ui-widget-content" )
10160              .appendTo( this.uiDialog );
10161  
10162          this._createTitlebar();
10163          this._createButtonPane();
10164  
10165          if ( this.options.draggable && $.fn.draggable ) {
10166              this._makeDraggable();
10167          }
10168          if ( this.options.resizable && $.fn.resizable ) {
10169              this._makeResizable();
10170          }
10171  
10172          this._isOpen = false;
10173  
10174          this._trackFocus();
10175      },
10176  
10177      _init: function() {
10178          if ( this.options.autoOpen ) {
10179              this.open();
10180          }
10181      },
10182  
10183      _appendTo: function() {
10184          var element = this.options.appendTo;
10185          if ( element && (element.jquery || element.nodeType) ) {
10186              return $( element );
10187          }
10188          return this.document.find( element || "body" ).eq( 0 );
10189      },
10190  
10191      _destroy: function() {
10192          var next,
10193              originalPosition = this.originalPosition;
10194  
10195          this._untrackInstance();
10196          this._destroyOverlay();
10197  
10198          this.element
10199              .removeUniqueId()
10200              .removeClass( "ui-dialog-content ui-widget-content" )
10201              .css( this.originalCss )
10202              // Without detaching first, the following becomes really slow
10203              .detach();
10204  
10205          this.uiDialog.stop( true, true ).remove();
10206  
10207          if ( this.originalTitle ) {
10208              this.element.attr( "title", this.originalTitle );
10209          }
10210  
10211          next = originalPosition.parent.children().eq( originalPosition.index );
10212          // Don't try to place the dialog next to itself (#8613)
10213          if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
10214              next.before( this.element );
10215          } else {
10216              originalPosition.parent.append( this.element );
10217          }
10218      },
10219  
10220      widget: function() {
10221          return this.uiDialog;
10222      },
10223  
10224      disable: $.noop,
10225      enable: $.noop,
10226  
10227      close: function( event ) {
10228          var activeElement,
10229              that = this;
10230  
10231          if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
10232              return;
10233          }
10234  
10235          this._isOpen = false;
10236          this._focusedElement = null;
10237          this._destroyOverlay();
10238          this._untrackInstance();
10239  
10240          if ( !this.opener.filter( ":focusable" ).focus().length ) {
10241  
10242              // support: IE9
10243              // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
10244              try {
10245                  activeElement = this.document[ 0 ].activeElement;
10246  
10247                  // Support: IE9, IE10
10248                  // If the <body> is blurred, IE will switch windows, see #4520
10249                  if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
10250  
10251                      // Hiding a focused element doesn't trigger blur in WebKit
10252                      // so in case we have nothing to focus on, explicitly blur the active element
10253                      // https://bugs.webkit.org/show_bug.cgi?id=47182
10254                      $( activeElement ).blur();
10255                  }
10256              } catch ( error ) {}
10257          }
10258  
10259          this._hide( this.uiDialog, this.options.hide, function() {
10260              that._trigger( "close", event );
10261          });
10262      },
10263  
10264      isOpen: function() {
10265          return this._isOpen;
10266      },
10267  
10268      moveToTop: function() {
10269          this._moveToTop();
10270      },
10271  
10272      _moveToTop: function( event, silent ) {
10273          var moved = false,
10274              zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
10275                  return +$( this ).css( "z-index" );
10276              }).get(),
10277              zIndexMax = Math.max.apply( null, zIndices );
10278  
10279          if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
10280              this.uiDialog.css( "z-index", zIndexMax + 1 );
10281              moved = true;
10282          }
10283  
10284          if ( moved && !silent ) {
10285              this._trigger( "focus", event );
10286          }
10287          return moved;
10288      },
10289  
10290      open: function() {
10291          var that = this;
10292          if ( this._isOpen ) {
10293              if ( this._moveToTop() ) {
10294                  this._focusTabbable();
10295              }
10296              return;
10297          }
10298  
10299          this._isOpen = true;
10300          this.opener = $( this.document[ 0 ].activeElement );
10301  
10302          this._size();
10303          this._position();
10304          this._createOverlay();
10305          this._moveToTop( null, true );
10306  
10307          // Ensure the overlay is moved to the top with the dialog, but only when
10308          // opening. The overlay shouldn't move after the dialog is open so that
10309          // modeless dialogs opened after the modal dialog stack properly.
10310          if ( this.overlay ) {
10311              this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
10312          }
10313  
10314          this._show( this.uiDialog, this.options.show, function() {
10315              that._focusTabbable();
10316              that._trigger( "focus" );
10317          });
10318  
10319          // Track the dialog immediately upon openening in case a focus event
10320          // somehow occurs outside of the dialog before an element inside the
10321          // dialog is focused (#10152)
10322          this._makeFocusTarget();
10323  
10324          this._trigger( "open" );
10325      },
10326  
10327      _focusTabbable: function() {
10328          // Set focus to the first match:
10329          // 1. An element that was focused previously
10330          // 2. First element inside the dialog matching [autofocus]
10331          // 3. Tabbable element inside the content element
10332          // 4. Tabbable element inside the buttonpane
10333          // 5. The close button
10334          // 6. The dialog itself
10335          var hasFocus = this._focusedElement;
10336          if ( !hasFocus ) {
10337              hasFocus = this.element.find( "[autofocus]" );
10338          }
10339          if ( !hasFocus.length ) {
10340              hasFocus = this.element.find( ":tabbable" );
10341          }
10342          if ( !hasFocus.length ) {
10343              hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
10344          }
10345          if ( !hasFocus.length ) {
10346              hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
10347          }
10348          if ( !hasFocus.length ) {
10349              hasFocus = this.uiDialog;
10350          }
10351          hasFocus.eq( 0 ).focus();
10352      },
10353  
10354      _keepFocus: function( event ) {
10355  		function checkFocus() {
10356              var activeElement = this.document[0].activeElement,
10357                  isActive = this.uiDialog[0] === activeElement ||
10358                      $.contains( this.uiDialog[0], activeElement );
10359              if ( !isActive ) {
10360                  this._focusTabbable();
10361              }
10362          }
10363          event.preventDefault();
10364          checkFocus.call( this );
10365          // support: IE
10366          // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
10367          // so we check again later
10368          this._delay( checkFocus );
10369      },
10370  
10371      _createWrapper: function() {
10372          this.uiDialog = $("<div>")
10373              .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
10374                  this.options.dialogClass )
10375              .hide()
10376              .attr({
10377                  // Setting tabIndex makes the div focusable
10378                  tabIndex: -1,
10379                  role: "dialog"
10380              })
10381              .appendTo( this._appendTo() );
10382  
10383          this._on( this.uiDialog, {
10384              keydown: function( event ) {
10385                  if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
10386                          event.keyCode === $.ui.keyCode.ESCAPE ) {
10387                      event.preventDefault();
10388                      this.close( event );
10389                      return;
10390                  }
10391  
10392                  // prevent tabbing out of dialogs
10393                  if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
10394                      return;
10395                  }
10396                  var tabbables = this.uiDialog.find( ":tabbable" ),
10397                      first = tabbables.filter( ":first" ),
10398                      last = tabbables.filter( ":last" );
10399  
10400                  if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
10401                      this._delay(function() {
10402                          first.focus();
10403                      });
10404                      event.preventDefault();
10405                  } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
10406                      this._delay(function() {
10407                          last.focus();
10408                      });
10409                      event.preventDefault();
10410                  }
10411              },
10412              mousedown: function( event ) {
10413                  if ( this._moveToTop( event ) ) {
10414                      this._focusTabbable();
10415                  }
10416              }
10417          });
10418  
10419          // We assume that any existing aria-describedby attribute means
10420          // that the dialog content is marked up properly
10421          // otherwise we brute force the content as the description
10422          if ( !this.element.find( "[aria-describedby]" ).length ) {
10423              this.uiDialog.attr({
10424                  "aria-describedby": this.element.uniqueId().attr( "id" )
10425              });
10426          }
10427      },
10428  
10429      _createTitlebar: function() {
10430          var uiDialogTitle;
10431  
10432          this.uiDialogTitlebar = $( "<div>" )
10433              .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
10434              .prependTo( this.uiDialog );
10435          this._on( this.uiDialogTitlebar, {
10436              mousedown: function( event ) {
10437                  // Don't prevent click on close button (#8838)
10438                  // Focusing a dialog that is partially scrolled out of view
10439                  // causes the browser to scroll it into view, preventing the click event
10440                  if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
10441                      // Dialog isn't getting focus when dragging (#8063)
10442                      this.uiDialog.focus();
10443                  }
10444              }
10445          });
10446  
10447          // support: IE
10448          // Use type="button" to prevent enter keypresses in textboxes from closing the
10449          // dialog in IE (#9312)
10450          this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
10451              .button({
10452                  label: this.options.closeText,
10453                  icons: {
10454                      primary: "ui-icon-closethick"
10455                  },
10456                  text: false
10457              })
10458              .addClass( "ui-dialog-titlebar-close" )
10459              .appendTo( this.uiDialogTitlebar );
10460          this._on( this.uiDialogTitlebarClose, {
10461              click: function( event ) {
10462                  event.preventDefault();
10463                  this.close( event );
10464              }
10465          });
10466  
10467          uiDialogTitle = $( "<span>" )
10468              .uniqueId()
10469              .addClass( "ui-dialog-title" )
10470              .prependTo( this.uiDialogTitlebar );
10471          this._title( uiDialogTitle );
10472  
10473          this.uiDialog.attr({
10474              "aria-labelledby": uiDialogTitle.attr( "id" )
10475          });
10476      },
10477  
10478      _title: function( title ) {
10479          if ( !this.options.title ) {
10480              title.html( "&#160;" );
10481          }
10482          title.text( this.options.title );
10483      },
10484  
10485      _createButtonPane: function() {
10486          this.uiDialogButtonPane = $( "<div>" )
10487              .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
10488  
10489          this.uiButtonSet = $( "<div>" )
10490              .addClass( "ui-dialog-buttonset" )
10491              .appendTo( this.uiDialogButtonPane );
10492  
10493          this._createButtons();
10494      },
10495  
10496      _createButtons: function() {
10497          var that = this,
10498              buttons = this.options.buttons;
10499  
10500          // if we already have a button pane, remove it
10501          this.uiDialogButtonPane.remove();
10502          this.uiButtonSet.empty();
10503  
10504          if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10505              this.uiDialog.removeClass( "ui-dialog-buttons" );
10506              return;
10507          }
10508  
10509          $.each( buttons, function( name, props ) {
10510              var click, buttonOptions;
10511              props = $.isFunction( props ) ?
10512                  { click: props, text: name } :
10513                  props;
10514              // Default to a non-submitting button
10515              props = $.extend( { type: "button" }, props );
10516              // Change the context for the click callback to be the main element
10517              click = props.click;
10518              props.click = function() {
10519                  click.apply( that.element[ 0 ], arguments );
10520              };
10521              buttonOptions = {
10522                  icons: props.icons,
10523                  text: props.showText
10524              };
10525              delete props.icons;
10526              delete props.showText;
10527              $( "<button></button>", props )
10528                  .button( buttonOptions )
10529                  .appendTo( that.uiButtonSet );
10530          });
10531          this.uiDialog.addClass( "ui-dialog-buttons" );
10532          this.uiDialogButtonPane.appendTo( this.uiDialog );
10533      },
10534  
10535      _makeDraggable: function() {
10536          var that = this,
10537              options = this.options;
10538  
10539  		function filteredUi( ui ) {
10540              return {
10541                  position: ui.position,
10542                  offset: ui.offset
10543              };
10544          }
10545  
10546          this.uiDialog.draggable({
10547              cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10548              handle: ".ui-dialog-titlebar",
10549              containment: "document",
10550              start: function( event, ui ) {
10551                  $( this ).addClass( "ui-dialog-dragging" );
10552                  that._blockFrames();
10553                  that._trigger( "dragStart", event, filteredUi( ui ) );
10554              },
10555              drag: function( event, ui ) {
10556                  that._trigger( "drag", event, filteredUi( ui ) );
10557              },
10558              stop: function( event, ui ) {
10559                  var left = ui.offset.left - that.document.scrollLeft(),
10560                      top = ui.offset.top - that.document.scrollTop();
10561  
10562                  options.position = {
10563                      my: "left top",
10564                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
10565                          "top" + (top >= 0 ? "+" : "") + top,
10566                      of: that.window
10567                  };
10568                  $( this ).removeClass( "ui-dialog-dragging" );
10569                  that._unblockFrames();
10570                  that._trigger( "dragStop", event, filteredUi( ui ) );
10571              }
10572          });
10573      },
10574  
10575      _makeResizable: function() {
10576          var that = this,
10577              options = this.options,
10578              handles = options.resizable,
10579              // .ui-resizable has position: relative defined in the stylesheet
10580              // but dialogs have to use absolute or fixed positioning
10581              position = this.uiDialog.css("position"),
10582              resizeHandles = typeof handles === "string" ?
10583                  handles    :
10584                  "n,e,s,w,se,sw,ne,nw";
10585  
10586  		function filteredUi( ui ) {
10587              return {
10588                  originalPosition: ui.originalPosition,
10589                  originalSize: ui.originalSize,
10590                  position: ui.position,
10591                  size: ui.size
10592              };
10593          }
10594  
10595          this.uiDialog.resizable({
10596              cancel: ".ui-dialog-content",
10597              containment: "document",
10598              alsoResize: this.element,
10599              maxWidth: options.maxWidth,
10600              maxHeight: options.maxHeight,
10601              minWidth: options.minWidth,
10602              minHeight: this._minHeight(),
10603              handles: resizeHandles,
10604              start: function( event, ui ) {
10605                  $( this ).addClass( "ui-dialog-resizing" );
10606                  that._blockFrames();
10607                  that._trigger( "resizeStart", event, filteredUi( ui ) );
10608              },
10609              resize: function( event, ui ) {
10610                  that._trigger( "resize", event, filteredUi( ui ) );
10611              },
10612              stop: function( event, ui ) {
10613                  var offset = that.uiDialog.offset(),
10614                      left = offset.left - that.document.scrollLeft(),
10615                      top = offset.top - that.document.scrollTop();
10616  
10617                  options.height = that.uiDialog.height();
10618                  options.width = that.uiDialog.width();
10619                  options.position = {
10620                      my: "left top",
10621                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
10622                          "top" + (top >= 0 ? "+" : "") + top,
10623                      of: that.window
10624                  };
10625                  $( this ).removeClass( "ui-dialog-resizing" );
10626                  that._unblockFrames();
10627                  that._trigger( "resizeStop", event, filteredUi( ui ) );
10628              }
10629          })
10630          .css( "position", position );
10631      },
10632  
10633      _trackFocus: function() {
10634          this._on( this.widget(), {
10635              focusin: function( event ) {
10636                  this._makeFocusTarget();
10637                  this._focusedElement = $( event.target );
10638              }
10639          });
10640      },
10641  
10642      _makeFocusTarget: function() {
10643          this._untrackInstance();
10644          this._trackingInstances().unshift( this );
10645      },
10646  
10647      _untrackInstance: function() {
10648          var instances = this._trackingInstances(),
10649              exists = $.inArray( this, instances );
10650          if ( exists !== -1 ) {
10651              instances.splice( exists, 1 );
10652          }
10653      },
10654  
10655      _trackingInstances: function() {
10656          var instances = this.document.data( "ui-dialog-instances" );
10657          if ( !instances ) {
10658              instances = [];
10659              this.document.data( "ui-dialog-instances", instances );
10660          }
10661          return instances;
10662      },
10663  
10664      _minHeight: function() {
10665          var options = this.options;
10666  
10667          return options.height === "auto" ?
10668              options.minHeight :
10669              Math.min( options.minHeight, options.height );
10670      },
10671  
10672      _position: function() {
10673          // Need to show the dialog to get the actual offset in the position plugin
10674          var isVisible = this.uiDialog.is( ":visible" );
10675          if ( !isVisible ) {
10676              this.uiDialog.show();
10677          }
10678          this.uiDialog.position( this.options.position );
10679          if ( !isVisible ) {
10680              this.uiDialog.hide();
10681          }
10682      },
10683  
10684      _setOptions: function( options ) {
10685          var that = this,
10686              resize = false,
10687              resizableOptions = {};
10688  
10689          $.each( options, function( key, value ) {
10690              that._setOption( key, value );
10691  
10692              if ( key in that.sizeRelatedOptions ) {
10693                  resize = true;
10694              }
10695              if ( key in that.resizableRelatedOptions ) {
10696                  resizableOptions[ key ] = value;
10697              }
10698          });
10699  
10700          if ( resize ) {
10701              this._size();
10702              this._position();
10703          }
10704          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10705              this.uiDialog.resizable( "option", resizableOptions );
10706          }
10707      },
10708  
10709      _setOption: function( key, value ) {
10710          var isDraggable, isResizable,
10711              uiDialog = this.uiDialog;
10712  
10713          if ( key === "dialogClass" ) {
10714              uiDialog
10715                  .removeClass( this.options.dialogClass )
10716                  .addClass( value );
10717          }
10718  
10719          if ( key === "disabled" ) {
10720              return;
10721          }
10722  
10723          this._super( key, value );
10724  
10725          if ( key === "appendTo" ) {
10726              this.uiDialog.appendTo( this._appendTo() );
10727          }
10728  
10729          if ( key === "buttons" ) {
10730              this._createButtons();
10731          }
10732  
10733          if ( key === "closeText" ) {
10734              this.uiDialogTitlebarClose.button({
10735                  // Ensure that we always pass a string
10736                  label: "" + value
10737              });
10738          }
10739  
10740          if ( key === "draggable" ) {
10741              isDraggable = uiDialog.is( ":data(ui-draggable)" );
10742              if ( isDraggable && !value ) {
10743                  uiDialog.draggable( "destroy" );
10744              }
10745  
10746              if ( !isDraggable && value ) {
10747                  this._makeDraggable();
10748              }
10749          }
10750  
10751          if ( key === "position" ) {
10752              this._position();
10753          }
10754  
10755          if ( key === "resizable" ) {
10756              // currently resizable, becoming non-resizable
10757              isResizable = uiDialog.is( ":data(ui-resizable)" );
10758              if ( isResizable && !value ) {
10759                  uiDialog.resizable( "destroy" );
10760              }
10761  
10762              // currently resizable, changing handles
10763              if ( isResizable && typeof value === "string" ) {
10764                  uiDialog.resizable( "option", "handles", value );
10765              }
10766  
10767              // currently non-resizable, becoming resizable
10768              if ( !isResizable && value !== false ) {
10769                  this._makeResizable();
10770              }
10771          }
10772  
10773          if ( key === "title" ) {
10774              this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
10775          }
10776      },
10777  
10778      _size: function() {
10779          // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10780          // divs will both have width and height set, so we need to reset them
10781          var nonContentHeight, minContentHeight, maxContentHeight,
10782              options = this.options;
10783  
10784          // Reset content sizing
10785          this.element.show().css({
10786              width: "auto",
10787              minHeight: 0,
10788              maxHeight: "none",
10789              height: 0
10790          });
10791  
10792          if ( options.minWidth > options.width ) {
10793              options.width = options.minWidth;
10794          }
10795  
10796          // reset wrapper sizing
10797          // determine the height of all the non-content elements
10798          nonContentHeight = this.uiDialog.css({
10799                  height: "auto",
10800                  width: options.width
10801              })
10802              .outerHeight();
10803          minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10804          maxContentHeight = typeof options.maxHeight === "number" ?
10805              Math.max( 0, options.maxHeight - nonContentHeight ) :
10806              "none";
10807  
10808          if ( options.height === "auto" ) {
10809              this.element.css({
10810                  minHeight: minContentHeight,
10811                  maxHeight: maxContentHeight,
10812                  height: "auto"
10813              });
10814          } else {
10815              this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10816          }
10817  
10818          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
10819              this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10820          }
10821      },
10822  
10823      _blockFrames: function() {
10824          this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10825              var iframe = $( this );
10826  
10827              return $( "<div>" )
10828                  .css({
10829                      position: "absolute",
10830                      width: iframe.outerWidth(),
10831                      height: iframe.outerHeight()
10832                  })
10833                  .appendTo( iframe.parent() )
10834                  .offset( iframe.offset() )[0];
10835          });
10836      },
10837  
10838      _unblockFrames: function() {
10839          if ( this.iframeBlocks ) {
10840              this.iframeBlocks.remove();
10841              delete this.iframeBlocks;
10842          }
10843      },
10844  
10845      _allowInteraction: function( event ) {
10846          if ( $( event.target ).closest( ".ui-dialog" ).length ) {
10847              return true;
10848          }
10849  
10850          // TODO: Remove hack when datepicker implements
10851          // the .ui-front logic (#8989)
10852          return !!$( event.target ).closest( ".ui-datepicker" ).length;
10853      },
10854  
10855      _createOverlay: function() {
10856          if ( !this.options.modal ) {
10857              return;
10858          }
10859  
10860          // We use a delay in case the overlay is created from an
10861          // event that we're going to be cancelling (#2804)
10862          var isOpening = true;
10863          this._delay(function() {
10864              isOpening = false;
10865          });
10866  
10867          if ( !this.document.data( "ui-dialog-overlays" ) ) {
10868  
10869              // Prevent use of anchors and inputs
10870              // Using _on() for an event handler shared across many instances is
10871              // safe because the dialogs stack and must be closed in reverse order
10872              this._on( this.document, {
10873                  focusin: function( event ) {
10874                      if ( isOpening ) {
10875                          return;
10876                      }
10877  
10878                      if ( !this._allowInteraction( event ) ) {
10879                          event.preventDefault();
10880                          this._trackingInstances()[ 0 ]._focusTabbable();
10881                      }
10882                  }
10883              });
10884          }
10885  
10886          this.overlay = $( "<div>" )
10887              .addClass( "ui-widget-overlay ui-front" )
10888              .appendTo( this._appendTo() );
10889          this._on( this.overlay, {
10890              mousedown: "_keepFocus"
10891          });
10892          this.document.data( "ui-dialog-overlays",
10893              (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
10894      },
10895  
10896      _destroyOverlay: function() {
10897          if ( !this.options.modal ) {
10898              return;
10899          }
10900  
10901          if ( this.overlay ) {
10902              var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
10903  
10904              if ( !overlays ) {
10905                  this.document
10906                      .unbind( "focusin" )
10907                      .removeData( "ui-dialog-overlays" );
10908              } else {
10909                  this.document.data( "ui-dialog-overlays", overlays );
10910              }
10911  
10912              this.overlay.remove();
10913              this.overlay = null;
10914          }
10915      }
10916  });
10917  
10918  
10919  /*!
10920   * jQuery UI Progressbar 1.11.4
10921   * http://jqueryui.com
10922   *
10923   * Copyright jQuery Foundation and other contributors
10924   * Released under the MIT license.
10925   * http://jquery.org/license
10926   *
10927   * http://api.jqueryui.com/progressbar/
10928   */
10929  
10930  
10931  var progressbar = $.widget( "ui.progressbar", {
10932      version: "1.11.4",
10933      options: {
10934          max: 100,
10935          value: 0,
10936  
10937          change: null,
10938          complete: null
10939      },
10940  
10941      min: 0,
10942  
10943      _create: function() {
10944          // Constrain initial value
10945          this.oldValue = this.options.value = this._constrainedValue();
10946  
10947          this.element
10948              .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10949              .attr({
10950                  // Only set static values, aria-valuenow and aria-valuemax are
10951                  // set inside _refreshValue()
10952                  role: "progressbar",
10953                  "aria-valuemin": this.min
10954              });
10955  
10956          this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10957              .appendTo( this.element );
10958  
10959          this._refreshValue();
10960      },
10961  
10962      _destroy: function() {
10963          this.element
10964              .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10965              .removeAttr( "role" )
10966              .removeAttr( "aria-valuemin" )
10967              .removeAttr( "aria-valuemax" )
10968              .removeAttr( "aria-valuenow" );
10969  
10970          this.valueDiv.remove();
10971      },
10972  
10973      value: function( newValue ) {
10974          if ( newValue === undefined ) {
10975              return this.options.value;
10976          }
10977  
10978          this.options.value = this._constrainedValue( newValue );
10979          this._refreshValue();
10980      },
10981  
10982      _constrainedValue: function( newValue ) {
10983          if ( newValue === undefined ) {
10984              newValue = this.options.value;
10985          }
10986  
10987          this.indeterminate = newValue === false;
10988  
10989          // sanitize value
10990          if ( typeof newValue !== "number" ) {
10991              newValue = 0;
10992          }
10993  
10994          return this.indeterminate ? false :
10995              Math.min( this.options.max, Math.max( this.min, newValue ) );
10996      },
10997  
10998      _setOptions: function( options ) {
10999          // Ensure "value" option is set after other values (like max)
11000          var value = options.value;
11001          delete options.value;
11002  
11003          this._super( options );
11004  
11005          this.options.value = this._constrainedValue( value );
11006          this._refreshValue();
11007      },
11008  
11009      _setOption: function( key, value ) {
11010          if ( key === "max" ) {
11011              // Don't allow a max less than min
11012              value = Math.max( this.min, value );
11013          }
11014          if ( key === "disabled" ) {
11015              this.element
11016                  .toggleClass( "ui-state-disabled", !!value )
11017                  .attr( "aria-disabled", value );
11018          }
11019          this._super( key, value );
11020      },
11021  
11022      _percentage: function() {
11023          return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11024      },
11025  
11026      _refreshValue: function() {
11027          var value = this.options.value,
11028              percentage = this._percentage();
11029  
11030          this.valueDiv
11031              .toggle( this.indeterminate || value > this.min )
11032              .toggleClass( "ui-corner-right", value === this.options.max )
11033              .width( percentage.toFixed(0) + "%" );
11034  
11035          this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11036  
11037          if ( this.indeterminate ) {
11038              this.element.removeAttr( "aria-valuenow" );
11039              if ( !this.overlayDiv ) {
11040                  this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11041              }
11042          } else {
11043              this.element.attr({
11044                  "aria-valuemax": this.options.max,
11045                  "aria-valuenow": value
11046              });
11047              if ( this.overlayDiv ) {
11048                  this.overlayDiv.remove();
11049                  this.overlayDiv = null;
11050              }
11051          }
11052  
11053          if ( this.oldValue !== value ) {
11054              this.oldValue = value;
11055              this._trigger( "change" );
11056          }
11057          if ( value === this.options.max ) {
11058              this._trigger( "complete" );
11059          }
11060      }
11061  });
11062  
11063  
11064  /*!
11065   * jQuery UI Selectmenu 1.11.4
11066   * http://jqueryui.com
11067   *
11068   * Copyright jQuery Foundation and other contributors
11069   * Released under the MIT license.
11070   * http://jquery.org/license
11071   *
11072   * http://api.jqueryui.com/selectmenu
11073   */
11074  
11075  
11076  var selectmenu = $.widget( "ui.selectmenu", {
11077      version: "1.11.4",
11078      defaultElement: "<select>",
11079      options: {
11080          appendTo: null,
11081          disabled: null,
11082          icons: {
11083              button: "ui-icon-triangle-1-s"
11084          },
11085          position: {
11086              my: "left top",
11087              at: "left bottom",
11088              collision: "none"
11089          },
11090          width: null,
11091  
11092          // callbacks
11093          change: null,
11094          close: null,
11095          focus: null,
11096          open: null,
11097          select: null
11098      },
11099  
11100      _create: function() {
11101          var selectmenuId = this.element.uniqueId().attr( "id" );
11102          this.ids = {
11103              element: selectmenuId,
11104              button: selectmenuId + "-button",
11105              menu: selectmenuId + "-menu"
11106          };
11107  
11108          this._drawButton();
11109          this._drawMenu();
11110  
11111          if ( this.options.disabled ) {
11112              this.disable();
11113          }
11114      },
11115  
11116      _drawButton: function() {
11117          var that = this;
11118  
11119          // Associate existing label with the new button
11120          this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
11121          this._on( this.label, {
11122              click: function( event ) {
11123                  this.button.focus();
11124                  event.preventDefault();
11125              }
11126          });
11127  
11128          // Hide original select element
11129          this.element.hide();
11130  
11131          // Create button
11132          this.button = $( "<span>", {
11133              "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
11134              tabindex: this.options.disabled ? -1 : 0,
11135              id: this.ids.button,
11136              role: "combobox",
11137              "aria-expanded": "false",
11138              "aria-autocomplete": "list",
11139              "aria-owns": this.ids.menu,
11140              "aria-haspopup": "true"
11141          })
11142              .insertAfter( this.element );
11143  
11144          $( "<span>", {
11145              "class": "ui-icon " + this.options.icons.button
11146          })
11147              .prependTo( this.button );
11148  
11149          this.buttonText = $( "<span>", {
11150              "class": "ui-selectmenu-text"
11151          })
11152              .appendTo( this.button );
11153  
11154          this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
11155          this._resizeButton();
11156  
11157          this._on( this.button, this._buttonEvents );
11158          this.button.one( "focusin", function() {
11159  
11160              // Delay rendering the menu items until the button receives focus.
11161              // The menu may have already been rendered via a programmatic open.
11162              if ( !that.menuItems ) {
11163                  that._refreshMenu();
11164              }
11165          });
11166          this._hoverable( this.button );
11167          this._focusable( this.button );
11168      },
11169  
11170      _drawMenu: function() {
11171          var that = this;
11172  
11173          // Create menu
11174          this.menu = $( "<ul>", {
11175              "aria-hidden": "true",
11176              "aria-labelledby": this.ids.button,
11177              id: this.ids.menu
11178          });
11179  
11180          // Wrap menu
11181          this.menuWrap = $( "<div>", {
11182              "class": "ui-selectmenu-menu ui-front"
11183          })
11184              .append( this.menu )
11185              .appendTo( this._appendTo() );
11186  
11187          // Initialize menu widget
11188          this.menuInstance = this.menu
11189              .menu({
11190                  role: "listbox",
11191                  select: function( event, ui ) {
11192                      event.preventDefault();
11193  
11194                      // support: IE8
11195                      // If the item was selected via a click, the text selection
11196                      // will be destroyed in IE
11197                      that._setSelection();
11198  
11199                      that._select( ui.item.data( "ui-selectmenu-item" ), event );
11200                  },
11201                  focus: function( event, ui ) {
11202                      var item = ui.item.data( "ui-selectmenu-item" );
11203  
11204                      // Prevent inital focus from firing and check if its a newly focused item
11205                      if ( that.focusIndex != null && item.index !== that.focusIndex ) {
11206                          that._trigger( "focus", event, { item: item } );
11207                          if ( !that.isOpen ) {
11208                              that._select( item, event );
11209                          }
11210                      }
11211                      that.focusIndex = item.index;
11212  
11213                      that.button.attr( "aria-activedescendant",
11214                          that.menuItems.eq( item.index ).attr( "id" ) );
11215                  }
11216              })
11217              .menu( "instance" );
11218  
11219          // Adjust menu styles to dropdown
11220          this.menu
11221              .addClass( "ui-corner-bottom" )
11222              .removeClass( "ui-corner-all" );
11223  
11224          // Don't close the menu on mouseleave
11225          this.menuInstance._off( this.menu, "mouseleave" );
11226  
11227          // Cancel the menu's collapseAll on document click
11228          this.menuInstance._closeOnDocumentClick = function() {
11229              return false;
11230          };
11231  
11232          // Selects often contain empty items, but never contain dividers
11233          this.menuInstance._isDivider = function() {
11234              return false;
11235          };
11236      },
11237  
11238      refresh: function() {
11239          this._refreshMenu();
11240          this._setText( this.buttonText, this._getSelectedItem().text() );
11241          if ( !this.options.width ) {
11242              this._resizeButton();
11243          }
11244      },
11245  
11246      _refreshMenu: function() {
11247          this.menu.empty();
11248  
11249          var item,
11250              options = this.element.find( "option" );
11251  
11252          if ( !options.length ) {
11253              return;
11254          }
11255  
11256          this._parseOptions( options );
11257          this._renderMenu( this.menu, this.items );
11258  
11259          this.menuInstance.refresh();
11260          this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
11261  
11262          item = this._getSelectedItem();
11263  
11264          // Update the menu to have the correct item focused
11265          this.menuInstance.focus( null, item );
11266          this._setAria( item.data( "ui-selectmenu-item" ) );
11267  
11268          // Set disabled state
11269          this._setOption( "disabled", this.element.prop( "disabled" ) );
11270      },
11271  
11272      open: function( event ) {
11273          if ( this.options.disabled ) {
11274              return;
11275          }
11276  
11277          // If this is the first time the menu is being opened, render the items
11278          if ( !this.menuItems ) {
11279              this._refreshMenu();
11280          } else {
11281  
11282              // Menu clears focus on close, reset focus to selected item
11283              this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
11284              this.menuInstance.focus( null, this._getSelectedItem() );
11285          }
11286  
11287          this.isOpen = true;
11288          this._toggleAttr();
11289          this._resizeMenu();
11290          this._position();
11291  
11292          this._on( this.document, this._documentClick );
11293  
11294          this._trigger( "open", event );
11295      },
11296  
11297      _position: function() {
11298          this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
11299      },
11300  
11301      close: function( event ) {
11302          if ( !this.isOpen ) {
11303              return;
11304          }
11305  
11306          this.isOpen = false;
11307          this._toggleAttr();
11308  
11309          this.range = null;
11310          this._off( this.document );
11311  
11312          this._trigger( "close", event );
11313      },
11314  
11315      widget: function() {
11316          return this.button;
11317      },
11318  
11319      menuWidget: function() {
11320          return this.menu;
11321      },
11322  
11323      _renderMenu: function( ul, items ) {
11324          var that = this,
11325              currentOptgroup = "";
11326  
11327          $.each( items, function( index, item ) {
11328              if ( item.optgroup !== currentOptgroup ) {
11329                  $( "<li>", {
11330                      "class": "ui-selectmenu-optgroup ui-menu-divider" +
11331                          ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
11332                              " ui-state-disabled" :
11333                              "" ),
11334                      text: item.optgroup
11335                  })
11336                      .appendTo( ul );
11337  
11338                  currentOptgroup = item.optgroup;
11339              }
11340  
11341              that._renderItemData( ul, item );
11342          });
11343      },
11344  
11345      _renderItemData: function( ul, item ) {
11346          return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
11347      },
11348  
11349      _renderItem: function( ul, item ) {
11350          var li = $( "<li>" );
11351  
11352          if ( item.disabled ) {
11353              li.addClass( "ui-state-disabled" );
11354          }
11355          this._setText( li, item.label );
11356  
11357          return li.appendTo( ul );
11358      },
11359  
11360      _setText: function( element, value ) {
11361          if ( value ) {
11362              element.text( value );
11363          } else {
11364              element.html( "&#160;" );
11365          }
11366      },
11367  
11368      _move: function( direction, event ) {
11369          var item, next,
11370              filter = ".ui-menu-item";
11371  
11372          if ( this.isOpen ) {
11373              item = this.menuItems.eq( this.focusIndex );
11374          } else {
11375              item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
11376              filter += ":not(.ui-state-disabled)";
11377          }
11378  
11379          if ( direction === "first" || direction === "last" ) {
11380              next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
11381          } else {
11382              next = item[ direction + "All" ]( filter ).eq( 0 );
11383          }
11384  
11385          if ( next.length ) {
11386              this.menuInstance.focus( event, next );
11387          }
11388      },
11389  
11390      _getSelectedItem: function() {
11391          return this.menuItems.eq( this.element[ 0 ].selectedIndex );
11392      },
11393  
11394      _toggle: function( event ) {
11395          this[ this.isOpen ? "close" : "open" ]( event );
11396      },
11397  
11398      _setSelection: function() {
11399          var selection;
11400  
11401          if ( !this.range ) {
11402              return;
11403          }
11404  
11405          if ( window.getSelection ) {
11406              selection = window.getSelection();
11407              selection.removeAllRanges();
11408              selection.addRange( this.range );
11409  
11410          // support: IE8
11411          } else {
11412              this.range.select();
11413          }
11414  
11415          // support: IE
11416          // Setting the text selection kills the button focus in IE, but
11417          // restoring the focus doesn't kill the selection.
11418          this.button.focus();
11419      },
11420  
11421      _documentClick: {
11422          mousedown: function( event ) {
11423              if ( !this.isOpen ) {
11424                  return;
11425              }
11426  
11427              if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
11428                  this.close( event );
11429              }
11430          }
11431      },
11432  
11433      _buttonEvents: {
11434  
11435          // Prevent text selection from being reset when interacting with the selectmenu (#10144)
11436          mousedown: function() {
11437              var selection;
11438  
11439              if ( window.getSelection ) {
11440                  selection = window.getSelection();
11441                  if ( selection.rangeCount ) {
11442                      this.range = selection.getRangeAt( 0 );
11443                  }
11444  
11445              // support: IE8
11446              } else {
11447                  this.range = document.selection.createRange();
11448              }
11449          },
11450  
11451          click: function( event ) {
11452              this._setSelection();
11453              this._toggle( event );
11454          },
11455  
11456          keydown: function( event ) {
11457              var preventDefault = true;
11458              switch ( event.keyCode ) {
11459                  case $.ui.keyCode.TAB:
11460                  case $.ui.keyCode.ESCAPE:
11461                      this.close( event );
11462                      preventDefault = false;
11463                      break;
11464                  case $.ui.keyCode.ENTER:
11465                      if ( this.isOpen ) {
11466                          this._selectFocusedItem( event );
11467                      }
11468                      break;
11469                  case $.ui.keyCode.UP:
11470                      if ( event.altKey ) {
11471                          this._toggle( event );
11472                      } else {
11473                          this._move( "prev", event );
11474                      }
11475                      break;
11476                  case $.ui.keyCode.DOWN:
11477                      if ( event.altKey ) {
11478                          this._toggle( event );
11479                      } else {
11480                          this._move( "next", event );
11481                      }
11482                      break;
11483                  case $.ui.keyCode.SPACE:
11484                      if ( this.isOpen ) {
11485                          this._selectFocusedItem( event );
11486                      } else {
11487                          this._toggle( event );
11488                      }
11489                      break;
11490                  case $.ui.keyCode.LEFT:
11491                      this._move( "prev", event );
11492                      break;
11493                  case $.ui.keyCode.RIGHT:
11494                      this._move( "next", event );
11495                      break;
11496                  case $.ui.keyCode.HOME:
11497                  case $.ui.keyCode.PAGE_UP:
11498                      this._move( "first", event );
11499                      break;
11500                  case $.ui.keyCode.END:
11501                  case $.ui.keyCode.PAGE_DOWN:
11502                      this._move( "last", event );
11503                      break;
11504                  default:
11505                      this.menu.trigger( event );
11506                      preventDefault = false;
11507              }
11508  
11509              if ( preventDefault ) {
11510                  event.preventDefault();
11511              }
11512          }
11513      },
11514  
11515      _selectFocusedItem: function( event ) {
11516          var item = this.menuItems.eq( this.focusIndex );
11517          if ( !item.hasClass( "ui-state-disabled" ) ) {
11518              this._select( item.data( "ui-selectmenu-item" ), event );
11519          }
11520      },
11521  
11522      _select: function( item, event ) {
11523          var oldIndex = this.element[ 0 ].selectedIndex;
11524  
11525          // Change native select element
11526          this.element[ 0 ].selectedIndex = item.index;
11527          this._setText( this.buttonText, item.label );
11528          this._setAria( item );
11529          this._trigger( "select", event, { item: item } );
11530  
11531          if ( item.index !== oldIndex ) {
11532              this._trigger( "change", event, { item: item } );
11533          }
11534  
11535          this.close( event );
11536      },
11537  
11538      _setAria: function( item ) {
11539          var id = this.menuItems.eq( item.index ).attr( "id" );
11540  
11541          this.button.attr({
11542              "aria-labelledby": id,
11543              "aria-activedescendant": id
11544          });
11545          this.menu.attr( "aria-activedescendant", id );
11546      },
11547  
11548      _setOption: function( key, value ) {
11549          if ( key === "icons" ) {
11550              this.button.find( "span.ui-icon" )
11551                  .removeClass( this.options.icons.button )
11552                  .addClass( value.button );
11553          }
11554  
11555          this._super( key, value );
11556  
11557          if ( key === "appendTo" ) {
11558              this.menuWrap.appendTo( this._appendTo() );
11559          }
11560  
11561          if ( key === "disabled" ) {
11562              this.menuInstance.option( "disabled", value );
11563              this.button
11564                  .toggleClass( "ui-state-disabled", value )
11565                  .attr( "aria-disabled", value );
11566  
11567              this.element.prop( "disabled", value );
11568              if ( value ) {
11569                  this.button.attr( "tabindex", -1 );
11570                  this.close();
11571              } else {
11572                  this.button.attr( "tabindex", 0 );
11573              }
11574          }
11575  
11576          if ( key === "width" ) {
11577              this._resizeButton();
11578          }
11579      },
11580  
11581      _appendTo: function() {
11582          var element = this.options.appendTo;
11583  
11584          if ( element ) {
11585              element = element.jquery || element.nodeType ?
11586                  $( element ) :
11587                  this.document.find( element ).eq( 0 );
11588          }
11589  
11590          if ( !element || !element[ 0 ] ) {
11591              element = this.element.closest( ".ui-front" );
11592          }
11593  
11594          if ( !element.length ) {
11595              element = this.document[ 0 ].body;
11596          }
11597  
11598          return element;
11599      },
11600  
11601      _toggleAttr: function() {
11602          this.button
11603              .toggleClass( "ui-corner-top", this.isOpen )
11604              .toggleClass( "ui-corner-all", !this.isOpen )
11605              .attr( "aria-expanded", this.isOpen );
11606          this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
11607          this.menu.attr( "aria-hidden", !this.isOpen );
11608      },
11609  
11610      _resizeButton: function() {
11611          var width = this.options.width;
11612  
11613          if ( !width ) {
11614              width = this.element.show().outerWidth();
11615              this.element.hide();
11616          }
11617  
11618          this.button.outerWidth( width );
11619      },
11620  
11621      _resizeMenu: function() {
11622          this.menu.outerWidth( Math.max(
11623              this.button.outerWidth(),
11624  
11625              // support: IE10
11626              // IE10 wraps long text (possibly a rounding bug)
11627              // so we add 1px to avoid the wrapping
11628              this.menu.width( "" ).outerWidth() + 1
11629          ) );
11630      },
11631  
11632      _getCreateOptions: function() {
11633          return { disabled: this.element.prop( "disabled" ) };
11634      },
11635  
11636      _parseOptions: function( options ) {
11637          var data = [];
11638          options.each(function( index, item ) {
11639              var option = $( item ),
11640                  optgroup = option.parent( "optgroup" );
11641              data.push({
11642                  element: option,
11643                  index: index,
11644                  value: option.val(),
11645                  label: option.text(),
11646                  optgroup: optgroup.attr( "label" ) || "",
11647                  disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
11648              });
11649          });
11650          this.items = data;
11651      },
11652  
11653      _destroy: function() {
11654          this.menuWrap.remove();
11655          this.button.remove();
11656          this.element.show();
11657          this.element.removeUniqueId();
11658          this.label.attr( "for", this.ids.element );
11659      }
11660  });
11661  
11662  
11663  /*!
11664   * jQuery UI Slider 1.11.4
11665   * http://jqueryui.com
11666   *
11667   * Copyright jQuery Foundation and other contributors
11668   * Released under the MIT license.
11669   * http://jquery.org/license
11670   *
11671   * http://api.jqueryui.com/slider/
11672   */
11673  
11674  
11675  var slider = $.widget( "ui.slider", $.ui.mouse, {
11676      version: "1.11.4",
11677      widgetEventPrefix: "slide",
11678  
11679      options: {
11680          animate: false,
11681          distance: 0,
11682          max: 100,
11683          min: 0,
11684          orientation: "horizontal",
11685          range: false,
11686          step: 1,
11687          value: 0,
11688          values: null,
11689  
11690          // callbacks
11691          change: null,
11692          slide: null,
11693          start: null,
11694          stop: null
11695      },
11696  
11697      // number of pages in a slider
11698      // (how many times can you page up/down to go through the whole range)
11699      numPages: 5,
11700  
11701      _create: function() {
11702          this._keySliding = false;
11703          this._mouseSliding = false;
11704          this._animateOff = true;
11705          this._handleIndex = null;
11706          this._detectOrientation();
11707          this._mouseInit();
11708          this._calculateNewMax();
11709  
11710          this.element
11711              .addClass( "ui-slider" +
11712                  " ui-slider-" + this.orientation +
11713                  " ui-widget" +
11714                  " ui-widget-content" +
11715                  " ui-corner-all");
11716  
11717          this._refresh();
11718          this._setOption( "disabled", this.options.disabled );
11719  
11720          this._animateOff = false;
11721      },
11722  
11723      _refresh: function() {
11724          this._createRange();
11725          this._createHandles();
11726          this._setupEvents();
11727          this._refreshValue();
11728      },
11729  
11730      _createHandles: function() {
11731          var i, handleCount,
11732              options = this.options,
11733              existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
11734              handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
11735              handles = [];
11736  
11737          handleCount = ( options.values && options.values.length ) || 1;
11738  
11739          if ( existingHandles.length > handleCount ) {
11740              existingHandles.slice( handleCount ).remove();
11741              existingHandles = existingHandles.slice( 0, handleCount );
11742          }
11743  
11744          for ( i = existingHandles.length; i < handleCount; i++ ) {
11745              handles.push( handle );
11746          }
11747  
11748          this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
11749  
11750          this.handle = this.handles.eq( 0 );
11751  
11752          this.handles.each(function( i ) {
11753              $( this ).data( "ui-slider-handle-index", i );
11754          });
11755      },
11756  
11757      _createRange: function() {
11758          var options = this.options,
11759              classes = "";
11760  
11761          if ( options.range ) {
11762              if ( options.range === true ) {
11763                  if ( !options.values ) {
11764                      options.values = [ this._valueMin(), this._valueMin() ];
11765                  } else if ( options.values.length && options.values.length !== 2 ) {
11766                      options.values = [ options.values[0], options.values[0] ];
11767                  } else if ( $.isArray( options.values ) ) {
11768                      options.values = options.values.slice(0);
11769                  }
11770              }
11771  
11772              if ( !this.range || !this.range.length ) {
11773                  this.range = $( "<div></div>" )
11774                      .appendTo( this.element );
11775  
11776                  classes = "ui-slider-range" +
11777                  // note: this isn't the most fittingly semantic framework class for this element,
11778                  // but worked best visually with a variety of themes
11779                  " ui-widget-header ui-corner-all";
11780              } else {
11781                  this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
11782                      // Handle range switching from true to min/max
11783                      .css({
11784                          "left": "",
11785                          "bottom": ""
11786                      });
11787              }
11788  
11789              this.range.addClass( classes +
11790                  ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
11791          } else {
11792              if ( this.range ) {
11793                  this.range.remove();
11794              }
11795              this.range = null;
11796          }
11797      },
11798  
11799      _setupEvents: function() {
11800          this._off( this.handles );
11801          this._on( this.handles, this._handleEvents );
11802          this._hoverable( this.handles );
11803          this._focusable( this.handles );
11804      },
11805  
11806      _destroy: function() {
11807          this.handles.remove();
11808          if ( this.range ) {
11809              this.range.remove();
11810          }
11811  
11812          this.element
11813              .removeClass( "ui-slider" +
11814                  " ui-slider-horizontal" +
11815                  " ui-slider-vertical" +
11816                  " ui-widget" +
11817                  " ui-widget-content" +
11818                  " ui-corner-all" );
11819  
11820          this._mouseDestroy();
11821      },
11822  
11823      _mouseCapture: function( event ) {
11824          var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
11825              that = this,
11826              o = this.options;
11827  
11828          if ( o.disabled ) {
11829              return false;
11830          }
11831  
11832          this.elementSize = {
11833              width: this.element.outerWidth(),
11834              height: this.element.outerHeight()
11835          };
11836          this.elementOffset = this.element.offset();
11837  
11838          position = { x: event.pageX, y: event.pageY };
11839          normValue = this._normValueFromMouse( position );
11840          distance = this._valueMax() - this._valueMin() + 1;
11841          this.handles.each(function( i ) {
11842              var thisDistance = Math.abs( normValue - that.values(i) );
11843              if (( distance > thisDistance ) ||
11844                  ( distance === thisDistance &&
11845                      (i === that._lastChangedValue || that.values(i) === o.min ))) {
11846                  distance = thisDistance;
11847                  closestHandle = $( this );
11848                  index = i;
11849              }
11850          });
11851  
11852          allowed = this._start( event, index );
11853          if ( allowed === false ) {
11854              return false;
11855          }
11856          this._mouseSliding = true;
11857  
11858          this._handleIndex = index;
11859  
11860          closestHandle
11861              .addClass( "ui-state-active" )
11862              .focus();
11863  
11864          offset = closestHandle.offset();
11865          mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
11866          this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
11867              left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
11868              top: event.pageY - offset.top -
11869                  ( closestHandle.height() / 2 ) -
11870                  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
11871                  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
11872                  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
11873          };
11874  
11875          if ( !this.handles.hasClass( "ui-state-hover" ) ) {
11876              this._slide( event, index, normValue );
11877          }
11878          this._animateOff = true;
11879          return true;
11880      },
11881  
11882      _mouseStart: function() {
11883          return true;
11884      },
11885  
11886      _mouseDrag: function( event ) {
11887          var position = { x: event.pageX, y: event.pageY },
11888              normValue = this._normValueFromMouse( position );
11889  
11890          this._slide( event, this._handleIndex, normValue );
11891  
11892          return false;
11893      },
11894  
11895      _mouseStop: function( event ) {
11896          this.handles.removeClass( "ui-state-active" );
11897          this._mouseSliding = false;
11898  
11899          this._stop( event, this._handleIndex );
11900          this._change( event, this._handleIndex );
11901  
11902          this._handleIndex = null;
11903          this._clickOffset = null;
11904          this._animateOff = false;
11905  
11906          return false;
11907      },
11908  
11909      _detectOrientation: function() {
11910          this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
11911      },
11912  
11913      _normValueFromMouse: function( position ) {
11914          var pixelTotal,
11915              pixelMouse,
11916              percentMouse,
11917              valueTotal,
11918              valueMouse;
11919  
11920          if ( this.orientation === "horizontal" ) {
11921              pixelTotal = this.elementSize.width;
11922              pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
11923          } else {
11924              pixelTotal = this.elementSize.height;
11925              pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
11926          }
11927  
11928          percentMouse = ( pixelMouse / pixelTotal );
11929          if ( percentMouse > 1 ) {
11930              percentMouse = 1;
11931          }
11932          if ( percentMouse < 0 ) {
11933              percentMouse = 0;
11934          }
11935          if ( this.orientation === "vertical" ) {
11936              percentMouse = 1 - percentMouse;
11937          }
11938  
11939          valueTotal = this._valueMax() - this._valueMin();
11940          valueMouse = this._valueMin() + percentMouse * valueTotal;
11941  
11942          return this._trimAlignValue( valueMouse );
11943      },
11944  
11945      _start: function( event, index ) {
11946          var uiHash = {
11947              handle: this.handles[ index ],
11948              value: this.value()
11949          };
11950          if ( this.options.values && this.options.values.length ) {
11951              uiHash.value = this.values( index );
11952              uiHash.values = this.values();
11953          }
11954          return this._trigger( "start", event, uiHash );
11955      },
11956  
11957      _slide: function( event, index, newVal ) {
11958          var otherVal,
11959              newValues,
11960              allowed;
11961  
11962          if ( this.options.values && this.options.values.length ) {
11963              otherVal = this.values( index ? 0 : 1 );
11964  
11965              if ( ( this.options.values.length === 2 && this.options.range === true ) &&
11966                      ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
11967                  ) {
11968                  newVal = otherVal;
11969              }
11970  
11971              if ( newVal !== this.values( index ) ) {
11972                  newValues = this.values();
11973                  newValues[ index ] = newVal;
11974                  // A slide can be canceled by returning false from the slide callback
11975                  allowed = this._trigger( "slide", event, {
11976                      handle: this.handles[ index ],
11977                      value: newVal,
11978                      values: newValues
11979                  } );
11980                  otherVal = this.values( index ? 0 : 1 );
11981                  if ( allowed !== false ) {
11982                      this.values( index, newVal );
11983                  }
11984              }
11985          } else {
11986              if ( newVal !== this.value() ) {
11987                  // A slide can be canceled by returning false from the slide callback
11988                  allowed = this._trigger( "slide", event, {
11989                      handle: this.handles[ index ],
11990                      value: newVal
11991                  } );
11992                  if ( allowed !== false ) {
11993                      this.value( newVal );
11994                  }
11995              }
11996          }
11997      },
11998  
11999      _stop: function( event, index ) {
12000          var uiHash = {
12001              handle: this.handles[ index ],
12002              value: this.value()
12003          };
12004          if ( this.options.values && this.options.values.length ) {
12005              uiHash.value = this.values( index );
12006              uiHash.values = this.values();
12007          }
12008  
12009          this._trigger( "stop", event, uiHash );
12010      },
12011  
12012      _change: function( event, index ) {
12013          if ( !this._keySliding && !this._mouseSliding ) {
12014              var uiHash = {
12015                  handle: this.handles[ index ],
12016                  value: this.value()
12017              };
12018              if ( this.options.values && this.options.values.length ) {
12019                  uiHash.value = this.values( index );
12020                  uiHash.values = this.values();
12021              }
12022  
12023              //store the last changed value index for reference when handles overlap
12024              this._lastChangedValue = index;
12025  
12026              this._trigger( "change", event, uiHash );
12027          }
12028      },
12029  
12030      value: function( newValue ) {
12031          if ( arguments.length ) {
12032              this.options.value = this._trimAlignValue( newValue );
12033              this._refreshValue();
12034              this._change( null, 0 );
12035              return;
12036          }
12037  
12038          return this._value();
12039      },
12040  
12041      values: function( index, newValue ) {
12042          var vals,
12043              newValues,
12044              i;
12045  
12046          if ( arguments.length > 1 ) {
12047              this.options.values[ index ] = this._trimAlignValue( newValue );
12048              this._refreshValue();
12049              this._change( null, index );
12050              return;
12051          }
12052  
12053          if ( arguments.length ) {
12054              if ( $.isArray( arguments[ 0 ] ) ) {
12055                  vals = this.options.values;
12056                  newValues = arguments[ 0 ];
12057                  for ( i = 0; i < vals.length; i += 1 ) {
12058                      vals[ i ] = this._trimAlignValue( newValues[ i ] );
12059                      this._change( null, i );
12060                  }
12061                  this._refreshValue();
12062              } else {
12063                  if ( this.options.values && this.options.values.length ) {
12064                      return this._values( index );
12065                  } else {
12066                      return this.value();
12067                  }
12068              }
12069          } else {
12070              return this._values();
12071          }
12072      },
12073  
12074      _setOption: function( key, value ) {
12075          var i,
12076              valsLength = 0;
12077  
12078          if ( key === "range" && this.options.range === true ) {
12079              if ( value === "min" ) {
12080                  this.options.value = this._values( 0 );
12081                  this.options.values = null;
12082              } else if ( value === "max" ) {
12083                  this.options.value = this._values( this.options.values.length - 1 );
12084                  this.options.values = null;
12085              }
12086          }
12087  
12088          if ( $.isArray( this.options.values ) ) {
12089              valsLength = this.options.values.length;
12090          }
12091  
12092          if ( key === "disabled" ) {
12093              this.element.toggleClass( "ui-state-disabled", !!value );
12094          }
12095  
12096          this._super( key, value );
12097  
12098          switch ( key ) {
12099              case "orientation":
12100                  this._detectOrientation();
12101                  this.element
12102                      .removeClass( "ui-slider-horizontal ui-slider-vertical" )
12103                      .addClass( "ui-slider-" + this.orientation );
12104                  this._refreshValue();
12105  
12106                  // Reset positioning from previous orientation
12107                  this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
12108                  break;
12109              case "value":
12110                  this._animateOff = true;
12111                  this._refreshValue();
12112                  this._change( null, 0 );
12113                  this._animateOff = false;
12114                  break;
12115              case "values":
12116                  this._animateOff = true;
12117                  this._refreshValue();
12118                  for ( i = 0; i < valsLength; i += 1 ) {
12119                      this._change( null, i );
12120                  }
12121                  this._animateOff = false;
12122                  break;
12123              case "step":
12124              case "min":
12125              case "max":
12126                  this._animateOff = true;
12127                  this._calculateNewMax();
12128                  this._refreshValue();
12129                  this._animateOff = false;
12130                  break;
12131              case "range":
12132                  this._animateOff = true;
12133                  this._refresh();
12134                  this._animateOff = false;
12135                  break;
12136          }
12137      },
12138  
12139      //internal value getter
12140      // _value() returns value trimmed by min and max, aligned by step
12141      _value: function() {
12142          var val = this.options.value;
12143          val = this._trimAlignValue( val );
12144  
12145          return val;
12146      },
12147  
12148      //internal values getter
12149      // _values() returns array of values trimmed by min and max, aligned by step
12150      // _values( index ) returns single value trimmed by min and max, aligned by step
12151      _values: function( index ) {
12152          var val,
12153              vals,
12154              i;
12155  
12156          if ( arguments.length ) {
12157              val = this.options.values[ index ];
12158              val = this._trimAlignValue( val );
12159  
12160              return val;
12161          } else if ( this.options.values && this.options.values.length ) {
12162              // .slice() creates a copy of the array
12163              // this copy gets trimmed by min and max and then returned
12164              vals = this.options.values.slice();
12165              for ( i = 0; i < vals.length; i += 1) {
12166                  vals[ i ] = this._trimAlignValue( vals[ i ] );
12167              }
12168  
12169              return vals;
12170          } else {
12171              return [];
12172          }
12173      },
12174  
12175      // returns the step-aligned value that val is closest to, between (inclusive) min and max
12176      _trimAlignValue: function( val ) {
12177          if ( val <= this._valueMin() ) {
12178              return this._valueMin();
12179          }
12180          if ( val >= this._valueMax() ) {
12181              return this._valueMax();
12182          }
12183          var step = ( this.options.step > 0 ) ? this.options.step : 1,
12184              valModStep = (val - this._valueMin()) % step,
12185              alignValue = val - valModStep;
12186  
12187          if ( Math.abs(valModStep) * 2 >= step ) {
12188              alignValue += ( valModStep > 0 ) ? step : ( -step );
12189          }
12190  
12191          // Since JavaScript has problems with large floats, round
12192          // the final value to 5 digits after the decimal point (see #4124)
12193          return parseFloat( alignValue.toFixed(5) );
12194      },
12195  
12196      _calculateNewMax: function() {
12197          var max = this.options.max,
12198              min = this._valueMin(),
12199              step = this.options.step,
12200              aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
12201          max = aboveMin + min;
12202          this.max = parseFloat( max.toFixed( this._precision() ) );
12203      },
12204  
12205      _precision: function() {
12206          var precision = this._precisionOf( this.options.step );
12207          if ( this.options.min !== null ) {
12208              precision = Math.max( precision, this._precisionOf( this.options.min ) );
12209          }
12210          return precision;
12211      },
12212  
12213      _precisionOf: function( num ) {
12214          var str = num.toString(),
12215              decimal = str.indexOf( "." );
12216          return decimal === -1 ? 0 : str.length - decimal - 1;
12217      },
12218  
12219      _valueMin: function() {
12220          return this.options.min;
12221      },
12222  
12223      _valueMax: function() {
12224          return this.max;
12225      },
12226  
12227      _refreshValue: function() {
12228          var lastValPercent, valPercent, value, valueMin, valueMax,
12229              oRange = this.options.range,
12230              o = this.options,
12231              that = this,
12232              animate = ( !this._animateOff ) ? o.animate : false,
12233              _set = {};
12234  
12235          if ( this.options.values && this.options.values.length ) {
12236              this.handles.each(function( i ) {
12237                  valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
12238                  _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12239                  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12240                  if ( that.options.range === true ) {
12241                      if ( that.orientation === "horizontal" ) {
12242                          if ( i === 0 ) {
12243                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
12244                          }
12245                          if ( i === 1 ) {
12246                              that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12247                          }
12248                      } else {
12249                          if ( i === 0 ) {
12250                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
12251                          }
12252                          if ( i === 1 ) {
12253                              that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
12254                          }
12255                      }
12256                  }
12257                  lastValPercent = valPercent;
12258              });
12259          } else {
12260              value = this.value();
12261              valueMin = this._valueMin();
12262              valueMax = this._valueMax();
12263              valPercent = ( valueMax !== valueMin ) ?
12264                      ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
12265                      0;
12266              _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
12267              this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
12268  
12269              if ( oRange === "min" && this.orientation === "horizontal" ) {
12270                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
12271              }
12272              if ( oRange === "max" && this.orientation === "horizontal" ) {
12273                  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12274              }
12275              if ( oRange === "min" && this.orientation === "vertical" ) {
12276                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
12277              }
12278              if ( oRange === "max" && this.orientation === "vertical" ) {
12279                  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
12280              }
12281          }
12282      },
12283  
12284      _handleEvents: {
12285          keydown: function( event ) {
12286              var allowed, curVal, newVal, step,
12287                  index = $( event.target ).data( "ui-slider-handle-index" );
12288  
12289              switch ( event.keyCode ) {
12290                  case $.ui.keyCode.HOME:
12291                  case $.ui.keyCode.END:
12292                  case $.ui.keyCode.PAGE_UP:
12293                  case $.ui.keyCode.PAGE_DOWN:
12294                  case $.ui.keyCode.UP:
12295                  case $.ui.keyCode.RIGHT:
12296                  case $.ui.keyCode.DOWN:
12297                  case $.ui.keyCode.LEFT:
12298                      event.preventDefault();
12299                      if ( !this._keySliding ) {
12300                          this._keySliding = true;
12301                          $( event.target ).addClass( "ui-state-active" );
12302                          allowed = this._start( event, index );
12303                          if ( allowed === false ) {
12304                              return;
12305                          }
12306                      }
12307                      break;
12308              }
12309  
12310              step = this.options.step;
12311              if ( this.options.values && this.options.values.length ) {
12312                  curVal = newVal = this.values( index );
12313              } else {
12314                  curVal = newVal = this.value();
12315              }
12316  
12317              switch ( event.keyCode ) {
12318                  case $.ui.keyCode.HOME:
12319                      newVal = this._valueMin();
12320                      break;
12321                  case $.ui.keyCode.END:
12322                      newVal = this._valueMax();
12323                      break;
12324                  case $.ui.keyCode.PAGE_UP:
12325                      newVal = this._trimAlignValue(
12326                          curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
12327                      );
12328                      break;
12329                  case $.ui.keyCode.PAGE_DOWN:
12330                      newVal = this._trimAlignValue(
12331                          curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
12332                      break;
12333                  case $.ui.keyCode.UP:
12334                  case $.ui.keyCode.RIGHT:
12335                      if ( curVal === this._valueMax() ) {
12336                          return;
12337                      }
12338                      newVal = this._trimAlignValue( curVal + step );
12339                      break;
12340                  case $.ui.keyCode.DOWN:
12341                  case $.ui.keyCode.LEFT:
12342                      if ( curVal === this._valueMin() ) {
12343                          return;
12344                      }
12345                      newVal = this._trimAlignValue( curVal - step );
12346                      break;
12347              }
12348  
12349              this._slide( event, index, newVal );
12350          },
12351          keyup: function( event ) {
12352              var index = $( event.target ).data( "ui-slider-handle-index" );
12353  
12354              if ( this._keySliding ) {
12355                  this._keySliding = false;
12356                  this._stop( event, index );
12357                  this._change( event, index );
12358                  $( event.target ).removeClass( "ui-state-active" );
12359              }
12360          }
12361      }
12362  });
12363  
12364  
12365  /*!
12366   * jQuery UI Spinner 1.11.4
12367   * http://jqueryui.com
12368   *
12369   * Copyright jQuery Foundation and other contributors
12370   * Released under the MIT license.
12371   * http://jquery.org/license
12372   *
12373   * http://api.jqueryui.com/spinner/
12374   */
12375  
12376  
12377  function spinner_modifier( fn ) {
12378      return function() {
12379          var previous = this.element.val();
12380          fn.apply( this, arguments );
12381          this._refresh();
12382          if ( previous !== this.element.val() ) {
12383              this._trigger( "change" );
12384          }
12385      };
12386  }
12387  
12388  var spinner = $.widget( "ui.spinner", {
12389      version: "1.11.4",
12390      defaultElement: "<input>",
12391      widgetEventPrefix: "spin",
12392      options: {
12393          culture: null,
12394          icons: {
12395              down: "ui-icon-triangle-1-s",
12396              up: "ui-icon-triangle-1-n"
12397          },
12398          incremental: true,
12399          max: null,
12400          min: null,
12401          numberFormat: null,
12402          page: 10,
12403          step: 1,
12404  
12405          change: null,
12406          spin: null,
12407          start: null,
12408          stop: null
12409      },
12410  
12411      _create: function() {
12412          // handle string values that need to be parsed
12413          this._setOption( "max", this.options.max );
12414          this._setOption( "min", this.options.min );
12415          this._setOption( "step", this.options.step );
12416  
12417          // Only format if there is a value, prevents the field from being marked
12418          // as invalid in Firefox, see #9573.
12419          if ( this.value() !== "" ) {
12420              // Format the value, but don't constrain.
12421              this._value( this.element.val(), true );
12422          }
12423  
12424          this._draw();
12425          this._on( this._events );
12426          this._refresh();
12427  
12428          // turning off autocomplete prevents the browser from remembering the
12429          // value when navigating through history, so we re-enable autocomplete
12430          // if the page is unloaded before the widget is destroyed. #7790
12431          this._on( this.window, {
12432              beforeunload: function() {
12433                  this.element.removeAttr( "autocomplete" );
12434              }
12435          });
12436      },
12437  
12438      _getCreateOptions: function() {
12439          var options = {},
12440              element = this.element;
12441  
12442          $.each( [ "min", "max", "step" ], function( i, option ) {
12443              var value = element.attr( option );
12444              if ( value !== undefined && value.length ) {
12445                  options[ option ] = value;
12446              }
12447          });
12448  
12449          return options;
12450      },
12451  
12452      _events: {
12453          keydown: function( event ) {
12454              if ( this._start( event ) && this._keydown( event ) ) {
12455                  event.preventDefault();
12456              }
12457          },
12458          keyup: "_stop",
12459          focus: function() {
12460              this.previous = this.element.val();
12461          },
12462          blur: function( event ) {
12463              if ( this.cancelBlur ) {
12464                  delete this.cancelBlur;
12465                  return;
12466              }
12467  
12468              this._stop();
12469              this._refresh();
12470              if ( this.previous !== this.element.val() ) {
12471                  this._trigger( "change", event );
12472              }
12473          },
12474          mousewheel: function( event, delta ) {
12475              if ( !delta ) {
12476                  return;
12477              }
12478              if ( !this.spinning && !this._start( event ) ) {
12479                  return false;
12480              }
12481  
12482              this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
12483              clearTimeout( this.mousewheelTimer );
12484              this.mousewheelTimer = this._delay(function() {
12485                  if ( this.spinning ) {
12486                      this._stop( event );
12487                  }
12488              }, 100 );
12489              event.preventDefault();
12490          },
12491          "mousedown .ui-spinner-button": function( event ) {
12492              var previous;
12493  
12494              // We never want the buttons to have focus; whenever the user is
12495              // interacting with the spinner, the focus should be on the input.
12496              // If the input is focused then this.previous is properly set from
12497              // when the input first received focus. If the input is not focused
12498              // then we need to set this.previous based on the value before spinning.
12499              previous = this.element[0] === this.document[0].activeElement ?
12500                  this.previous : this.element.val();
12501  			function checkFocus() {
12502                  var isActive = this.element[0] === this.document[0].activeElement;
12503                  if ( !isActive ) {
12504                      this.element.focus();
12505                      this.previous = previous;
12506                      // support: IE
12507                      // IE sets focus asynchronously, so we need to check if focus
12508                      // moved off of the input because the user clicked on the button.
12509                      this._delay(function() {
12510                          this.previous = previous;
12511                      });
12512                  }
12513              }
12514  
12515              // ensure focus is on (or stays on) the text field
12516              event.preventDefault();
12517              checkFocus.call( this );
12518  
12519              // support: IE
12520              // IE doesn't prevent moving focus even with event.preventDefault()
12521              // so we set a flag to know when we should ignore the blur event
12522              // and check (again) if focus moved off of the input.
12523              this.cancelBlur = true;
12524              this._delay(function() {
12525                  delete this.cancelBlur;
12526                  checkFocus.call( this );
12527              });
12528  
12529              if ( this._start( event ) === false ) {
12530                  return;
12531              }
12532  
12533              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12534          },
12535          "mouseup .ui-spinner-button": "_stop",
12536          "mouseenter .ui-spinner-button": function( event ) {
12537              // button will add ui-state-active if mouse was down while mouseleave and kept down
12538              if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
12539                  return;
12540              }
12541  
12542              if ( this._start( event ) === false ) {
12543                  return false;
12544              }
12545              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
12546          },
12547          // TODO: do we really want to consider this a stop?
12548          // shouldn't we just stop the repeater and wait until mouseup before
12549          // we trigger the stop event?
12550          "mouseleave .ui-spinner-button": "_stop"
12551      },
12552  
12553      _draw: function() {
12554          var uiSpinner = this.uiSpinner = this.element
12555              .addClass( "ui-spinner-input" )
12556              .attr( "autocomplete", "off" )
12557              .wrap( this._uiSpinnerHtml() )
12558              .parent()
12559                  // add buttons
12560                  .append( this._buttonHtml() );
12561  
12562          this.element.attr( "role", "spinbutton" );
12563  
12564          // button bindings
12565          this.buttons = uiSpinner.find( ".ui-spinner-button" )
12566              .attr( "tabIndex", -1 )
12567              .button()
12568              .removeClass( "ui-corner-all" );
12569  
12570          // IE 6 doesn't understand height: 50% for the buttons
12571          // unless the wrapper has an explicit height
12572          if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
12573                  uiSpinner.height() > 0 ) {
12574              uiSpinner.height( uiSpinner.height() );
12575          }
12576  
12577          // disable spinner if element was already disabled
12578          if ( this.options.disabled ) {
12579              this.disable();
12580          }
12581      },
12582  
12583      _keydown: function( event ) {
12584          var options = this.options,
12585              keyCode = $.ui.keyCode;
12586  
12587          switch ( event.keyCode ) {
12588          case keyCode.UP:
12589              this._repeat( null, 1, event );
12590              return true;
12591          case keyCode.DOWN:
12592              this._repeat( null, -1, event );
12593              return true;
12594          case keyCode.PAGE_UP:
12595              this._repeat( null, options.page, event );
12596              return true;
12597          case keyCode.PAGE_DOWN:
12598              this._repeat( null, -options.page, event );
12599              return true;
12600          }
12601  
12602          return false;
12603      },
12604  
12605      _uiSpinnerHtml: function() {
12606          return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
12607      },
12608  
12609      _buttonHtml: function() {
12610          return "" +
12611              "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
12612                  "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
12613              "</a>" +
12614              "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
12615                  "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
12616              "</a>";
12617      },
12618  
12619      _start: function( event ) {
12620          if ( !this.spinning && this._trigger( "start", event ) === false ) {
12621              return false;
12622          }
12623  
12624          if ( !this.counter ) {
12625              this.counter = 1;
12626          }
12627          this.spinning = true;
12628          return true;
12629      },
12630  
12631      _repeat: function( i, steps, event ) {
12632          i = i || 500;
12633  
12634          clearTimeout( this.timer );
12635          this.timer = this._delay(function() {
12636              this._repeat( 40, steps, event );
12637          }, i );
12638  
12639          this._spin( steps * this.options.step, event );
12640      },
12641  
12642      _spin: function( step, event ) {
12643          var value = this.value() || 0;
12644  
12645          if ( !this.counter ) {
12646              this.counter = 1;
12647          }
12648  
12649          value = this._adjustValue( value + step * this._increment( this.counter ) );
12650  
12651          if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
12652              this._value( value );
12653              this.counter++;
12654          }
12655      },
12656  
12657      _increment: function( i ) {
12658          var incremental = this.options.incremental;
12659  
12660          if ( incremental ) {
12661              return $.isFunction( incremental ) ?
12662                  incremental( i ) :
12663                  Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
12664          }
12665  
12666          return 1;
12667      },
12668  
12669      _precision: function() {
12670          var precision = this._precisionOf( this.options.step );
12671          if ( this.options.min !== null ) {
12672              precision = Math.max( precision, this._precisionOf( this.options.min ) );
12673          }
12674          return precision;
12675      },
12676  
12677      _precisionOf: function( num ) {
12678          var str = num.toString(),
12679              decimal = str.indexOf( "." );
12680          return decimal === -1 ? 0 : str.length - decimal - 1;
12681      },
12682  
12683      _adjustValue: function( value ) {
12684          var base, aboveMin,
12685              options = this.options;
12686  
12687          // make sure we're at a valid step
12688          // - find out where we are relative to the base (min or 0)
12689          base = options.min !== null ? options.min : 0;
12690          aboveMin = value - base;
12691          // - round to the nearest step
12692          aboveMin = Math.round(aboveMin / options.step) * options.step;
12693          // - rounding is based on 0, so adjust back to our base
12694          value = base + aboveMin;
12695  
12696          // fix precision from bad JS floating point math
12697          value = parseFloat( value.toFixed( this._precision() ) );
12698  
12699          // clamp the value
12700          if ( options.max !== null && value > options.max) {
12701              return options.max;
12702          }
12703          if ( options.min !== null && value < options.min ) {
12704              return options.min;
12705          }
12706  
12707          return value;
12708      },
12709  
12710      _stop: function( event ) {
12711          if ( !this.spinning ) {
12712              return;
12713          }
12714  
12715          clearTimeout( this.timer );
12716          clearTimeout( this.mousewheelTimer );
12717          this.counter = 0;
12718          this.spinning = false;
12719          this._trigger( "stop", event );
12720      },
12721  
12722      _setOption: function( key, value ) {
12723          if ( key === "culture" || key === "numberFormat" ) {
12724              var prevValue = this._parse( this.element.val() );
12725              this.options[ key ] = value;
12726              this.element.val( this._format( prevValue ) );
12727              return;
12728          }
12729  
12730          if ( key === "max" || key === "min" || key === "step" ) {
12731              if ( typeof value === "string" ) {
12732                  value = this._parse( value );
12733              }
12734          }
12735          if ( key === "icons" ) {
12736              this.buttons.first().find( ".ui-icon" )
12737                  .removeClass( this.options.icons.up )
12738                  .addClass( value.up );
12739              this.buttons.last().find( ".ui-icon" )
12740                  .removeClass( this.options.icons.down )
12741                  .addClass( value.down );
12742          }
12743  
12744          this._super( key, value );
12745  
12746          if ( key === "disabled" ) {
12747              this.widget().toggleClass( "ui-state-disabled", !!value );
12748              this.element.prop( "disabled", !!value );
12749              this.buttons.button( value ? "disable" : "enable" );
12750          }
12751      },
12752  
12753      _setOptions: spinner_modifier(function( options ) {
12754          this._super( options );
12755      }),
12756  
12757      _parse: function( val ) {
12758          if ( typeof val === "string" && val !== "" ) {
12759              val = window.Globalize && this.options.numberFormat ?
12760                  Globalize.parseFloat( val, 10, this.options.culture ) : +val;
12761          }
12762          return val === "" || isNaN( val ) ? null : val;
12763      },
12764  
12765      _format: function( value ) {
12766          if ( value === "" ) {
12767              return "";
12768          }
12769          return window.Globalize && this.options.numberFormat ?
12770              Globalize.format( value, this.options.numberFormat, this.options.culture ) :
12771              value;
12772      },
12773  
12774      _refresh: function() {
12775          this.element.attr({
12776              "aria-valuemin": this.options.min,
12777              "aria-valuemax": this.options.max,
12778              // TODO: what should we do with values that can't be parsed?
12779              "aria-valuenow": this._parse( this.element.val() )
12780          });
12781      },
12782  
12783      isValid: function() {
12784          var value = this.value();
12785  
12786          // null is invalid
12787          if ( value === null ) {
12788              return false;
12789          }
12790  
12791          // if value gets adjusted, it's invalid
12792          return value === this._adjustValue( value );
12793      },
12794  
12795      // update the value without triggering change
12796      _value: function( value, allowAny ) {
12797          var parsed;
12798          if ( value !== "" ) {
12799              parsed = this._parse( value );
12800              if ( parsed !== null ) {
12801                  if ( !allowAny ) {
12802                      parsed = this._adjustValue( parsed );
12803                  }
12804                  value = this._format( parsed );
12805              }
12806          }
12807          this.element.val( value );
12808          this._refresh();
12809      },
12810  
12811      _destroy: function() {
12812          this.element
12813              .removeClass( "ui-spinner-input" )
12814              .prop( "disabled", false )
12815              .removeAttr( "autocomplete" )
12816              .removeAttr( "role" )
12817              .removeAttr( "aria-valuemin" )
12818              .removeAttr( "aria-valuemax" )
12819              .removeAttr( "aria-valuenow" );
12820          this.uiSpinner.replaceWith( this.element );
12821      },
12822  
12823      stepUp: spinner_modifier(function( steps ) {
12824          this._stepUp( steps );
12825      }),
12826      _stepUp: function( steps ) {
12827          if ( this._start() ) {
12828              this._spin( (steps || 1) * this.options.step );
12829              this._stop();
12830          }
12831      },
12832  
12833      stepDown: spinner_modifier(function( steps ) {
12834          this._stepDown( steps );
12835      }),
12836      _stepDown: function( steps ) {
12837          if ( this._start() ) {
12838              this._spin( (steps || 1) * -this.options.step );
12839              this._stop();
12840          }
12841      },
12842  
12843      pageUp: spinner_modifier(function( pages ) {
12844          this._stepUp( (pages || 1) * this.options.page );
12845      }),
12846  
12847      pageDown: spinner_modifier(function( pages ) {
12848          this._stepDown( (pages || 1) * this.options.page );
12849      }),
12850  
12851      value: function( newVal ) {
12852          if ( !arguments.length ) {
12853              return this._parse( this.element.val() );
12854          }
12855          spinner_modifier( this._value ).call( this, newVal );
12856      },
12857  
12858      widget: function() {
12859          return this.uiSpinner;
12860      }
12861  });
12862  
12863  
12864  /*!
12865   * jQuery UI Tabs 1.11.4
12866   * http://jqueryui.com
12867   *
12868   * Copyright jQuery Foundation and other contributors
12869   * Released under the MIT license.
12870   * http://jquery.org/license
12871   *
12872   * http://api.jqueryui.com/tabs/
12873   */
12874  
12875  
12876  var tabs = $.widget( "ui.tabs", {
12877      version: "1.11.4",
12878      delay: 300,
12879      options: {
12880          active: null,
12881          collapsible: false,
12882          event: "click",
12883          heightStyle: "content",
12884          hide: null,
12885          show: null,
12886  
12887          // callbacks
12888          activate: null,
12889          beforeActivate: null,
12890          beforeLoad: null,
12891          load: null
12892      },
12893  
12894      _isLocal: (function() {
12895          var rhash = /#.*$/;
12896  
12897          return function( anchor ) {
12898              var anchorUrl, locationUrl;
12899  
12900              // support: IE7
12901              // IE7 doesn't normalize the href property when set via script (#9317)
12902              anchor = anchor.cloneNode( false );
12903  
12904              anchorUrl = anchor.href.replace( rhash, "" );
12905              locationUrl = location.href.replace( rhash, "" );
12906  
12907              // decoding may throw an error if the URL isn't UTF-8 (#9518)
12908              try {
12909                  anchorUrl = decodeURIComponent( anchorUrl );
12910              } catch ( error ) {}
12911              try {
12912                  locationUrl = decodeURIComponent( locationUrl );
12913              } catch ( error ) {}
12914  
12915              return anchor.hash.length > 1 && anchorUrl === locationUrl;
12916          };
12917      })(),
12918  
12919      _create: function() {
12920          var that = this,
12921              options = this.options;
12922  
12923          this.running = false;
12924  
12925          this.element
12926              .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
12927              .toggleClass( "ui-tabs-collapsible", options.collapsible );
12928  
12929          this._processTabs();
12930          options.active = this._initialActive();
12931  
12932          // Take disabling tabs via class attribute from HTML
12933          // into account and update option properly.
12934          if ( $.isArray( options.disabled ) ) {
12935              options.disabled = $.unique( options.disabled.concat(
12936                  $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
12937                      return that.tabs.index( li );
12938                  })
12939              ) ).sort();
12940          }
12941  
12942          // check for length avoids error when initializing empty list
12943          if ( this.options.active !== false && this.anchors.length ) {
12944              this.active = this._findActive( options.active );
12945          } else {
12946              this.active = $();
12947          }
12948  
12949          this._refresh();
12950  
12951          if ( this.active.length ) {
12952              this.load( options.active );
12953          }
12954      },
12955  
12956      _initialActive: function() {
12957          var active = this.options.active,
12958              collapsible = this.options.collapsible,
12959              locationHash = location.hash.substring( 1 );
12960  
12961          if ( active === null ) {
12962              // check the fragment identifier in the URL
12963              if ( locationHash ) {
12964                  this.tabs.each(function( i, tab ) {
12965                      if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
12966                          active = i;
12967                          return false;
12968                      }
12969                  });
12970              }
12971  
12972              // check for a tab marked active via a class
12973              if ( active === null ) {
12974                  active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
12975              }
12976  
12977              // no active tab, set to false
12978              if ( active === null || active === -1 ) {
12979                  active = this.tabs.length ? 0 : false;
12980              }
12981          }
12982  
12983          // handle numbers: negative, out of range
12984          if ( active !== false ) {
12985              active = this.tabs.index( this.tabs.eq( active ) );
12986              if ( active === -1 ) {
12987                  active = collapsible ? false : 0;
12988              }
12989          }
12990  
12991          // don't allow collapsible: false and active: false
12992          if ( !collapsible && active === false && this.anchors.length ) {
12993              active = 0;
12994          }
12995  
12996          return active;
12997      },
12998  
12999      _getCreateEventData: function() {
13000          return {
13001              tab: this.active,
13002              panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13003          };
13004      },
13005  
13006      _tabKeydown: function( event ) {
13007          var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13008              selectedIndex = this.tabs.index( focusedTab ),
13009              goingForward = true;
13010  
13011          if ( this._handlePageNav( event ) ) {
13012              return;
13013          }
13014  
13015          switch ( event.keyCode ) {
13016              case $.ui.keyCode.RIGHT:
13017              case $.ui.keyCode.DOWN:
13018                  selectedIndex++;
13019                  break;
13020              case $.ui.keyCode.UP:
13021              case $.ui.keyCode.LEFT:
13022                  goingForward = false;
13023                  selectedIndex--;
13024                  break;
13025              case $.ui.keyCode.END:
13026                  selectedIndex = this.anchors.length - 1;
13027                  break;
13028              case $.ui.keyCode.HOME:
13029                  selectedIndex = 0;
13030                  break;
13031              case $.ui.keyCode.SPACE:
13032                  // Activate only, no collapsing
13033                  event.preventDefault();
13034                  clearTimeout( this.activating );
13035                  this._activate( selectedIndex );
13036                  return;
13037              case $.ui.keyCode.ENTER:
13038                  // Toggle (cancel delayed activation, allow collapsing)
13039                  event.preventDefault();
13040                  clearTimeout( this.activating );
13041                  // Determine if we should collapse or activate
13042                  this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13043                  return;
13044              default:
13045                  return;
13046          }
13047  
13048          // Focus the appropriate tab, based on which key was pressed
13049          event.preventDefault();
13050          clearTimeout( this.activating );
13051          selectedIndex = this._focusNextTab( selectedIndex, goingForward );
13052  
13053          // Navigating with control/command key will prevent automatic activation
13054          if ( !event.ctrlKey && !event.metaKey ) {
13055  
13056              // Update aria-selected immediately so that AT think the tab is already selected.
13057              // Otherwise AT may confuse the user by stating that they need to activate the tab,
13058              // but the tab will already be activated by the time the announcement finishes.
13059              focusedTab.attr( "aria-selected", "false" );
13060              this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
13061  
13062              this.activating = this._delay(function() {
13063                  this.option( "active", selectedIndex );
13064              }, this.delay );
13065          }
13066      },
13067  
13068      _panelKeydown: function( event ) {
13069          if ( this._handlePageNav( event ) ) {
13070              return;
13071          }
13072  
13073          // Ctrl+up moves focus to the current tab
13074          if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
13075              event.preventDefault();
13076              this.active.focus();
13077          }
13078      },
13079  
13080      // Alt+page up/down moves focus to the previous/next tab (and activates)
13081      _handlePageNav: function( event ) {
13082          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
13083              this._activate( this._focusNextTab( this.options.active - 1, false ) );
13084              return true;
13085          }
13086          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
13087              this._activate( this._focusNextTab( this.options.active + 1, true ) );
13088              return true;
13089          }
13090      },
13091  
13092      _findNextTab: function( index, goingForward ) {
13093          var lastTabIndex = this.tabs.length - 1;
13094  
13095  		function constrain() {
13096              if ( index > lastTabIndex ) {
13097                  index = 0;
13098              }
13099              if ( index < 0 ) {
13100                  index = lastTabIndex;
13101              }
13102              return index;
13103          }
13104  
13105          while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
13106              index = goingForward ? index + 1 : index - 1;
13107          }
13108  
13109          return index;
13110      },
13111  
13112      _focusNextTab: function( index, goingForward ) {
13113          index = this._findNextTab( index, goingForward );
13114          this.tabs.eq( index ).focus();
13115          return index;
13116      },
13117  
13118      _setOption: function( key, value ) {
13119          if ( key === "active" ) {
13120              // _activate() will handle invalid values and update this.options
13121              this._activate( value );
13122              return;
13123          }
13124  
13125          if ( key === "disabled" ) {
13126              // don't use the widget factory's disabled handling
13127              this._setupDisabled( value );
13128              return;
13129          }
13130  
13131          this._super( key, value);
13132  
13133          if ( key === "collapsible" ) {
13134              this.element.toggleClass( "ui-tabs-collapsible", value );
13135              // Setting collapsible: false while collapsed; open first panel
13136              if ( !value && this.options.active === false ) {
13137                  this._activate( 0 );
13138              }
13139          }
13140  
13141          if ( key === "event" ) {
13142              this._setupEvents( value );
13143          }
13144  
13145          if ( key === "heightStyle" ) {
13146              this._setupHeightStyle( value );
13147          }
13148      },
13149  
13150      _sanitizeSelector: function( hash ) {
13151          return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
13152      },
13153  
13154      refresh: function() {
13155          var options = this.options,
13156              lis = this.tablist.children( ":has(a[href])" );
13157  
13158          // get disabled tabs from class attribute from HTML
13159          // this will get converted to a boolean if needed in _refresh()
13160          options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
13161              return lis.index( tab );
13162          });
13163  
13164          this._processTabs();
13165  
13166          // was collapsed or no tabs
13167          if ( options.active === false || !this.anchors.length ) {
13168              options.active = false;
13169              this.active = $();
13170          // was active, but active tab is gone
13171          } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
13172              // all remaining tabs are disabled
13173              if ( this.tabs.length === options.disabled.length ) {
13174                  options.active = false;
13175                  this.active = $();
13176              // activate previous tab
13177              } else {
13178                  this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
13179              }
13180          // was active, active tab still exists
13181          } else {
13182              // make sure active index is correct
13183              options.active = this.tabs.index( this.active );
13184          }
13185  
13186          this._refresh();
13187      },
13188  
13189      _refresh: function() {
13190          this._setupDisabled( this.options.disabled );
13191          this._setupEvents( this.options.event );
13192          this._setupHeightStyle( this.options.heightStyle );
13193  
13194          this.tabs.not( this.active ).attr({
13195              "aria-selected": "false",
13196              "aria-expanded": "false",
13197              tabIndex: -1
13198          });
13199          this.panels.not( this._getPanelForTab( this.active ) )
13200              .hide()
13201              .attr({
13202                  "aria-hidden": "true"
13203              });
13204  
13205          // Make sure one tab is in the tab order
13206          if ( !this.active.length ) {
13207              this.tabs.eq( 0 ).attr( "tabIndex", 0 );
13208          } else {
13209              this.active
13210                  .addClass( "ui-tabs-active ui-state-active" )
13211                  .attr({
13212                      "aria-selected": "true",
13213                      "aria-expanded": "true",
13214                      tabIndex: 0
13215                  });
13216              this._getPanelForTab( this.active )
13217                  .show()
13218                  .attr({
13219                      "aria-hidden": "false"
13220                  });
13221          }
13222      },
13223  
13224      _processTabs: function() {
13225          var that = this,
13226              prevTabs = this.tabs,
13227              prevAnchors = this.anchors,
13228              prevPanels = this.panels;
13229  
13230          this.tablist = this._getList()
13231              .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13232              .attr( "role", "tablist" )
13233  
13234              // Prevent users from focusing disabled tabs via click
13235              .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
13236                  if ( $( this ).is( ".ui-state-disabled" ) ) {
13237                      event.preventDefault();
13238                  }
13239              })
13240  
13241              // support: IE <9
13242              // Preventing the default action in mousedown doesn't prevent IE
13243              // from focusing the element, so if the anchor gets focused, blur.
13244              // We don't have to worry about focusing the previously focused
13245              // element since clicking on a non-focusable element should focus
13246              // the body anyway.
13247              .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13248                  if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13249                      this.blur();
13250                  }
13251              });
13252  
13253          this.tabs = this.tablist.find( "> li:has(a[href])" )
13254              .addClass( "ui-state-default ui-corner-top" )
13255              .attr({
13256                  role: "tab",
13257                  tabIndex: -1
13258              });
13259  
13260          this.anchors = this.tabs.map(function() {
13261                  return $( "a", this )[ 0 ];
13262              })
13263              .addClass( "ui-tabs-anchor" )
13264              .attr({
13265                  role: "presentation",
13266                  tabIndex: -1
13267              });
13268  
13269          this.panels = $();
13270  
13271          this.anchors.each(function( i, anchor ) {
13272              var selector, panel, panelId,
13273                  anchorId = $( anchor ).uniqueId().attr( "id" ),
13274                  tab = $( anchor ).closest( "li" ),
13275                  originalAriaControls = tab.attr( "aria-controls" );
13276  
13277              // inline tab
13278              if ( that._isLocal( anchor ) ) {
13279                  selector = anchor.hash;
13280                  panelId = selector.substring( 1 );
13281                  panel = that.element.find( that._sanitizeSelector( selector ) );
13282              // remote tab
13283              } else {
13284                  // If the tab doesn't already have aria-controls,
13285                  // generate an id by using a throw-away element
13286                  panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
13287                  selector = "#" + panelId;
13288                  panel = that.element.find( selector );
13289                  if ( !panel.length ) {
13290                      panel = that._createPanel( panelId );
13291                      panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
13292                  }
13293                  panel.attr( "aria-live", "polite" );
13294              }
13295  
13296              if ( panel.length) {
13297                  that.panels = that.panels.add( panel );
13298              }
13299              if ( originalAriaControls ) {
13300                  tab.data( "ui-tabs-aria-controls", originalAriaControls );
13301              }
13302              tab.attr({
13303                  "aria-controls": panelId,
13304                  "aria-labelledby": anchorId
13305              });
13306              panel.attr( "aria-labelledby", anchorId );
13307          });
13308  
13309          this.panels
13310              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13311              .attr( "role", "tabpanel" );
13312  
13313          // Avoid memory leaks (#10056)
13314          if ( prevTabs ) {
13315              this._off( prevTabs.not( this.tabs ) );
13316              this._off( prevAnchors.not( this.anchors ) );
13317              this._off( prevPanels.not( this.panels ) );
13318          }
13319      },
13320  
13321      // allow overriding how to find the list for rare usage scenarios (#7715)
13322      _getList: function() {
13323          return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
13324      },
13325  
13326      _createPanel: function( id ) {
13327          return $( "<div>" )
13328              .attr( "id", id )
13329              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
13330              .data( "ui-tabs-destroy", true );
13331      },
13332  
13333      _setupDisabled: function( disabled ) {
13334          if ( $.isArray( disabled ) ) {
13335              if ( !disabled.length ) {
13336                  disabled = false;
13337              } else if ( disabled.length === this.anchors.length ) {
13338                  disabled = true;
13339              }
13340          }
13341  
13342          // disable tabs
13343          for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
13344              if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
13345                  $( li )
13346                      .addClass( "ui-state-disabled" )
13347                      .attr( "aria-disabled", "true" );
13348              } else {
13349                  $( li )
13350                      .removeClass( "ui-state-disabled" )
13351                      .removeAttr( "aria-disabled" );
13352              }
13353          }
13354  
13355          this.options.disabled = disabled;
13356      },
13357  
13358      _setupEvents: function( event ) {
13359          var events = {};
13360          if ( event ) {
13361              $.each( event.split(" "), function( index, eventName ) {
13362                  events[ eventName ] = "_eventHandler";
13363              });
13364          }
13365  
13366          this._off( this.anchors.add( this.tabs ).add( this.panels ) );
13367          // Always prevent the default action, even when disabled
13368          this._on( true, this.anchors, {
13369              click: function( event ) {
13370                  event.preventDefault();
13371              }
13372          });
13373          this._on( this.anchors, events );
13374          this._on( this.tabs, { keydown: "_tabKeydown" } );
13375          this._on( this.panels, { keydown: "_panelKeydown" } );
13376  
13377          this._focusable( this.tabs );
13378          this._hoverable( this.tabs );
13379      },
13380  
13381      _setupHeightStyle: function( heightStyle ) {
13382          var maxHeight,
13383              parent = this.element.parent();
13384  
13385          if ( heightStyle === "fill" ) {
13386              maxHeight = parent.height();
13387              maxHeight -= this.element.outerHeight() - this.element.height();
13388  
13389              this.element.siblings( ":visible" ).each(function() {
13390                  var elem = $( this ),
13391                      position = elem.css( "position" );
13392  
13393                  if ( position === "absolute" || position === "fixed" ) {
13394                      return;
13395                  }
13396                  maxHeight -= elem.outerHeight( true );
13397              });
13398  
13399              this.element.children().not( this.panels ).each(function() {
13400                  maxHeight -= $( this ).outerHeight( true );
13401              });
13402  
13403              this.panels.each(function() {
13404                  $( this ).height( Math.max( 0, maxHeight -
13405                      $( this ).innerHeight() + $( this ).height() ) );
13406              })
13407              .css( "overflow", "auto" );
13408          } else if ( heightStyle === "auto" ) {
13409              maxHeight = 0;
13410              this.panels.each(function() {
13411                  maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
13412              }).height( maxHeight );
13413          }
13414      },
13415  
13416      _eventHandler: function( event ) {
13417          var options = this.options,
13418              active = this.active,
13419              anchor = $( event.currentTarget ),
13420              tab = anchor.closest( "li" ),
13421              clickedIsActive = tab[ 0 ] === active[ 0 ],
13422              collapsing = clickedIsActive && options.collapsible,
13423              toShow = collapsing ? $() : this._getPanelForTab( tab ),
13424              toHide = !active.length ? $() : this._getPanelForTab( active ),
13425              eventData = {
13426                  oldTab: active,
13427                  oldPanel: toHide,
13428                  newTab: collapsing ? $() : tab,
13429                  newPanel: toShow
13430              };
13431  
13432          event.preventDefault();
13433  
13434          if ( tab.hasClass( "ui-state-disabled" ) ||
13435                  // tab is already loading
13436                  tab.hasClass( "ui-tabs-loading" ) ||
13437                  // can't switch durning an animation
13438                  this.running ||
13439                  // click on active header, but not collapsible
13440                  ( clickedIsActive && !options.collapsible ) ||
13441                  // allow canceling activation
13442                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
13443              return;
13444          }
13445  
13446          options.active = collapsing ? false : this.tabs.index( tab );
13447  
13448          this.active = clickedIsActive ? $() : tab;
13449          if ( this.xhr ) {
13450              this.xhr.abort();
13451          }
13452  
13453          if ( !toHide.length && !toShow.length ) {
13454              $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
13455          }
13456  
13457          if ( toShow.length ) {
13458              this.load( this.tabs.index( tab ), event );
13459          }
13460          this._toggle( event, eventData );
13461      },
13462  
13463      // handles show/hide for selecting tabs
13464      _toggle: function( event, eventData ) {
13465          var that = this,
13466              toShow = eventData.newPanel,
13467              toHide = eventData.oldPanel;
13468  
13469          this.running = true;
13470  
13471  		function complete() {
13472              that.running = false;
13473              that._trigger( "activate", event, eventData );
13474          }
13475  
13476  		function show() {
13477              eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
13478  
13479              if ( toShow.length && that.options.show ) {
13480                  that._show( toShow, that.options.show, complete );
13481              } else {
13482                  toShow.show();
13483                  complete();
13484              }
13485          }
13486  
13487          // start out by hiding, then showing, then completing
13488          if ( toHide.length && this.options.hide ) {
13489              this._hide( toHide, this.options.hide, function() {
13490                  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13491                  show();
13492              });
13493          } else {
13494              eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
13495              toHide.hide();
13496              show();
13497          }
13498  
13499          toHide.attr( "aria-hidden", "true" );
13500          eventData.oldTab.attr({
13501              "aria-selected": "false",
13502              "aria-expanded": "false"
13503          });
13504          // If we're switching tabs, remove the old tab from the tab order.
13505          // If we're opening from collapsed state, remove the previous tab from the tab order.
13506          // If we're collapsing, then keep the collapsing tab in the tab order.
13507          if ( toShow.length && toHide.length ) {
13508              eventData.oldTab.attr( "tabIndex", -1 );
13509          } else if ( toShow.length ) {
13510              this.tabs.filter(function() {
13511                  return $( this ).attr( "tabIndex" ) === 0;
13512              })
13513              .attr( "tabIndex", -1 );
13514          }
13515  
13516          toShow.attr( "aria-hidden", "false" );
13517          eventData.newTab.attr({
13518              "aria-selected": "true",
13519              "aria-expanded": "true",
13520              tabIndex: 0
13521          });
13522      },
13523  
13524      _activate: function( index ) {
13525          var anchor,
13526              active = this._findActive( index );
13527  
13528          // trying to activate the already active panel
13529          if ( active[ 0 ] === this.active[ 0 ] ) {
13530              return;
13531          }
13532  
13533          // trying to collapse, simulate a click on the current active header
13534          if ( !active.length ) {
13535              active = this.active;
13536          }
13537  
13538          anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
13539          this._eventHandler({
13540              target: anchor,
13541              currentTarget: anchor,
13542              preventDefault: $.noop
13543          });
13544      },
13545  
13546      _findActive: function( index ) {
13547          return index === false ? $() : this.tabs.eq( index );
13548      },
13549  
13550      _getIndex: function( index ) {
13551          // meta-function to give users option to provide a href string instead of a numerical index.
13552          if ( typeof index === "string" ) {
13553              index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
13554          }
13555  
13556          return index;
13557      },
13558  
13559      _destroy: function() {
13560          if ( this.xhr ) {
13561              this.xhr.abort();
13562          }
13563  
13564          this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
13565  
13566          this.tablist
13567              .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
13568              .removeAttr( "role" );
13569  
13570          this.anchors
13571              .removeClass( "ui-tabs-anchor" )
13572              .removeAttr( "role" )
13573              .removeAttr( "tabIndex" )
13574              .removeUniqueId();
13575  
13576          this.tablist.unbind( this.eventNamespace );
13577  
13578          this.tabs.add( this.panels ).each(function() {
13579              if ( $.data( this, "ui-tabs-destroy" ) ) {
13580                  $( this ).remove();
13581              } else {
13582                  $( this )
13583                      .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
13584                          "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
13585                      .removeAttr( "tabIndex" )
13586                      .removeAttr( "aria-live" )
13587                      .removeAttr( "aria-busy" )
13588                      .removeAttr( "aria-selected" )
13589                      .removeAttr( "aria-labelledby" )
13590                      .removeAttr( "aria-hidden" )
13591                      .removeAttr( "aria-expanded" )
13592                      .removeAttr( "role" );
13593              }
13594          });
13595  
13596          this.tabs.each(function() {
13597              var li = $( this ),
13598                  prev = li.data( "ui-tabs-aria-controls" );
13599              if ( prev ) {
13600                  li
13601                      .attr( "aria-controls", prev )
13602                      .removeData( "ui-tabs-aria-controls" );
13603              } else {
13604                  li.removeAttr( "aria-controls" );
13605              }
13606          });
13607  
13608          this.panels.show();
13609  
13610          if ( this.options.heightStyle !== "content" ) {
13611              this.panels.css( "height", "" );
13612          }
13613      },
13614  
13615      enable: function( index ) {
13616          var disabled = this.options.disabled;
13617          if ( disabled === false ) {
13618              return;
13619          }
13620  
13621          if ( index === undefined ) {
13622              disabled = false;
13623          } else {
13624              index = this._getIndex( index );
13625              if ( $.isArray( disabled ) ) {
13626                  disabled = $.map( disabled, function( num ) {
13627                      return num !== index ? num : null;
13628                  });
13629              } else {
13630                  disabled = $.map( this.tabs, function( li, num ) {
13631                      return num !== index ? num : null;
13632                  });
13633              }
13634          }
13635          this._setupDisabled( disabled );
13636      },
13637  
13638      disable: function( index ) {
13639          var disabled = this.options.disabled;
13640          if ( disabled === true ) {
13641              return;
13642          }
13643  
13644          if ( index === undefined ) {
13645              disabled = true;
13646          } else {
13647              index = this._getIndex( index );
13648              if ( $.inArray( index, disabled ) !== -1 ) {
13649                  return;
13650              }
13651              if ( $.isArray( disabled ) ) {
13652                  disabled = $.merge( [ index ], disabled ).sort();
13653              } else {
13654                  disabled = [ index ];
13655              }
13656          }
13657          this._setupDisabled( disabled );
13658      },
13659  
13660      load: function( index, event ) {
13661          index = this._getIndex( index );
13662          var that = this,
13663              tab = this.tabs.eq( index ),
13664              anchor = tab.find( ".ui-tabs-anchor" ),
13665              panel = this._getPanelForTab( tab ),
13666              eventData = {
13667                  tab: tab,
13668                  panel: panel
13669              },
13670              complete = function( jqXHR, status ) {
13671                  if ( status === "abort" ) {
13672                      that.panels.stop( false, true );
13673                  }
13674  
13675                  tab.removeClass( "ui-tabs-loading" );
13676                  panel.removeAttr( "aria-busy" );
13677  
13678                  if ( jqXHR === that.xhr ) {
13679                      delete that.xhr;
13680                  }
13681              };
13682  
13683          // not remote
13684          if ( this._isLocal( anchor[ 0 ] ) ) {
13685              return;
13686          }
13687  
13688          this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
13689  
13690          // support: jQuery <1.8
13691          // jQuery <1.8 returns false if the request is canceled in beforeSend,
13692          // but as of 1.8, $.ajax() always returns a jqXHR object.
13693          if ( this.xhr && this.xhr.statusText !== "canceled" ) {
13694              tab.addClass( "ui-tabs-loading" );
13695              panel.attr( "aria-busy", "true" );
13696  
13697              this.xhr
13698                  .done(function( response, status, jqXHR ) {
13699                      // support: jQuery <1.8
13700                      // http://bugs.jquery.com/ticket/11778
13701                      setTimeout(function() {
13702                          panel.html( response );
13703                          that._trigger( "load", event, eventData );
13704  
13705                          complete( jqXHR, status );
13706                      }, 1 );
13707                  })
13708                  .fail(function( jqXHR, status ) {
13709                      // support: jQuery <1.8
13710                      // http://bugs.jquery.com/ticket/11778
13711                      setTimeout(function() {
13712                          complete( jqXHR, status );
13713                      }, 1 );
13714                  });
13715          }
13716      },
13717  
13718      _ajaxSettings: function( anchor, event, eventData ) {
13719          var that = this;
13720          return {
13721              url: anchor.attr( "href" ),
13722              beforeSend: function( jqXHR, settings ) {
13723                  return that._trigger( "beforeLoad", event,
13724                      $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
13725              }
13726          };
13727      },
13728  
13729      _getPanelForTab: function( tab ) {
13730          var id = $( tab ).attr( "aria-controls" );
13731          return this.element.find( this._sanitizeSelector( "#" + id ) );
13732      }
13733  });
13734  
13735  
13736  /*!
13737   * jQuery UI Tooltip 1.11.4
13738   * http://jqueryui.com
13739   *
13740   * Copyright jQuery Foundation and other contributors
13741   * Released under the MIT license.
13742   * http://jquery.org/license
13743   *
13744   * http://api.jqueryui.com/tooltip/
13745   */
13746  
13747  
13748  var tooltip = $.widget( "ui.tooltip", {
13749      version: "1.11.4",
13750      options: {
13751          content: function() {
13752              // support: IE<9, Opera in jQuery <1.7
13753              // .text() can't accept undefined, so coerce to a string
13754              var title = $( this ).attr( "title" ) || "";
13755              // Escape title, since we're going from an attribute to raw HTML
13756              return $( "<a>" ).text( title ).html();
13757          },
13758          hide: true,
13759          // Disabled elements have inconsistent behavior across browsers (#8661)
13760          items: "[title]:not([disabled])",
13761          position: {
13762              my: "left top+15",
13763              at: "left bottom",
13764              collision: "flipfit flip"
13765          },
13766          show: true,
13767          tooltipClass: null,
13768          track: false,
13769  
13770          // callbacks
13771          close: null,
13772          open: null
13773      },
13774  
13775      _addDescribedBy: function( elem, id ) {
13776          var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
13777          describedby.push( id );
13778          elem
13779              .data( "ui-tooltip-id", id )
13780              .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
13781      },
13782  
13783      _removeDescribedBy: function( elem ) {
13784          var id = elem.data( "ui-tooltip-id" ),
13785              describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
13786              index = $.inArray( id, describedby );
13787  
13788          if ( index !== -1 ) {
13789              describedby.splice( index, 1 );
13790          }
13791  
13792          elem.removeData( "ui-tooltip-id" );
13793          describedby = $.trim( describedby.join( " " ) );
13794          if ( describedby ) {
13795              elem.attr( "aria-describedby", describedby );
13796          } else {
13797              elem.removeAttr( "aria-describedby" );
13798          }
13799      },
13800  
13801      _create: function() {
13802          this._on({
13803              mouseover: "open",
13804              focusin: "open"
13805          });
13806  
13807          // IDs of generated tooltips, needed for destroy
13808          this.tooltips = {};
13809  
13810          // IDs of parent tooltips where we removed the title attribute
13811          this.parents = {};
13812  
13813          if ( this.options.disabled ) {
13814              this._disable();
13815          }
13816  
13817          // Append the aria-live region so tooltips announce correctly
13818          this.liveRegion = $( "<div>" )
13819              .attr({
13820                  role: "log",
13821                  "aria-live": "assertive",
13822                  "aria-relevant": "additions"
13823              })
13824              .addClass( "ui-helper-hidden-accessible" )
13825              .appendTo( this.document[ 0 ].body );
13826      },
13827  
13828      _setOption: function( key, value ) {
13829          var that = this;
13830  
13831          if ( key === "disabled" ) {
13832              this[ value ? "_disable" : "_enable" ]();
13833              this.options[ key ] = value;
13834              // disable element style changes
13835              return;
13836          }
13837  
13838          this._super( key, value );
13839  
13840          if ( key === "content" ) {
13841              $.each( this.tooltips, function( id, tooltipData ) {
13842                  that._updateContent( tooltipData.element );
13843              });
13844          }
13845      },
13846  
13847      _disable: function() {
13848          var that = this;
13849  
13850          // close open tooltips
13851          $.each( this.tooltips, function( id, tooltipData ) {
13852              var event = $.Event( "blur" );
13853              event.target = event.currentTarget = tooltipData.element[ 0 ];
13854              that.close( event, true );
13855          });
13856  
13857          // remove title attributes to prevent native tooltips
13858          this.element.find( this.options.items ).addBack().each(function() {
13859              var element = $( this );
13860              if ( element.is( "[title]" ) ) {
13861                  element
13862                      .data( "ui-tooltip-title", element.attr( "title" ) )
13863                      .removeAttr( "title" );
13864              }
13865          });
13866      },
13867  
13868      _enable: function() {
13869          // restore title attributes
13870          this.element.find( this.options.items ).addBack().each(function() {
13871              var element = $( this );
13872              if ( element.data( "ui-tooltip-title" ) ) {
13873                  element.attr( "title", element.data( "ui-tooltip-title" ) );
13874              }
13875          });
13876      },
13877  
13878      open: function( event ) {
13879          var that = this,
13880              target = $( event ? event.target : this.element )
13881                  // we need closest here due to mouseover bubbling,
13882                  // but always pointing at the same event target
13883                  .closest( this.options.items );
13884  
13885          // No element to show a tooltip for or the tooltip is already open
13886          if ( !target.length || target.data( "ui-tooltip-id" ) ) {
13887              return;
13888          }
13889  
13890          if ( target.attr( "title" ) ) {
13891              target.data( "ui-tooltip-title", target.attr( "title" ) );
13892          }
13893  
13894          target.data( "ui-tooltip-open", true );
13895  
13896          // kill parent tooltips, custom or native, for hover
13897          if ( event && event.type === "mouseover" ) {
13898              target.parents().each(function() {
13899                  var parent = $( this ),
13900                      blurEvent;
13901                  if ( parent.data( "ui-tooltip-open" ) ) {
13902                      blurEvent = $.Event( "blur" );
13903                      blurEvent.target = blurEvent.currentTarget = this;
13904                      that.close( blurEvent, true );
13905                  }
13906                  if ( parent.attr( "title" ) ) {
13907                      parent.uniqueId();
13908                      that.parents[ this.id ] = {
13909                          element: this,
13910                          title: parent.attr( "title" )
13911                      };
13912                      parent.attr( "title", "" );
13913                  }
13914              });
13915          }
13916  
13917          this._registerCloseHandlers( event, target );
13918          this._updateContent( target, event );
13919      },
13920  
13921      _updateContent: function( target, event ) {
13922          var content,
13923              contentOption = this.options.content,
13924              that = this,
13925              eventType = event ? event.type : null;
13926  
13927          if ( typeof contentOption === "string" ) {
13928              return this._open( event, target, contentOption );
13929          }
13930  
13931          content = contentOption.call( target[0], function( response ) {
13932  
13933              // IE may instantly serve a cached response for ajax requests
13934              // delay this call to _open so the other call to _open runs first
13935              that._delay(function() {
13936  
13937                  // Ignore async response if tooltip was closed already
13938                  if ( !target.data( "ui-tooltip-open" ) ) {
13939                      return;
13940                  }
13941  
13942                  // jQuery creates a special event for focusin when it doesn't
13943                  // exist natively. To improve performance, the native event
13944                  // object is reused and the type is changed. Therefore, we can't
13945                  // rely on the type being correct after the event finished
13946                  // bubbling, so we set it back to the previous value. (#8740)
13947                  if ( event ) {
13948                      event.type = eventType;
13949                  }
13950                  this._open( event, target, response );
13951              });
13952          });
13953          if ( content ) {
13954              this._open( event, target, content );
13955          }
13956      },
13957  
13958      _open: function( event, target, content ) {
13959          var tooltipData, tooltip, delayedShow, a11yContent,
13960              positionOption = $.extend( {}, this.options.position );
13961  
13962          if ( !content ) {
13963              return;
13964          }
13965  
13966          // Content can be updated multiple times. If the tooltip already
13967          // exists, then just update the content and bail.
13968          tooltipData = this._find( target );
13969          if ( tooltipData ) {
13970              tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
13971              return;
13972          }
13973  
13974          // if we have a title, clear it to prevent the native tooltip
13975          // we have to check first to avoid defining a title if none exists
13976          // (we don't want to cause an element to start matching [title])
13977          //
13978          // We use removeAttr only for key events, to allow IE to export the correct
13979          // accessible attributes. For mouse events, set to empty string to avoid
13980          // native tooltip showing up (happens only when removing inside mouseover).
13981          if ( target.is( "[title]" ) ) {
13982              if ( event && event.type === "mouseover" ) {
13983                  target.attr( "title", "" );
13984              } else {
13985                  target.removeAttr( "title" );
13986              }
13987          }
13988  
13989          tooltipData = this._tooltip( target );
13990          tooltip = tooltipData.tooltip;
13991          this._addDescribedBy( target, tooltip.attr( "id" ) );
13992          tooltip.find( ".ui-tooltip-content" ).html( content );
13993  
13994          // Support: Voiceover on OS X, JAWS on IE <= 9
13995          // JAWS announces deletions even when aria-relevant="additions"
13996          // Voiceover will sometimes re-read the entire log region's contents from the beginning
13997          this.liveRegion.children().hide();
13998          if ( content.clone ) {
13999              a11yContent = content.clone();
14000              a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
14001          } else {
14002              a11yContent = content;
14003          }
14004          $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
14005  
14006  		function position( event ) {
14007              positionOption.of = event;
14008              if ( tooltip.is( ":hidden" ) ) {
14009                  return;
14010              }
14011              tooltip.position( positionOption );
14012          }
14013          if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14014              this._on( this.document, {
14015                  mousemove: position
14016              });
14017              // trigger once to override element-relative positioning
14018              position( event );
14019          } else {
14020              tooltip.position( $.extend({
14021                  of: target
14022              }, this.options.position ) );
14023          }
14024  
14025          tooltip.hide();
14026  
14027          this._show( tooltip, this.options.show );
14028          // Handle tracking tooltips that are shown with a delay (#8644). As soon
14029          // as the tooltip is visible, position the tooltip using the most recent
14030          // event.
14031          if ( this.options.show && this.options.show.delay ) {
14032              delayedShow = this.delayedShow = setInterval(function() {
14033                  if ( tooltip.is( ":visible" ) ) {
14034                      position( positionOption.of );
14035                      clearInterval( delayedShow );
14036                  }
14037              }, $.fx.interval );
14038          }
14039  
14040          this._trigger( "open", event, { tooltip: tooltip } );
14041      },
14042  
14043      _registerCloseHandlers: function( event, target ) {
14044          var events = {
14045              keyup: function( event ) {
14046                  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14047                      var fakeEvent = $.Event(event);
14048                      fakeEvent.currentTarget = target[0];
14049                      this.close( fakeEvent, true );
14050                  }
14051              }
14052          };
14053  
14054          // Only bind remove handler for delegated targets. Non-delegated
14055          // tooltips will handle this in destroy.
14056          if ( target[ 0 ] !== this.element[ 0 ] ) {
14057              events.remove = function() {
14058                  this._removeTooltip( this._find( target ).tooltip );
14059              };
14060          }
14061  
14062          if ( !event || event.type === "mouseover" ) {
14063              events.mouseleave = "close";
14064          }
14065          if ( !event || event.type === "focusin" ) {
14066              events.focusout = "close";
14067          }
14068          this._on( true, target, events );
14069      },
14070  
14071      close: function( event ) {
14072          var tooltip,
14073              that = this,
14074              target = $( event ? event.currentTarget : this.element ),
14075              tooltipData = this._find( target );
14076  
14077          // The tooltip may already be closed
14078          if ( !tooltipData ) {
14079  
14080              // We set ui-tooltip-open immediately upon open (in open()), but only set the
14081              // additional data once there's actually content to show (in _open()). So even if the
14082              // tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
14083              // the period between open() and _open().
14084              target.removeData( "ui-tooltip-open" );
14085              return;
14086          }
14087  
14088          tooltip = tooltipData.tooltip;
14089  
14090          // disabling closes the tooltip, so we need to track when we're closing
14091          // to avoid an infinite loop in case the tooltip becomes disabled on close
14092          if ( tooltipData.closing ) {
14093              return;
14094          }
14095  
14096          // Clear the interval for delayed tracking tooltips
14097          clearInterval( this.delayedShow );
14098  
14099          // only set title if we had one before (see comment in _open())
14100          // If the title attribute has changed since open(), don't restore
14101          if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
14102              target.attr( "title", target.data( "ui-tooltip-title" ) );
14103          }
14104  
14105          this._removeDescribedBy( target );
14106  
14107          tooltipData.hiding = true;
14108          tooltip.stop( true );
14109          this._hide( tooltip, this.options.hide, function() {
14110              that._removeTooltip( $( this ) );
14111          });
14112  
14113          target.removeData( "ui-tooltip-open" );
14114          this._off( target, "mouseleave focusout keyup" );
14115  
14116          // Remove 'remove' binding only on delegated targets
14117          if ( target[ 0 ] !== this.element[ 0 ] ) {
14118              this._off( target, "remove" );
14119          }
14120          this._off( this.document, "mousemove" );
14121  
14122          if ( event && event.type === "mouseleave" ) {
14123              $.each( this.parents, function( id, parent ) {
14124                  $( parent.element ).attr( "title", parent.title );
14125                  delete that.parents[ id ];
14126              });
14127          }
14128  
14129          tooltipData.closing = true;
14130          this._trigger( "close", event, { tooltip: tooltip } );
14131          if ( !tooltipData.hiding ) {
14132              tooltipData.closing = false;
14133          }
14134      },
14135  
14136      _tooltip: function( element ) {
14137          var tooltip = $( "<div>" )
14138                  .attr( "role", "tooltip" )
14139                  .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14140                      ( this.options.tooltipClass || "" ) ),
14141              id = tooltip.uniqueId().attr( "id" );
14142  
14143          $( "<div>" )
14144              .addClass( "ui-tooltip-content" )
14145              .appendTo( tooltip );
14146  
14147          tooltip.appendTo( this.document[0].body );
14148  
14149          return this.tooltips[ id ] = {
14150              element: element,
14151              tooltip: tooltip
14152          };
14153      },
14154  
14155      _find: function( target ) {
14156          var id = target.data( "ui-tooltip-id" );
14157          return id ? this.tooltips[ id ] : null;
14158      },
14159  
14160      _removeTooltip: function( tooltip ) {
14161          tooltip.remove();
14162          delete this.tooltips[ tooltip.attr( "id" ) ];
14163      },
14164  
14165      _destroy: function() {
14166          var that = this;
14167  
14168          // close open tooltips
14169          $.each( this.tooltips, function( id, tooltipData ) {
14170              // Delegate to close method to handle common cleanup
14171              var event = $.Event( "blur" ),
14172                  element = tooltipData.element;
14173              event.target = event.currentTarget = element[ 0 ];
14174              that.close( event, true );
14175  
14176              // Remove immediately; destroying an open tooltip doesn't use the
14177              // hide animation
14178              $( "#" + id ).remove();
14179  
14180              // Restore the title
14181              if ( element.data( "ui-tooltip-title" ) ) {
14182                  // If the title attribute has changed since open(), don't restore
14183                  if ( !element.attr( "title" ) ) {
14184                      element.attr( "title", element.data( "ui-tooltip-title" ) );
14185                  }
14186                  element.removeData( "ui-tooltip-title" );
14187              }
14188          });
14189          this.liveRegion.remove();
14190      }
14191  });
14192  
14193  
14194  /*!
14195   * jQuery UI Effects 1.11.4
14196   * http://jqueryui.com
14197   *
14198   * Copyright jQuery Foundation and other contributors
14199   * Released under the MIT license.
14200   * http://jquery.org/license
14201   *
14202   * http://api.jqueryui.com/category/effects-core/
14203   */
14204  
14205  
14206  var dataSpace = "ui-effects-",
14207  
14208      // Create a local jQuery because jQuery Color relies on it and the
14209      // global may not exist with AMD and a custom build (#10199)
14210      jQuery = $;
14211  
14212  $.effects = {
14213      effect: {}
14214  };
14215  
14216  /*!
14217   * jQuery Color Animations v2.1.2
14218   * https://github.com/jquery/jquery-color
14219   *
14220   * Copyright 2014 jQuery Foundation and other contributors
14221   * Released under the MIT license.
14222   * http://jquery.org/license
14223   *
14224   * Date: Wed Jan 16 08:47:09 2013 -0600
14225   */
14226  (function( jQuery, undefined ) {
14227  
14228      var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
14229  
14230      // plusequals test for += 100 -= 100
14231      rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
14232      // a set of RE's that can match strings and generate color tuples.
14233      stringParsers = [ {
14234              re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14235              parse: function( execResult ) {
14236                  return [
14237                      execResult[ 1 ],
14238                      execResult[ 2 ],
14239                      execResult[ 3 ],
14240                      execResult[ 4 ]
14241                  ];
14242              }
14243          }, {
14244              re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14245              parse: function( execResult ) {
14246                  return [
14247                      execResult[ 1 ] * 2.55,
14248                      execResult[ 2 ] * 2.55,
14249                      execResult[ 3 ] * 2.55,
14250                      execResult[ 4 ]
14251                  ];
14252              }
14253          }, {
14254              // this regex ignores A-F because it's compared against an already lowercased string
14255              re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
14256              parse: function( execResult ) {
14257                  return [
14258                      parseInt( execResult[ 1 ], 16 ),
14259                      parseInt( execResult[ 2 ], 16 ),
14260                      parseInt( execResult[ 3 ], 16 )
14261                  ];
14262              }
14263          }, {
14264              // this regex ignores A-F because it's compared against an already lowercased string
14265              re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
14266              parse: function( execResult ) {
14267                  return [
14268                      parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
14269                      parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
14270                      parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
14271                  ];
14272              }
14273          }, {
14274              re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
14275              space: "hsla",
14276              parse: function( execResult ) {
14277                  return [
14278                      execResult[ 1 ],
14279                      execResult[ 2 ] / 100,
14280                      execResult[ 3 ] / 100,
14281                      execResult[ 4 ]
14282                  ];
14283              }
14284          } ],
14285  
14286      // jQuery.Color( )
14287      color = jQuery.Color = function( color, green, blue, alpha ) {
14288          return new jQuery.Color.fn.parse( color, green, blue, alpha );
14289      },
14290      spaces = {
14291          rgba: {
14292              props: {
14293                  red: {
14294                      idx: 0,
14295                      type: "byte"
14296                  },
14297                  green: {
14298                      idx: 1,
14299                      type: "byte"
14300                  },
14301                  blue: {
14302                      idx: 2,
14303                      type: "byte"
14304                  }
14305              }
14306          },
14307  
14308          hsla: {
14309              props: {
14310                  hue: {
14311                      idx: 0,
14312                      type: "degrees"
14313                  },
14314                  saturation: {
14315                      idx: 1,
14316                      type: "percent"
14317                  },
14318                  lightness: {
14319                      idx: 2,
14320                      type: "percent"
14321                  }
14322              }
14323          }
14324      },
14325      propTypes = {
14326          "byte": {
14327              floor: true,
14328              max: 255
14329          },
14330          "percent": {
14331              max: 1
14332          },
14333          "degrees": {
14334              mod: 360,
14335              floor: true
14336          }
14337      },
14338      support = color.support = {},
14339  
14340      // element for support tests
14341      supportElem = jQuery( "<p>" )[ 0 ],
14342  
14343      // colors = jQuery.Color.names
14344      colors,
14345  
14346      // local aliases of functions called often
14347      each = jQuery.each;
14348  
14349  // determine rgba support immediately
14350  supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
14351  support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
14352  
14353  // define cache name and alpha properties
14354  // for rgba and hsla spaces
14355  each( spaces, function( spaceName, space ) {
14356      space.cache = "_" + spaceName;
14357      space.props.alpha = {
14358          idx: 3,
14359          type: "percent",
14360          def: 1
14361      };
14362  });
14363  
14364  function clamp( value, prop, allowEmpty ) {
14365      var type = propTypes[ prop.type ] || {};
14366  
14367      if ( value == null ) {
14368          return (allowEmpty || !prop.def) ? null : prop.def;
14369      }
14370  
14371      // ~~ is an short way of doing floor for positive numbers
14372      value = type.floor ? ~~value : parseFloat( value );
14373  
14374      // IE will pass in empty strings as value for alpha,
14375      // which will hit this case
14376      if ( isNaN( value ) ) {
14377          return prop.def;
14378      }
14379  
14380      if ( type.mod ) {
14381          // we add mod before modding to make sure that negatives values
14382          // get converted properly: -10 -> 350
14383          return (value + type.mod) % type.mod;
14384      }
14385  
14386      // for now all property types without mod have min and max
14387      return 0 > value ? 0 : type.max < value ? type.max : value;
14388  }
14389  
14390  function stringParse( string ) {
14391      var inst = color(),
14392          rgba = inst._rgba = [];
14393  
14394      string = string.toLowerCase();
14395  
14396      each( stringParsers, function( i, parser ) {
14397          var parsed,
14398              match = parser.re.exec( string ),
14399              values = match && parser.parse( match ),
14400              spaceName = parser.space || "rgba";
14401  
14402          if ( values ) {
14403              parsed = inst[ spaceName ]( values );
14404  
14405              // if this was an rgba parse the assignment might happen twice
14406              // oh well....
14407              inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
14408              rgba = inst._rgba = parsed._rgba;
14409  
14410              // exit each( stringParsers ) here because we matched
14411              return false;
14412          }
14413      });
14414  
14415      // Found a stringParser that handled it
14416      if ( rgba.length ) {
14417  
14418          // if this came from a parsed string, force "transparent" when alpha is 0
14419          // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
14420          if ( rgba.join() === "0,0,0,0" ) {
14421              jQuery.extend( rgba, colors.transparent );
14422          }
14423          return inst;
14424      }
14425  
14426      // named colors
14427      return colors[ string ];
14428  }
14429  
14430  color.fn = jQuery.extend( color.prototype, {
14431      parse: function( red, green, blue, alpha ) {
14432          if ( red === undefined ) {
14433              this._rgba = [ null, null, null, null ];
14434              return this;
14435          }
14436          if ( red.jquery || red.nodeType ) {
14437              red = jQuery( red ).css( green );
14438              green = undefined;
14439          }
14440  
14441          var inst = this,
14442              type = jQuery.type( red ),
14443              rgba = this._rgba = [];
14444  
14445          // more than 1 argument specified - assume ( red, green, blue, alpha )
14446          if ( green !== undefined ) {
14447              red = [ red, green, blue, alpha ];
14448              type = "array";
14449          }
14450  
14451          if ( type === "string" ) {
14452              return this.parse( stringParse( red ) || colors._default );
14453          }
14454  
14455          if ( type === "array" ) {
14456              each( spaces.rgba.props, function( key, prop ) {
14457                  rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
14458              });
14459              return this;
14460          }
14461  
14462          if ( type === "object" ) {
14463              if ( red instanceof color ) {
14464                  each( spaces, function( spaceName, space ) {
14465                      if ( red[ space.cache ] ) {
14466                          inst[ space.cache ] = red[ space.cache ].slice();
14467                      }
14468                  });
14469              } else {
14470                  each( spaces, function( spaceName, space ) {
14471                      var cache = space.cache;
14472                      each( space.props, function( key, prop ) {
14473  
14474                          // if the cache doesn't exist, and we know how to convert
14475                          if ( !inst[ cache ] && space.to ) {
14476  
14477                              // if the value was null, we don't need to copy it
14478                              // if the key was alpha, we don't need to copy it either
14479                              if ( key === "alpha" || red[ key ] == null ) {
14480                                  return;
14481                              }
14482                              inst[ cache ] = space.to( inst._rgba );
14483                          }
14484  
14485                          // this is the only case where we allow nulls for ALL properties.
14486                          // call clamp with alwaysAllowEmpty
14487                          inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
14488                      });
14489  
14490                      // everything defined but alpha?
14491                      if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
14492                          // use the default of 1
14493                          inst[ cache ][ 3 ] = 1;
14494                          if ( space.from ) {
14495                              inst._rgba = space.from( inst[ cache ] );
14496                          }
14497                      }
14498                  });
14499              }
14500              return this;
14501          }
14502      },
14503      is: function( compare ) {
14504          var is = color( compare ),
14505              same = true,
14506              inst = this;
14507  
14508          each( spaces, function( _, space ) {
14509              var localCache,
14510                  isCache = is[ space.cache ];
14511              if (isCache) {
14512                  localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
14513                  each( space.props, function( _, prop ) {
14514                      if ( isCache[ prop.idx ] != null ) {
14515                          same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
14516                          return same;
14517                      }
14518                  });
14519              }
14520              return same;
14521          });
14522          return same;
14523      },
14524      _space: function() {
14525          var used = [],
14526              inst = this;
14527          each( spaces, function( spaceName, space ) {
14528              if ( inst[ space.cache ] ) {
14529                  used.push( spaceName );
14530              }
14531          });
14532          return used.pop();
14533      },
14534      transition: function( other, distance ) {
14535          var end = color( other ),
14536              spaceName = end._space(),
14537              space = spaces[ spaceName ],
14538              startColor = this.alpha() === 0 ? color( "transparent" ) : this,
14539              start = startColor[ space.cache ] || space.to( startColor._rgba ),
14540              result = start.slice();
14541  
14542          end = end[ space.cache ];
14543          each( space.props, function( key, prop ) {
14544              var index = prop.idx,
14545                  startValue = start[ index ],
14546                  endValue = end[ index ],
14547                  type = propTypes[ prop.type ] || {};
14548  
14549              // if null, don't override start value
14550              if ( endValue === null ) {
14551                  return;
14552              }
14553              // if null - use end
14554              if ( startValue === null ) {
14555                  result[ index ] = endValue;
14556              } else {
14557                  if ( type.mod ) {
14558                      if ( endValue - startValue > type.mod / 2 ) {
14559                          startValue += type.mod;
14560                      } else if ( startValue - endValue > type.mod / 2 ) {
14561                          startValue -= type.mod;
14562                      }
14563                  }
14564                  result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
14565              }
14566          });
14567          return this[ spaceName ]( result );
14568      },
14569      blend: function( opaque ) {
14570          // if we are already opaque - return ourself
14571          if ( this._rgba[ 3 ] === 1 ) {
14572              return this;
14573          }
14574  
14575          var rgb = this._rgba.slice(),
14576              a = rgb.pop(),
14577              blend = color( opaque )._rgba;
14578  
14579          return color( jQuery.map( rgb, function( v, i ) {
14580              return ( 1 - a ) * blend[ i ] + a * v;
14581          }));
14582      },
14583      toRgbaString: function() {
14584          var prefix = "rgba(",
14585              rgba = jQuery.map( this._rgba, function( v, i ) {
14586                  return v == null ? ( i > 2 ? 1 : 0 ) : v;
14587              });
14588  
14589          if ( rgba[ 3 ] === 1 ) {
14590              rgba.pop();
14591              prefix = "rgb(";
14592          }
14593  
14594          return prefix + rgba.join() + ")";
14595      },
14596      toHslaString: function() {
14597          var prefix = "hsla(",
14598              hsla = jQuery.map( this.hsla(), function( v, i ) {
14599                  if ( v == null ) {
14600                      v = i > 2 ? 1 : 0;
14601                  }
14602  
14603                  // catch 1 and 2
14604                  if ( i && i < 3 ) {
14605                      v = Math.round( v * 100 ) + "%";
14606                  }
14607                  return v;
14608              });
14609  
14610          if ( hsla[ 3 ] === 1 ) {
14611              hsla.pop();
14612              prefix = "hsl(";
14613          }
14614          return prefix + hsla.join() + ")";
14615      },
14616      toHexString: function( includeAlpha ) {
14617          var rgba = this._rgba.slice(),
14618              alpha = rgba.pop();
14619  
14620          if ( includeAlpha ) {
14621              rgba.push( ~~( alpha * 255 ) );
14622          }
14623  
14624          return "#" + jQuery.map( rgba, function( v ) {
14625  
14626              // default to 0 when nulls exist
14627              v = ( v || 0 ).toString( 16 );
14628              return v.length === 1 ? "0" + v : v;
14629          }).join("");
14630      },
14631      toString: function() {
14632          return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
14633      }
14634  });
14635  color.fn.parse.prototype = color.fn;
14636  
14637  // hsla conversions adapted from:
14638  // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
14639  
14640  function hue2rgb( p, q, h ) {
14641      h = ( h + 1 ) % 1;
14642      if ( h * 6 < 1 ) {
14643          return p + ( q - p ) * h * 6;
14644      }
14645      if ( h * 2 < 1) {
14646          return q;
14647      }
14648      if ( h * 3 < 2 ) {
14649          return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
14650      }
14651      return p;
14652  }
14653  
14654  spaces.hsla.to = function( rgba ) {
14655      if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
14656          return [ null, null, null, rgba[ 3 ] ];
14657      }
14658      var r = rgba[ 0 ] / 255,
14659          g = rgba[ 1 ] / 255,
14660          b = rgba[ 2 ] / 255,
14661          a = rgba[ 3 ],
14662          max = Math.max( r, g, b ),
14663          min = Math.min( r, g, b ),
14664          diff = max - min,
14665          add = max + min,
14666          l = add * 0.5,
14667          h, s;
14668  
14669      if ( min === max ) {
14670          h = 0;
14671      } else if ( r === max ) {
14672          h = ( 60 * ( g - b ) / diff ) + 360;
14673      } else if ( g === max ) {
14674          h = ( 60 * ( b - r ) / diff ) + 120;
14675      } else {
14676          h = ( 60 * ( r - g ) / diff ) + 240;
14677      }
14678  
14679      // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
14680      // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
14681      if ( diff === 0 ) {
14682          s = 0;
14683      } else if ( l <= 0.5 ) {
14684          s = diff / add;
14685      } else {
14686          s = diff / ( 2 - add );
14687      }
14688      return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
14689  };
14690  
14691  spaces.hsla.from = function( hsla ) {
14692      if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
14693          return [ null, null, null, hsla[ 3 ] ];
14694      }
14695      var h = hsla[ 0 ] / 360,
14696          s = hsla[ 1 ],
14697          l = hsla[ 2 ],
14698          a = hsla[ 3 ],
14699          q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
14700          p = 2 * l - q;
14701  
14702      return [
14703          Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
14704          Math.round( hue2rgb( p, q, h ) * 255 ),
14705          Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
14706          a
14707      ];
14708  };
14709  
14710  each( spaces, function( spaceName, space ) {
14711      var props = space.props,
14712          cache = space.cache,
14713          to = space.to,
14714          from = space.from;
14715  
14716      // makes rgba() and hsla()
14717      color.fn[ spaceName ] = function( value ) {
14718  
14719          // generate a cache for this space if it doesn't exist
14720          if ( to && !this[ cache ] ) {
14721              this[ cache ] = to( this._rgba );
14722          }
14723          if ( value === undefined ) {
14724              return this[ cache ].slice();
14725          }
14726  
14727          var ret,
14728              type = jQuery.type( value ),
14729              arr = ( type === "array" || type === "object" ) ? value : arguments,
14730              local = this[ cache ].slice();
14731  
14732          each( props, function( key, prop ) {
14733              var val = arr[ type === "object" ? key : prop.idx ];
14734              if ( val == null ) {
14735                  val = local[ prop.idx ];
14736              }
14737              local[ prop.idx ] = clamp( val, prop );
14738          });
14739  
14740          if ( from ) {
14741              ret = color( from( local ) );
14742              ret[ cache ] = local;
14743              return ret;
14744          } else {
14745              return color( local );
14746          }
14747      };
14748  
14749      // makes red() green() blue() alpha() hue() saturation() lightness()
14750      each( props, function( key, prop ) {
14751          // alpha is included in more than one space
14752          if ( color.fn[ key ] ) {
14753              return;
14754          }
14755          color.fn[ key ] = function( value ) {
14756              var vtype = jQuery.type( value ),
14757                  fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
14758                  local = this[ fn ](),
14759                  cur = local[ prop.idx ],
14760                  match;
14761  
14762              if ( vtype === "undefined" ) {
14763                  return cur;
14764              }
14765  
14766              if ( vtype === "function" ) {
14767                  value = value.call( this, cur );
14768                  vtype = jQuery.type( value );
14769              }
14770              if ( value == null && prop.empty ) {
14771                  return this;
14772              }
14773              if ( vtype === "string" ) {
14774                  match = rplusequals.exec( value );
14775                  if ( match ) {
14776                      value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
14777                  }
14778              }
14779              local[ prop.idx ] = value;
14780              return this[ fn ]( local );
14781          };
14782      });
14783  });
14784  
14785  // add cssHook and .fx.step function for each named hook.
14786  // accept a space separated string of properties
14787  color.hook = function( hook ) {
14788      var hooks = hook.split( " " );
14789      each( hooks, function( i, hook ) {
14790          jQuery.cssHooks[ hook ] = {
14791              set: function( elem, value ) {
14792                  var parsed, curElem,
14793                      backgroundColor = "";
14794  
14795                  if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
14796                      value = color( parsed || value );
14797                      if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
14798                          curElem = hook === "backgroundColor" ? elem.parentNode : elem;
14799                          while (
14800                              (backgroundColor === "" || backgroundColor === "transparent") &&
14801                              curElem && curElem.style
14802                          ) {
14803                              try {
14804                                  backgroundColor = jQuery.css( curElem, "backgroundColor" );
14805                                  curElem = curElem.parentNode;
14806                              } catch ( e ) {
14807                              }
14808                          }
14809  
14810                          value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
14811                              backgroundColor :
14812                              "_default" );
14813                      }
14814  
14815                      value = value.toRgbaString();
14816                  }
14817                  try {
14818                      elem.style[ hook ] = value;
14819                  } catch ( e ) {
14820                      // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
14821                  }
14822              }
14823          };
14824          jQuery.fx.step[ hook ] = function( fx ) {
14825              if ( !fx.colorInit ) {
14826                  fx.start = color( fx.elem, hook );
14827                  fx.end = color( fx.end );
14828                  fx.colorInit = true;
14829              }
14830              jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
14831          };
14832      });
14833  
14834  };
14835  
14836  color.hook( stepHooks );
14837  
14838  jQuery.cssHooks.borderColor = {
14839      expand: function( value ) {
14840          var expanded = {};
14841  
14842          each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
14843              expanded[ "border" + part + "Color" ] = value;
14844          });
14845          return expanded;
14846      }
14847  };
14848  
14849  // Basic color names only.
14850  // Usage of any of the other color names requires adding yourself or including
14851  // jquery.color.svg-names.js.
14852  colors = jQuery.Color.names = {
14853      // 4.1. Basic color keywords
14854      aqua: "#00ffff",
14855      black: "#000000",
14856      blue: "#0000ff",
14857      fuchsia: "#ff00ff",
14858      gray: "#808080",
14859      green: "#008000",
14860      lime: "#00ff00",
14861      maroon: "#800000",
14862      navy: "#000080",
14863      olive: "#808000",
14864      purple: "#800080",
14865      red: "#ff0000",
14866      silver: "#c0c0c0",
14867      teal: "#008080",
14868      white: "#ffffff",
14869      yellow: "#ffff00",
14870  
14871      // 4.2.3. "transparent" color keyword
14872      transparent: [ null, null, null, 0 ],
14873  
14874      _default: "#ffffff"
14875  };
14876  
14877  })( jQuery );
14878  
14879  /******************************************************************************/
14880  /****************************** CLASS ANIMATIONS ******************************/
14881  /******************************************************************************/
14882  (function() {
14883  
14884  var classAnimationActions = [ "add", "remove", "toggle" ],
14885      shorthandStyles = {
14886          border: 1,
14887          borderBottom: 1,
14888          borderColor: 1,
14889          borderLeft: 1,
14890          borderRight: 1,
14891          borderTop: 1,
14892          borderWidth: 1,
14893          margin: 1,
14894          padding: 1
14895      };
14896  
14897  $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
14898      $.fx.step[ prop ] = function( fx ) {
14899          if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
14900              jQuery.style( fx.elem, prop, fx.end );
14901              fx.setAttr = true;
14902          }
14903      };
14904  });
14905  
14906  function getElementStyles( elem ) {
14907      var key, len,
14908          style = elem.ownerDocument.defaultView ?
14909              elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
14910              elem.currentStyle,
14911          styles = {};
14912  
14913      if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
14914          len = style.length;
14915          while ( len-- ) {
14916              key = style[ len ];
14917              if ( typeof style[ key ] === "string" ) {
14918                  styles[ $.camelCase( key ) ] = style[ key ];
14919              }
14920          }
14921      // support: Opera, IE <9
14922      } else {
14923          for ( key in style ) {
14924              if ( typeof style[ key ] === "string" ) {
14925                  styles[ key ] = style[ key ];
14926              }
14927          }
14928      }
14929  
14930      return styles;
14931  }
14932  
14933  function styleDifference( oldStyle, newStyle ) {
14934      var diff = {},
14935          name, value;
14936  
14937      for ( name in newStyle ) {
14938          value = newStyle[ name ];
14939          if ( oldStyle[ name ] !== value ) {
14940              if ( !shorthandStyles[ name ] ) {
14941                  if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
14942                      diff[ name ] = value;
14943                  }
14944              }
14945          }
14946      }
14947  
14948      return diff;
14949  }
14950  
14951  // support: jQuery <1.8
14952  if ( !$.fn.addBack ) {
14953      $.fn.addBack = function( selector ) {
14954          return this.add( selector == null ?
14955              this.prevObject : this.prevObject.filter( selector )
14956          );
14957      };
14958  }
14959  
14960  $.effects.animateClass = function( value, duration, easing, callback ) {
14961      var o = $.speed( duration, easing, callback );
14962  
14963      return this.queue( function() {
14964          var animated = $( this ),
14965              baseClass = animated.attr( "class" ) || "",
14966              applyClassChange,
14967              allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
14968  
14969          // map the animated objects to store the original styles.
14970          allAnimations = allAnimations.map(function() {
14971              var el = $( this );
14972              return {
14973                  el: el,
14974                  start: getElementStyles( this )
14975              };
14976          });
14977  
14978          // apply class change
14979          applyClassChange = function() {
14980              $.each( classAnimationActions, function(i, action) {
14981                  if ( value[ action ] ) {
14982                      animated[ action + "Class" ]( value[ action ] );
14983                  }
14984              });
14985          };
14986          applyClassChange();
14987  
14988          // map all animated objects again - calculate new styles and diff
14989          allAnimations = allAnimations.map(function() {
14990              this.end = getElementStyles( this.el[ 0 ] );
14991              this.diff = styleDifference( this.start, this.end );
14992              return this;
14993          });
14994  
14995          // apply original class
14996          animated.attr( "class", baseClass );
14997  
14998          // map all animated objects again - this time collecting a promise
14999          allAnimations = allAnimations.map(function() {
15000              var styleInfo = this,
15001                  dfd = $.Deferred(),
15002                  opts = $.extend({}, o, {
15003                      queue: false,
15004                      complete: function() {
15005                          dfd.resolve( styleInfo );
15006                      }
15007                  });
15008  
15009              this.el.animate( this.diff, opts );
15010              return dfd.promise();
15011          });
15012  
15013          // once all animations have completed:
15014          $.when.apply( $, allAnimations.get() ).done(function() {
15015  
15016              // set the final class
15017              applyClassChange();
15018  
15019              // for each animated element,
15020              // clear all css properties that were animated
15021              $.each( arguments, function() {
15022                  var el = this.el;
15023                  $.each( this.diff, function(key) {
15024                      el.css( key, "" );
15025                  });
15026              });
15027  
15028              // this is guarnteed to be there if you use jQuery.speed()
15029              // it also handles dequeuing the next anim...
15030              o.complete.call( animated[ 0 ] );
15031          });
15032      });
15033  };
15034  
15035  $.fn.extend({
15036      addClass: (function( orig ) {
15037          return function( classNames, speed, easing, callback ) {
15038              return speed ?
15039                  $.effects.animateClass.call( this,
15040                      { add: classNames }, speed, easing, callback ) :
15041                  orig.apply( this, arguments );
15042          };
15043      })( $.fn.addClass ),
15044  
15045      removeClass: (function( orig ) {
15046          return function( classNames, speed, easing, callback ) {
15047              return arguments.length > 1 ?
15048                  $.effects.animateClass.call( this,
15049                      { remove: classNames }, speed, easing, callback ) :
15050                  orig.apply( this, arguments );
15051          };
15052      })( $.fn.removeClass ),
15053  
15054      toggleClass: (function( orig ) {
15055          return function( classNames, force, speed, easing, callback ) {
15056              if ( typeof force === "boolean" || force === undefined ) {
15057                  if ( !speed ) {
15058                      // without speed parameter
15059                      return orig.apply( this, arguments );
15060                  } else {
15061                      return $.effects.animateClass.call( this,
15062                          (force ? { add: classNames } : { remove: classNames }),
15063                          speed, easing, callback );
15064                  }
15065              } else {
15066                  // without force parameter
15067                  return $.effects.animateClass.call( this,
15068                      { toggle: classNames }, force, speed, easing );
15069              }
15070          };
15071      })( $.fn.toggleClass ),
15072  
15073      switchClass: function( remove, add, speed, easing, callback) {
15074          return $.effects.animateClass.call( this, {
15075              add: add,
15076              remove: remove
15077          }, speed, easing, callback );
15078      }
15079  });
15080  
15081  })();
15082  
15083  /******************************************************************************/
15084  /*********************************** EFFECTS **********************************/
15085  /******************************************************************************/
15086  
15087  (function() {
15088  
15089  $.extend( $.effects, {
15090      version: "1.11.4",
15091  
15092      // Saves a set of properties in a data storage
15093      save: function( element, set ) {
15094          for ( var i = 0; i < set.length; i++ ) {
15095              if ( set[ i ] !== null ) {
15096                  element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
15097              }
15098          }
15099      },
15100  
15101      // Restores a set of previously saved properties from a data storage
15102      restore: function( element, set ) {
15103          var val, i;
15104          for ( i = 0; i < set.length; i++ ) {
15105              if ( set[ i ] !== null ) {
15106                  val = element.data( dataSpace + set[ i ] );
15107                  // support: jQuery 1.6.2
15108                  // http://bugs.jquery.com/ticket/9917
15109                  // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
15110                  // We can't differentiate between "" and 0 here, so we just assume
15111                  // empty string since it's likely to be a more common value...
15112                  if ( val === undefined ) {
15113                      val = "";
15114                  }
15115                  element.css( set[ i ], val );
15116              }
15117          }
15118      },
15119  
15120      setMode: function( el, mode ) {
15121          if (mode === "toggle") {
15122              mode = el.is( ":hidden" ) ? "show" : "hide";
15123          }
15124          return mode;
15125      },
15126  
15127      // Translates a [top,left] array into a baseline value
15128      // this should be a little more flexible in the future to handle a string & hash
15129      getBaseline: function( origin, original ) {
15130          var y, x;
15131          switch ( origin[ 0 ] ) {
15132              case "top": y = 0; break;
15133              case "middle": y = 0.5; break;
15134              case "bottom": y = 1; break;
15135              default: y = origin[ 0 ] / original.height;
15136          }
15137          switch ( origin[ 1 ] ) {
15138              case "left": x = 0; break;
15139              case "center": x = 0.5; break;
15140              case "right": x = 1; break;
15141              default: x = origin[ 1 ] / original.width;
15142          }
15143          return {
15144              x: x,
15145              y: y
15146          };
15147      },
15148  
15149      // Wraps the element around a wrapper that copies position properties
15150      createWrapper: function( element ) {
15151  
15152          // if the element is already wrapped, return it
15153          if ( element.parent().is( ".ui-effects-wrapper" )) {
15154              return element.parent();
15155          }
15156  
15157          // wrap the element
15158          var props = {
15159                  width: element.outerWidth(true),
15160                  height: element.outerHeight(true),
15161                  "float": element.css( "float" )
15162              },
15163              wrapper = $( "<div></div>" )
15164                  .addClass( "ui-effects-wrapper" )
15165                  .css({
15166                      fontSize: "100%",
15167                      background: "transparent",
15168                      border: "none",
15169                      margin: 0,
15170                      padding: 0
15171                  }),
15172              // Store the size in case width/height are defined in % - Fixes #5245
15173              size = {
15174                  width: element.width(),
15175                  height: element.height()
15176              },
15177              active = document.activeElement;
15178  
15179          // support: Firefox
15180          // Firefox incorrectly exposes anonymous content
15181          // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
15182          try {
15183              active.id;
15184          } catch ( e ) {
15185              active = document.body;
15186          }
15187  
15188          element.wrap( wrapper );
15189  
15190          // Fixes #7595 - Elements lose focus when wrapped.
15191          if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15192              $( active ).focus();
15193          }
15194  
15195          wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
15196  
15197          // transfer positioning properties to the wrapper
15198          if ( element.css( "position" ) === "static" ) {
15199              wrapper.css({ position: "relative" });
15200              element.css({ position: "relative" });
15201          } else {
15202              $.extend( props, {
15203                  position: element.css( "position" ),
15204                  zIndex: element.css( "z-index" )
15205              });
15206              $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
15207                  props[ pos ] = element.css( pos );
15208                  if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
15209                      props[ pos ] = "auto";
15210                  }
15211              });
15212              element.css({
15213                  position: "relative",
15214                  top: 0,
15215                  left: 0,
15216                  right: "auto",
15217                  bottom: "auto"
15218              });
15219          }
15220          element.css(size);
15221  
15222          return wrapper.css( props ).show();
15223      },
15224  
15225      removeWrapper: function( element ) {
15226          var active = document.activeElement;
15227  
15228          if ( element.parent().is( ".ui-effects-wrapper" ) ) {
15229              element.parent().replaceWith( element );
15230  
15231              // Fixes #7595 - Elements lose focus when wrapped.
15232              if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
15233                  $( active ).focus();
15234              }
15235          }
15236  
15237          return element;
15238      },
15239  
15240      setTransition: function( element, list, factor, value ) {
15241          value = value || {};
15242          $.each( list, function( i, x ) {
15243              var unit = element.cssUnit( x );
15244              if ( unit[ 0 ] > 0 ) {
15245                  value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
15246              }
15247          });
15248          return value;
15249      }
15250  });
15251  
15252  // return an effect options object for the given parameters:
15253  function _normalizeArguments( effect, options, speed, callback ) {
15254  
15255      // allow passing all options as the first parameter
15256      if ( $.isPlainObject( effect ) ) {
15257          options = effect;
15258          effect = effect.effect;
15259      }
15260  
15261      // convert to an object
15262      effect = { effect: effect };
15263  
15264      // catch (effect, null, ...)
15265      if ( options == null ) {
15266          options = {};
15267      }
15268  
15269      // catch (effect, callback)
15270      if ( $.isFunction( options ) ) {
15271          callback = options;
15272          speed = null;
15273          options = {};
15274      }
15275  
15276      // catch (effect, speed, ?)
15277      if ( typeof options === "number" || $.fx.speeds[ options ] ) {
15278          callback = speed;
15279          speed = options;
15280          options = {};
15281      }
15282  
15283      // catch (effect, options, callback)
15284      if ( $.isFunction( speed ) ) {
15285          callback = speed;
15286          speed = null;
15287      }
15288  
15289      // add options to effect
15290      if ( options ) {
15291          $.extend( effect, options );
15292      }
15293  
15294      speed = speed || options.duration;
15295      effect.duration = $.fx.off ? 0 :
15296          typeof speed === "number" ? speed :
15297          speed in $.fx.speeds ? $.fx.speeds[ speed ] :
15298          $.fx.speeds._default;
15299  
15300      effect.complete = callback || options.complete;
15301  
15302      return effect;
15303  }
15304  
15305  function standardAnimationOption( option ) {
15306      // Valid standard speeds (nothing, number, named speed)
15307      if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
15308          return true;
15309      }
15310  
15311      // Invalid strings - treat as "normal" speed
15312      if ( typeof option === "string" && !$.effects.effect[ option ] ) {
15313          return true;
15314      }
15315  
15316      // Complete callback
15317      if ( $.isFunction( option ) ) {
15318          return true;
15319      }
15320  
15321      // Options hash (but not naming an effect)
15322      if ( typeof option === "object" && !option.effect ) {
15323          return true;
15324      }
15325  
15326      // Didn't match any standard API
15327      return false;
15328  }
15329  
15330  $.fn.extend({
15331      effect: function( /* effect, options, speed, callback */ ) {
15332          var args = _normalizeArguments.apply( this, arguments ),
15333              mode = args.mode,
15334              queue = args.queue,
15335              effectMethod = $.effects.effect[ args.effect ];
15336  
15337          if ( $.fx.off || !effectMethod ) {
15338              // delegate to the original method (e.g., .show()) if possible
15339              if ( mode ) {
15340                  return this[ mode ]( args.duration, args.complete );
15341              } else {
15342                  return this.each( function() {
15343                      if ( args.complete ) {
15344                          args.complete.call( this );
15345                      }
15346                  });
15347              }
15348          }
15349  
15350  		function run( next ) {
15351              var elem = $( this ),
15352                  complete = args.complete,
15353                  mode = args.mode;
15354  
15355  			function done() {
15356                  if ( $.isFunction( complete ) ) {
15357                      complete.call( elem[0] );
15358                  }
15359                  if ( $.isFunction( next ) ) {
15360                      next();
15361                  }
15362              }
15363  
15364              // If the element already has the correct final state, delegate to
15365              // the core methods so the internal tracking of "olddisplay" works.
15366              if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
15367                  elem[ mode ]();
15368                  done();
15369              } else {
15370                  effectMethod.call( elem[0], args, done );
15371              }
15372          }
15373  
15374          return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
15375      },
15376  
15377      show: (function( orig ) {
15378          return function( option ) {
15379              if ( standardAnimationOption( option ) ) {
15380                  return orig.apply( this, arguments );
15381              } else {
15382                  var args = _normalizeArguments.apply( this, arguments );
15383                  args.mode = "show";
15384                  return this.effect.call( this, args );
15385              }
15386          };
15387      })( $.fn.show ),
15388  
15389      hide: (function( orig ) {
15390          return function( option ) {
15391              if ( standardAnimationOption( option ) ) {
15392                  return orig.apply( this, arguments );
15393              } else {
15394                  var args = _normalizeArguments.apply( this, arguments );
15395                  args.mode = "hide";
15396                  return this.effect.call( this, args );
15397              }
15398          };
15399      })( $.fn.hide ),
15400  
15401      toggle: (function( orig ) {
15402          return function( option ) {
15403              if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
15404                  return orig.apply( this, arguments );
15405              } else {
15406                  var args = _normalizeArguments.apply( this, arguments );
15407                  args.mode = "toggle";
15408                  return this.effect.call( this, args );
15409              }
15410          };
15411      })( $.fn.toggle ),
15412  
15413      // helper functions
15414      cssUnit: function(key) {
15415          var style = this.css( key ),
15416              val = [];
15417  
15418          $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
15419              if ( style.indexOf( unit ) > 0 ) {
15420                  val = [ parseFloat( style ), unit ];
15421              }
15422          });
15423          return val;
15424      }
15425  });
15426  
15427  })();
15428  
15429  /******************************************************************************/
15430  /*********************************** EASING ***********************************/
15431  /******************************************************************************/
15432  
15433  (function() {
15434  
15435  // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
15436  
15437  var baseEasings = {};
15438  
15439  $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
15440      baseEasings[ name ] = function( p ) {
15441          return Math.pow( p, i + 2 );
15442      };
15443  });
15444  
15445  $.extend( baseEasings, {
15446      Sine: function( p ) {
15447          return 1 - Math.cos( p * Math.PI / 2 );
15448      },
15449      Circ: function( p ) {
15450          return 1 - Math.sqrt( 1 - p * p );
15451      },
15452      Elastic: function( p ) {
15453          return p === 0 || p === 1 ? p :
15454              -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
15455      },
15456      Back: function( p ) {
15457          return p * p * ( 3 * p - 2 );
15458      },
15459      Bounce: function( p ) {
15460          var pow2,
15461              bounce = 4;
15462  
15463          while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
15464          return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
15465      }
15466  });
15467  
15468  $.each( baseEasings, function( name, easeIn ) {
15469      $.easing[ "easeIn" + name ] = easeIn;
15470      $.easing[ "easeOut" + name ] = function( p ) {
15471          return 1 - easeIn( 1 - p );
15472      };
15473      $.easing[ "easeInOut" + name ] = function( p ) {
15474          return p < 0.5 ?
15475              easeIn( p * 2 ) / 2 :
15476              1 - easeIn( p * -2 + 2 ) / 2;
15477      };
15478  });
15479  
15480  })();
15481  
15482  var effect = $.effects;
15483  
15484  
15485  /*!
15486   * jQuery UI Effects Blind 1.11.4
15487   * http://jqueryui.com
15488   *
15489   * Copyright jQuery Foundation and other contributors
15490   * Released under the MIT license.
15491   * http://jquery.org/license
15492   *
15493   * http://api.jqueryui.com/blind-effect/
15494   */
15495  
15496  
15497  var effectBlind = $.effects.effect.blind = function( o, done ) {
15498      // Create element
15499      var el = $( this ),
15500          rvertical = /up|down|vertical/,
15501          rpositivemotion = /up|left|vertical|horizontal/,
15502          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15503          mode = $.effects.setMode( el, o.mode || "hide" ),
15504          direction = o.direction || "up",
15505          vertical = rvertical.test( direction ),
15506          ref = vertical ? "height" : "width",
15507          ref2 = vertical ? "top" : "left",
15508          motion = rpositivemotion.test( direction ),
15509          animation = {},
15510          show = mode === "show",
15511          wrapper, distance, margin;
15512  
15513      // if already wrapped, the wrapper's properties are my property. #6245
15514      if ( el.parent().is( ".ui-effects-wrapper" ) ) {
15515          $.effects.save( el.parent(), props );
15516      } else {
15517          $.effects.save( el, props );
15518      }
15519      el.show();
15520      wrapper = $.effects.createWrapper( el ).css({
15521          overflow: "hidden"
15522      });
15523  
15524      distance = wrapper[ ref ]();
15525      margin = parseFloat( wrapper.css( ref2 ) ) || 0;
15526  
15527      animation[ ref ] = show ? distance : 0;
15528      if ( !motion ) {
15529          el
15530              .css( vertical ? "bottom" : "right", 0 )
15531              .css( vertical ? "top" : "left", "auto" )
15532              .css({ position: "absolute" });
15533  
15534          animation[ ref2 ] = show ? margin : distance + margin;
15535      }
15536  
15537      // start at 0 if we are showing
15538      if ( show ) {
15539          wrapper.css( ref, 0 );
15540          if ( !motion ) {
15541              wrapper.css( ref2, margin + distance );
15542          }
15543      }
15544  
15545      // Animate
15546      wrapper.animate( animation, {
15547          duration: o.duration,
15548          easing: o.easing,
15549          queue: false,
15550          complete: function() {
15551              if ( mode === "hide" ) {
15552                  el.hide();
15553              }
15554              $.effects.restore( el, props );
15555              $.effects.removeWrapper( el );
15556              done();
15557          }
15558      });
15559  };
15560  
15561  
15562  /*!
15563   * jQuery UI Effects Bounce 1.11.4
15564   * http://jqueryui.com
15565   *
15566   * Copyright jQuery Foundation and other contributors
15567   * Released under the MIT license.
15568   * http://jquery.org/license
15569   *
15570   * http://api.jqueryui.com/bounce-effect/
15571   */
15572  
15573  
15574  var effectBounce = $.effects.effect.bounce = function( o, done ) {
15575      var el = $( this ),
15576          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15577  
15578          // defaults:
15579          mode = $.effects.setMode( el, o.mode || "effect" ),
15580          hide = mode === "hide",
15581          show = mode === "show",
15582          direction = o.direction || "up",
15583          distance = o.distance,
15584          times = o.times || 5,
15585  
15586          // number of internal animations
15587          anims = times * 2 + ( show || hide ? 1 : 0 ),
15588          speed = o.duration / anims,
15589          easing = o.easing,
15590  
15591          // utility:
15592          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15593          motion = ( direction === "up" || direction === "left" ),
15594          i,
15595          upAnim,
15596          downAnim,
15597  
15598          // we will need to re-assemble the queue to stack our animations in place
15599          queue = el.queue(),
15600          queuelen = queue.length;
15601  
15602      // Avoid touching opacity to prevent clearType and PNG issues in IE
15603      if ( show || hide ) {
15604          props.push( "opacity" );
15605      }
15606  
15607      $.effects.save( el, props );
15608      el.show();
15609      $.effects.createWrapper( el ); // Create Wrapper
15610  
15611      // default distance for the BIGGEST bounce is the outer Distance / 3
15612      if ( !distance ) {
15613          distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
15614      }
15615  
15616      if ( show ) {
15617          downAnim = { opacity: 1 };
15618          downAnim[ ref ] = 0;
15619  
15620          // if we are showing, force opacity 0 and set the initial position
15621          // then do the "first" animation
15622          el.css( "opacity", 0 )
15623              .css( ref, motion ? -distance * 2 : distance * 2 )
15624              .animate( downAnim, speed, easing );
15625      }
15626  
15627      // start at the smallest distance if we are hiding
15628      if ( hide ) {
15629          distance = distance / Math.pow( 2, times - 1 );
15630      }
15631  
15632      downAnim = {};
15633      downAnim[ ref ] = 0;
15634      // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
15635      for ( i = 0; i < times; i++ ) {
15636          upAnim = {};
15637          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15638  
15639          el.animate( upAnim, speed, easing )
15640              .animate( downAnim, speed, easing );
15641  
15642          distance = hide ? distance * 2 : distance / 2;
15643      }
15644  
15645      // Last Bounce when Hiding
15646      if ( hide ) {
15647          upAnim = { opacity: 0 };
15648          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15649  
15650          el.animate( upAnim, speed, easing );
15651      }
15652  
15653      el.queue(function() {
15654          if ( hide ) {
15655              el.hide();
15656          }
15657          $.effects.restore( el, props );
15658          $.effects.removeWrapper( el );
15659          done();
15660      });
15661  
15662      // inject all the animations we just queued to be first in line (after "inprogress")
15663      if ( queuelen > 1) {
15664          queue.splice.apply( queue,
15665              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
15666      }
15667      el.dequeue();
15668  
15669  };
15670  
15671  
15672  /*!
15673   * jQuery UI Effects Clip 1.11.4
15674   * http://jqueryui.com
15675   *
15676   * Copyright jQuery Foundation and other contributors
15677   * Released under the MIT license.
15678   * http://jquery.org/license
15679   *
15680   * http://api.jqueryui.com/clip-effect/
15681   */
15682  
15683  
15684  var effectClip = $.effects.effect.clip = function( o, done ) {
15685      // Create element
15686      var el = $( this ),
15687          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15688          mode = $.effects.setMode( el, o.mode || "hide" ),
15689          show = mode === "show",
15690          direction = o.direction || "vertical",
15691          vert = direction === "vertical",
15692          size = vert ? "height" : "width",
15693          position = vert ? "top" : "left",
15694          animation = {},
15695          wrapper, animate, distance;
15696  
15697      // Save & Show
15698      $.effects.save( el, props );
15699      el.show();
15700  
15701      // Create Wrapper
15702      wrapper = $.effects.createWrapper( el ).css({
15703          overflow: "hidden"
15704      });
15705      animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
15706      distance = animate[ size ]();
15707  
15708      // Shift
15709      if ( show ) {
15710          animate.css( size, 0 );
15711          animate.css( position, distance / 2 );
15712      }
15713  
15714      // Create Animation Object:
15715      animation[ size ] = show ? distance : 0;
15716      animation[ position ] = show ? 0 : distance / 2;
15717  
15718      // Animate
15719      animate.animate( animation, {
15720          queue: false,
15721          duration: o.duration,
15722          easing: o.easing,
15723          complete: function() {
15724              if ( !show ) {
15725                  el.hide();
15726              }
15727              $.effects.restore( el, props );
15728              $.effects.removeWrapper( el );
15729              done();
15730          }
15731      });
15732  
15733  };
15734  
15735  
15736  /*!
15737   * jQuery UI Effects Drop 1.11.4
15738   * http://jqueryui.com
15739   *
15740   * Copyright jQuery Foundation and other contributors
15741   * Released under the MIT license.
15742   * http://jquery.org/license
15743   *
15744   * http://api.jqueryui.com/drop-effect/
15745   */
15746  
15747  
15748  var effectDrop = $.effects.effect.drop = function( o, done ) {
15749  
15750      var el = $( this ),
15751          props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
15752          mode = $.effects.setMode( el, o.mode || "hide" ),
15753          show = mode === "show",
15754          direction = o.direction || "left",
15755          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15756          motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
15757          animation = {
15758              opacity: show ? 1 : 0
15759          },
15760          distance;
15761  
15762      // Adjust
15763      $.effects.save( el, props );
15764      el.show();
15765      $.effects.createWrapper( el );
15766  
15767      distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15768  
15769      if ( show ) {
15770          el
15771              .css( "opacity", 0 )
15772              .css( ref, motion === "pos" ? -distance : distance );
15773      }
15774  
15775      // Animation
15776      animation[ ref ] = ( show ?
15777          ( motion === "pos" ? "+=" : "-=" ) :
15778          ( motion === "pos" ? "-=" : "+=" ) ) +
15779          distance;
15780  
15781      // Animate
15782      el.animate( animation, {
15783          queue: false,
15784          duration: o.duration,
15785          easing: o.easing,
15786          complete: function() {
15787              if ( mode === "hide" ) {
15788                  el.hide();
15789              }
15790              $.effects.restore( el, props );
15791              $.effects.removeWrapper( el );
15792              done();
15793          }
15794      });
15795  };
15796  
15797  
15798  /*!
15799   * jQuery UI Effects Explode 1.11.4
15800   * http://jqueryui.com
15801   *
15802   * Copyright jQuery Foundation and other contributors
15803   * Released under the MIT license.
15804   * http://jquery.org/license
15805   *
15806   * http://api.jqueryui.com/explode-effect/
15807   */
15808  
15809  
15810  var effectExplode = $.effects.effect.explode = function( o, done ) {
15811  
15812      var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
15813          cells = rows,
15814          el = $( this ),
15815          mode = $.effects.setMode( el, o.mode || "hide" ),
15816          show = mode === "show",
15817  
15818          // show and then visibility:hidden the element before calculating offset
15819          offset = el.show().css( "visibility", "hidden" ).offset(),
15820  
15821          // width and height of a piece
15822          width = Math.ceil( el.outerWidth() / cells ),
15823          height = Math.ceil( el.outerHeight() / rows ),
15824          pieces = [],
15825  
15826          // loop
15827          i, j, left, top, mx, my;
15828  
15829      // children animate complete:
15830  	function childComplete() {
15831          pieces.push( this );
15832          if ( pieces.length === rows * cells ) {
15833              animComplete();
15834          }
15835      }
15836  
15837      // clone the element for each row and cell.
15838      for ( i = 0; i < rows ; i++ ) { // ===>
15839          top = offset.top + i * height;
15840          my = i - ( rows - 1 ) / 2 ;
15841  
15842          for ( j = 0; j < cells ; j++ ) { // |||
15843              left = offset.left + j * width;
15844              mx = j - ( cells - 1 ) / 2 ;
15845  
15846              // Create a clone of the now hidden main element that will be absolute positioned
15847              // within a wrapper div off the -left and -top equal to size of our pieces
15848              el
15849                  .clone()
15850                  .appendTo( "body" )
15851                  .wrap( "<div></div>" )
15852                  .css({
15853                      position: "absolute",
15854                      visibility: "visible",
15855                      left: -j * width,
15856                      top: -i * height
15857                  })
15858  
15859              // select the wrapper - make it overflow: hidden and absolute positioned based on
15860              // where the original was located +left and +top equal to the size of pieces
15861                  .parent()
15862                  .addClass( "ui-effects-explode" )
15863                  .css({
15864                      position: "absolute",
15865                      overflow: "hidden",
15866                      width: width,
15867                      height: height,
15868                      left: left + ( show ? mx * width : 0 ),
15869                      top: top + ( show ? my * height : 0 ),
15870                      opacity: show ? 0 : 1
15871                  }).animate({
15872                      left: left + ( show ? 0 : mx * width ),
15873                      top: top + ( show ? 0 : my * height ),
15874                      opacity: show ? 1 : 0
15875                  }, o.duration || 500, o.easing, childComplete );
15876          }
15877      }
15878  
15879  	function animComplete() {
15880          el.css({
15881              visibility: "visible"
15882          });
15883          $( pieces ).remove();
15884          if ( !show ) {
15885              el.hide();
15886          }
15887          done();
15888      }
15889  };
15890  
15891  
15892  /*!
15893   * jQuery UI Effects Fade 1.11.4
15894   * http://jqueryui.com
15895   *
15896   * Copyright jQuery Foundation and other contributors
15897   * Released under the MIT license.
15898   * http://jquery.org/license
15899   *
15900   * http://api.jqueryui.com/fade-effect/
15901   */
15902  
15903  
15904  var effectFade = $.effects.effect.fade = function( o, done ) {
15905      var el = $( this ),
15906          mode = $.effects.setMode( el, o.mode || "toggle" );
15907  
15908      el.animate({
15909          opacity: mode
15910      }, {
15911          queue: false,
15912          duration: o.duration,
15913          easing: o.easing,
15914          complete: done
15915      });
15916  };
15917  
15918  
15919  /*!
15920   * jQuery UI Effects Fold 1.11.4
15921   * http://jqueryui.com
15922   *
15923   * Copyright jQuery Foundation and other contributors
15924   * Released under the MIT license.
15925   * http://jquery.org/license
15926   *
15927   * http://api.jqueryui.com/fold-effect/
15928   */
15929  
15930  
15931  var effectFold = $.effects.effect.fold = function( o, done ) {
15932  
15933      // Create element
15934      var el = $( this ),
15935          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
15936          mode = $.effects.setMode( el, o.mode || "hide" ),
15937          show = mode === "show",
15938          hide = mode === "hide",
15939          size = o.size || 15,
15940          percent = /([0-9]+)%/.exec( size ),
15941          horizFirst = !!o.horizFirst,
15942          widthFirst = show !== horizFirst,
15943          ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
15944          duration = o.duration / 2,
15945          wrapper, distance,
15946          animation1 = {},
15947          animation2 = {};
15948  
15949      $.effects.save( el, props );
15950      el.show();
15951  
15952      // Create Wrapper
15953      wrapper = $.effects.createWrapper( el ).css({
15954          overflow: "hidden"
15955      });
15956      distance = widthFirst ?
15957          [ wrapper.width(), wrapper.height() ] :
15958          [ wrapper.height(), wrapper.width() ];
15959  
15960      if ( percent ) {
15961          size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15962      }
15963      if ( show ) {
15964          wrapper.css( horizFirst ? {
15965              height: 0,
15966              width: size
15967          } : {
15968              height: size,
15969              width: 0
15970          });
15971      }
15972  
15973      // Animation
15974      animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
15975      animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
15976  
15977      // Animate
15978      wrapper
15979          .animate( animation1, duration, o.easing )
15980          .animate( animation2, duration, o.easing, function() {
15981              if ( hide ) {
15982                  el.hide();
15983              }
15984              $.effects.restore( el, props );
15985              $.effects.removeWrapper( el );
15986              done();
15987          });
15988  
15989  };
15990  
15991  
15992  /*!
15993   * jQuery UI Effects Highlight 1.11.4
15994   * http://jqueryui.com
15995   *
15996   * Copyright jQuery Foundation and other contributors
15997   * Released under the MIT license.
15998   * http://jquery.org/license
15999   *
16000   * http://api.jqueryui.com/highlight-effect/
16001   */
16002  
16003  
16004  var effectHighlight = $.effects.effect.highlight = function( o, done ) {
16005      var elem = $( this ),
16006          props = [ "backgroundImage", "backgroundColor", "opacity" ],
16007          mode = $.effects.setMode( elem, o.mode || "show" ),
16008          animation = {
16009              backgroundColor: elem.css( "backgroundColor" )
16010          };
16011  
16012      if (mode === "hide") {
16013          animation.opacity = 0;
16014      }
16015  
16016      $.effects.save( elem, props );
16017  
16018      elem
16019          .show()
16020          .css({
16021              backgroundImage: "none",
16022              backgroundColor: o.color || "#ffff99"
16023          })
16024          .animate( animation, {
16025              queue: false,
16026              duration: o.duration,
16027              easing: o.easing,
16028              complete: function() {
16029                  if ( mode === "hide" ) {
16030                      elem.hide();
16031                  }
16032                  $.effects.restore( elem, props );
16033                  done();
16034              }
16035          });
16036  };
16037  
16038  
16039  /*!
16040   * jQuery UI Effects Size 1.11.4
16041   * http://jqueryui.com
16042   *
16043   * Copyright jQuery Foundation and other contributors
16044   * Released under the MIT license.
16045   * http://jquery.org/license
16046   *
16047   * http://api.jqueryui.com/size-effect/
16048   */
16049  
16050  
16051  var effectSize = $.effects.effect.size = function( o, done ) {
16052  
16053      // Create element
16054      var original, baseline, factor,
16055          el = $( this ),
16056          props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
16057  
16058          // Always restore
16059          props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
16060  
16061          // Copy for children
16062          props2 = [ "width", "height", "overflow" ],
16063          cProps = [ "fontSize" ],
16064          vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
16065          hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
16066  
16067          // Set options
16068          mode = $.effects.setMode( el, o.mode || "effect" ),
16069          restore = o.restore || mode !== "effect",
16070          scale = o.scale || "both",
16071          origin = o.origin || [ "middle", "center" ],
16072          position = el.css( "position" ),
16073          props = restore ? props0 : props1,
16074          zero = {
16075              height: 0,
16076              width: 0,
16077              outerHeight: 0,
16078              outerWidth: 0
16079          };
16080  
16081      if ( mode === "show" ) {
16082          el.show();
16083      }
16084      original = {
16085          height: el.height(),
16086          width: el.width(),
16087          outerHeight: el.outerHeight(),
16088          outerWidth: el.outerWidth()
16089      };
16090  
16091      if ( o.mode === "toggle" && mode === "show" ) {
16092          el.from = o.to || zero;
16093          el.to = o.from || original;
16094      } else {
16095          el.from = o.from || ( mode === "show" ? zero : original );
16096          el.to = o.to || ( mode === "hide" ? zero : original );
16097      }
16098  
16099      // Set scaling factor
16100      factor = {
16101          from: {
16102              y: el.from.height / original.height,
16103              x: el.from.width / original.width
16104          },
16105          to: {
16106              y: el.to.height / original.height,
16107              x: el.to.width / original.width
16108          }
16109      };
16110  
16111      // Scale the css box
16112      if ( scale === "box" || scale === "both" ) {
16113  
16114          // Vertical props scaling
16115          if ( factor.from.y !== factor.to.y ) {
16116              props = props.concat( vProps );
16117              el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
16118              el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
16119          }
16120  
16121          // Horizontal props scaling
16122          if ( factor.from.x !== factor.to.x ) {
16123              props = props.concat( hProps );
16124              el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
16125              el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
16126          }
16127      }
16128  
16129      // Scale the content
16130      if ( scale === "content" || scale === "both" ) {
16131  
16132          // Vertical props scaling
16133          if ( factor.from.y !== factor.to.y ) {
16134              props = props.concat( cProps ).concat( props2 );
16135              el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
16136              el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
16137          }
16138      }
16139  
16140      $.effects.save( el, props );
16141      el.show();
16142      $.effects.createWrapper( el );
16143      el.css( "overflow", "hidden" ).css( el.from );
16144  
16145      // Adjust
16146      if (origin) { // Calculate baseline shifts
16147          baseline = $.effects.getBaseline( origin, original );
16148          el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
16149          el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
16150          el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
16151          el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
16152      }
16153      el.css( el.from ); // set top & left
16154  
16155      // Animate
16156      if ( scale === "content" || scale === "both" ) { // Scale the children
16157  
16158          // Add margins/font-size
16159          vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
16160          hProps = hProps.concat([ "marginLeft", "marginRight" ]);
16161          props2 = props0.concat(vProps).concat(hProps);
16162  
16163          el.find( "*[width]" ).each( function() {
16164              var child = $( this ),
16165                  c_original = {
16166                      height: child.height(),
16167                      width: child.width(),
16168                      outerHeight: child.outerHeight(),
16169                      outerWidth: child.outerWidth()
16170                  };
16171              if (restore) {
16172                  $.effects.save(child, props2);
16173              }
16174  
16175              child.from = {
16176                  height: c_original.height * factor.from.y,
16177                  width: c_original.width * factor.from.x,
16178                  outerHeight: c_original.outerHeight * factor.from.y,
16179                  outerWidth: c_original.outerWidth * factor.from.x
16180              };
16181              child.to = {
16182                  height: c_original.height * factor.to.y,
16183                  width: c_original.width * factor.to.x,
16184                  outerHeight: c_original.height * factor.to.y,
16185                  outerWidth: c_original.width * factor.to.x
16186              };
16187  
16188              // Vertical props scaling
16189              if ( factor.from.y !== factor.to.y ) {
16190                  child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
16191                  child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
16192              }
16193  
16194              // Horizontal props scaling
16195              if ( factor.from.x !== factor.to.x ) {
16196                  child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
16197                  child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
16198              }
16199  
16200              // Animate children
16201              child.css( child.from );
16202              child.animate( child.to, o.duration, o.easing, function() {
16203  
16204                  // Restore children
16205                  if ( restore ) {
16206                      $.effects.restore( child, props2 );
16207                  }
16208              });
16209          });
16210      }
16211  
16212      // Animate
16213      el.animate( el.to, {
16214          queue: false,
16215          duration: o.duration,
16216          easing: o.easing,
16217          complete: function() {
16218              if ( el.to.opacity === 0 ) {
16219                  el.css( "opacity", el.from.opacity );
16220              }
16221              if ( mode === "hide" ) {
16222                  el.hide();
16223              }
16224              $.effects.restore( el, props );
16225              if ( !restore ) {
16226  
16227                  // we need to calculate our new positioning based on the scaling
16228                  if ( position === "static" ) {
16229                      el.css({
16230                          position: "relative",
16231                          top: el.to.top,
16232                          left: el.to.left
16233                      });
16234                  } else {
16235                      $.each([ "top", "left" ], function( idx, pos ) {
16236                          el.css( pos, function( _, str ) {
16237                              var val = parseInt( str, 10 ),
16238                                  toRef = idx ? el.to.left : el.to.top;
16239  
16240                              // if original was "auto", recalculate the new value from wrapper
16241                              if ( str === "auto" ) {
16242                                  return toRef + "px";
16243                              }
16244  
16245                              return val + toRef + "px";
16246                          });
16247                      });
16248                  }
16249              }
16250  
16251              $.effects.removeWrapper( el );
16252              done();
16253          }
16254      });
16255  
16256  };
16257  
16258  
16259  /*!
16260   * jQuery UI Effects Scale 1.11.4
16261   * http://jqueryui.com
16262   *
16263   * Copyright jQuery Foundation and other contributors
16264   * Released under the MIT license.
16265   * http://jquery.org/license
16266   *
16267   * http://api.jqueryui.com/scale-effect/
16268   */
16269  
16270  
16271  var effectScale = $.effects.effect.scale = function( o, done ) {
16272  
16273      // Create element
16274      var el = $( this ),
16275          options = $.extend( true, {}, o ),
16276          mode = $.effects.setMode( el, o.mode || "effect" ),
16277          percent = parseInt( o.percent, 10 ) ||
16278              ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
16279          direction = o.direction || "both",
16280          origin = o.origin,
16281          original = {
16282              height: el.height(),
16283              width: el.width(),
16284              outerHeight: el.outerHeight(),
16285              outerWidth: el.outerWidth()
16286          },
16287          factor = {
16288              y: direction !== "horizontal" ? (percent / 100) : 1,
16289              x: direction !== "vertical" ? (percent / 100) : 1
16290          };
16291  
16292      // We are going to pass this effect to the size effect:
16293      options.effect = "size";
16294      options.queue = false;
16295      options.complete = done;
16296  
16297      // Set default origin and restore for show/hide
16298      if ( mode !== "effect" ) {
16299          options.origin = origin || [ "middle", "center" ];
16300          options.restore = true;
16301      }
16302  
16303      options.from = o.from || ( mode === "show" ? {
16304          height: 0,
16305          width: 0,
16306          outerHeight: 0,
16307          outerWidth: 0
16308      } : original );
16309      options.to = {
16310          height: original.height * factor.y,
16311          width: original.width * factor.x,
16312          outerHeight: original.outerHeight * factor.y,
16313          outerWidth: original.outerWidth * factor.x
16314      };
16315  
16316      // Fade option to support puff
16317      if ( options.fade ) {
16318          if ( mode === "show" ) {
16319              options.from.opacity = 0;
16320              options.to.opacity = 1;
16321          }
16322          if ( mode === "hide" ) {
16323              options.from.opacity = 1;
16324              options.to.opacity = 0;
16325          }
16326      }
16327  
16328      // Animate
16329      el.effect( options );
16330  
16331  };
16332  
16333  
16334  /*!
16335   * jQuery UI Effects Puff 1.11.4
16336   * http://jqueryui.com
16337   *
16338   * Copyright jQuery Foundation and other contributors
16339   * Released under the MIT license.
16340   * http://jquery.org/license
16341   *
16342   * http://api.jqueryui.com/puff-effect/
16343   */
16344  
16345  
16346  var effectPuff = $.effects.effect.puff = function( o, done ) {
16347      var elem = $( this ),
16348          mode = $.effects.setMode( elem, o.mode || "hide" ),
16349          hide = mode === "hide",
16350          percent = parseInt( o.percent, 10 ) || 150,
16351          factor = percent / 100,
16352          original = {
16353              height: elem.height(),
16354              width: elem.width(),
16355              outerHeight: elem.outerHeight(),
16356              outerWidth: elem.outerWidth()
16357          };
16358  
16359      $.extend( o, {
16360          effect: "scale",
16361          queue: false,
16362          fade: true,
16363          mode: mode,
16364          complete: done,
16365          percent: hide ? percent : 100,
16366          from: hide ?
16367              original :
16368              {
16369                  height: original.height * factor,
16370                  width: original.width * factor,
16371                  outerHeight: original.outerHeight * factor,
16372                  outerWidth: original.outerWidth * factor
16373              }
16374      });
16375  
16376      elem.effect( o );
16377  };
16378  
16379  
16380  /*!
16381   * jQuery UI Effects Pulsate 1.11.4
16382   * http://jqueryui.com
16383   *
16384   * Copyright jQuery Foundation and other contributors
16385   * Released under the MIT license.
16386   * http://jquery.org/license
16387   *
16388   * http://api.jqueryui.com/pulsate-effect/
16389   */
16390  
16391  
16392  var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
16393      var elem = $( this ),
16394          mode = $.effects.setMode( elem, o.mode || "show" ),
16395          show = mode === "show",
16396          hide = mode === "hide",
16397          showhide = ( show || mode === "hide" ),
16398  
16399          // showing or hiding leaves of the "last" animation
16400          anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
16401          duration = o.duration / anims,
16402          animateTo = 0,
16403          queue = elem.queue(),
16404          queuelen = queue.length,
16405          i;
16406  
16407      if ( show || !elem.is(":visible")) {
16408          elem.css( "opacity", 0 ).show();
16409          animateTo = 1;
16410      }
16411  
16412      // anims - 1 opacity "toggles"
16413      for ( i = 1; i < anims; i++ ) {
16414          elem.animate({
16415              opacity: animateTo
16416          }, duration, o.easing );
16417          animateTo = 1 - animateTo;
16418      }
16419  
16420      elem.animate({
16421          opacity: animateTo
16422      }, duration, o.easing);
16423  
16424      elem.queue(function() {
16425          if ( hide ) {
16426              elem.hide();
16427          }
16428          done();
16429      });
16430  
16431      // We just queued up "anims" animations, we need to put them next in the queue
16432      if ( queuelen > 1 ) {
16433          queue.splice.apply( queue,
16434              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16435      }
16436      elem.dequeue();
16437  };
16438  
16439  
16440  /*!
16441   * jQuery UI Effects Shake 1.11.4
16442   * http://jqueryui.com
16443   *
16444   * Copyright jQuery Foundation and other contributors
16445   * Released under the MIT license.
16446   * http://jquery.org/license
16447   *
16448   * http://api.jqueryui.com/shake-effect/
16449   */
16450  
16451  
16452  var effectShake = $.effects.effect.shake = function( o, done ) {
16453  
16454      var el = $( this ),
16455          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
16456          mode = $.effects.setMode( el, o.mode || "effect" ),
16457          direction = o.direction || "left",
16458          distance = o.distance || 20,
16459          times = o.times || 3,
16460          anims = times * 2 + 1,
16461          speed = Math.round( o.duration / anims ),
16462          ref = (direction === "up" || direction === "down") ? "top" : "left",
16463          positiveMotion = (direction === "up" || direction === "left"),
16464          animation = {},
16465          animation1 = {},
16466          animation2 = {},
16467          i,
16468  
16469          // we will need to re-assemble the queue to stack our animations in place
16470          queue = el.queue(),
16471          queuelen = queue.length;
16472  
16473      $.effects.save( el, props );
16474      el.show();
16475      $.effects.createWrapper( el );
16476  
16477      // Animation
16478      animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
16479      animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
16480      animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
16481  
16482      // Animate
16483      el.animate( animation, speed, o.easing );
16484  
16485      // Shakes
16486      for ( i = 1; i < times; i++ ) {
16487          el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
16488      }
16489      el
16490          .animate( animation1, speed, o.easing )
16491          .animate( animation, speed / 2, o.easing )
16492          .queue(function() {
16493              if ( mode === "hide" ) {
16494                  el.hide();
16495              }
16496              $.effects.restore( el, props );
16497              $.effects.removeWrapper( el );
16498              done();
16499          });
16500  
16501      // inject all the animations we just queued to be first in line (after "inprogress")
16502      if ( queuelen > 1) {
16503          queue.splice.apply( queue,
16504              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
16505      }
16506      el.dequeue();
16507  
16508  };
16509  
16510  
16511  /*!
16512   * jQuery UI Effects Slide 1.11.4
16513   * http://jqueryui.com
16514   *
16515   * Copyright jQuery Foundation and other contributors
16516   * Released under the MIT license.
16517   * http://jquery.org/license
16518   *
16519   * http://api.jqueryui.com/slide-effect/
16520   */
16521  
16522  
16523  var effectSlide = $.effects.effect.slide = function( o, done ) {
16524  
16525      // Create element
16526      var el = $( this ),
16527          props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
16528          mode = $.effects.setMode( el, o.mode || "show" ),
16529          show = mode === "show",
16530          direction = o.direction || "left",
16531          ref = (direction === "up" || direction === "down") ? "top" : "left",
16532          positiveMotion = (direction === "up" || direction === "left"),
16533          distance,
16534          animation = {};
16535  
16536      // Adjust
16537      $.effects.save( el, props );
16538      el.show();
16539      distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
16540  
16541      $.effects.createWrapper( el ).css({
16542          overflow: "hidden"
16543      });
16544  
16545      if ( show ) {
16546          el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
16547      }
16548  
16549      // Animation
16550      animation[ ref ] = ( show ?
16551          ( positiveMotion ? "+=" : "-=") :
16552          ( positiveMotion ? "-=" : "+=")) +
16553          distance;
16554  
16555      // Animate
16556      el.animate( animation, {
16557          queue: false,
16558          duration: o.duration,
16559          easing: o.easing,
16560          complete: function() {
16561              if ( mode === "hide" ) {
16562                  el.hide();
16563              }
16564              $.effects.restore( el, props );
16565              $.effects.removeWrapper( el );
16566              done();
16567          }
16568      });
16569  };
16570  
16571  
16572  /*!
16573   * jQuery UI Effects Transfer 1.11.4
16574   * http://jqueryui.com
16575   *
16576   * Copyright jQuery Foundation and other contributors
16577   * Released under the MIT license.
16578   * http://jquery.org/license
16579   *
16580   * http://api.jqueryui.com/transfer-effect/
16581   */
16582  
16583  
16584  var effectTransfer = $.effects.effect.transfer = function( o, done ) {
16585      var elem = $( this ),
16586          target = $( o.to ),
16587          targetFixed = target.css( "position" ) === "fixed",
16588          body = $("body"),
16589          fixTop = targetFixed ? body.scrollTop() : 0,
16590          fixLeft = targetFixed ? body.scrollLeft() : 0,
16591          endPosition = target.offset(),
16592          animation = {
16593              top: endPosition.top - fixTop,
16594              left: endPosition.left - fixLeft,
16595              height: target.innerHeight(),
16596              width: target.innerWidth()
16597          },
16598          startPosition = elem.offset(),
16599          transfer = $( "<div class='ui-effects-transfer'></div>" )
16600              .appendTo( document.body )
16601              .addClass( o.className )
16602              .css({
16603                  top: startPosition.top - fixTop,
16604                  left: startPosition.left - fixLeft,
16605                  height: elem.innerHeight(),
16606                  width: elem.innerWidth(),
16607                  position: targetFixed ? "fixed" : "absolute"
16608              })
16609              .animate( animation, o.duration, o.easing, function() {
16610                  transfer.remove();
16611                  done();
16612              });
16613  };
16614  
16615  
16616  
16617  }));


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1