[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

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

   1  /*! jQuery UI - v1.11.1 - 2014-08-13
   2  * http://jqueryui.com
   3  * Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
   4  * Copyright 2014 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.1
  19   * http://jqueryui.com
  20   *
  21   * Copyright 2014 jQuery Foundation and other contributors
  22   * Released under the MIT license.
  23   * http://jquery.org/license
  24   *
  25   * http://api.jqueryui.com/category/ui-core/
  26   */
  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.1",
  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.1
 313   * http://jqueryui.com
 314   *
 315   * Copyright 2014 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          // allow multiple hashes to be passed on init
 494          options = !isMethodCall && args.length ?
 495              $.widget.extend.apply( null, [ options ].concat(args) ) :
 496              options;
 497  
 498          if ( isMethodCall ) {
 499              this.each(function() {
 500                  var methodValue,
 501                      instance = $.data( this, fullName );
 502                  if ( options === "instance" ) {
 503                      returnValue = instance;
 504                      return false;
 505                  }
 506                  if ( !instance ) {
 507                      return $.error( "cannot call methods on " + name + " prior to initialization; " +
 508                          "attempted to call method '" + options + "'" );
 509                  }
 510                  if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
 511                      return $.error( "no such method '" + options + "' for " + name + " widget instance" );
 512                  }
 513                  methodValue = instance[ options ].apply( instance, args );
 514                  if ( methodValue !== instance && methodValue !== undefined ) {
 515                      returnValue = methodValue && methodValue.jquery ?
 516                          returnValue.pushStack( methodValue.get() ) :
 517                          methodValue;
 518                      return false;
 519                  }
 520              });
 521          } else {
 522              this.each(function() {
 523                  var instance = $.data( this, fullName );
 524                  if ( instance ) {
 525                      instance.option( options || {} );
 526                      if ( instance._init ) {
 527                          instance._init();
 528                      }
 529                  } else {
 530                      $.data( this, fullName, new object( options, this ) );
 531                  }
 532              });
 533          }
 534  
 535          return returnValue;
 536      };
 537  };
 538  
 539  $.Widget = function( /* options, element */ ) {};
 540  $.Widget._childConstructors = [];
 541  
 542  $.Widget.prototype = {
 543      widgetName: "widget",
 544      widgetEventPrefix: "",
 545      defaultElement: "<div>",
 546      options: {
 547          disabled: false,
 548  
 549          // callbacks
 550          create: null
 551      },
 552      _createWidget: function( options, element ) {
 553          element = $( element || this.defaultElement || this )[ 0 ];
 554          this.element = $( element );
 555          this.uuid = widget_uuid++;
 556          this.eventNamespace = "." + this.widgetName + this.uuid;
 557          this.options = $.widget.extend( {},
 558              this.options,
 559              this._getCreateOptions(),
 560              options );
 561  
 562          this.bindings = $();
 563          this.hoverable = $();
 564          this.focusable = $();
 565  
 566          if ( element !== this ) {
 567              $.data( element, this.widgetFullName, this );
 568              this._on( true, this.element, {
 569                  remove: function( event ) {
 570                      if ( event.target === element ) {
 571                          this.destroy();
 572                      }
 573                  }
 574              });
 575              this.document = $( element.style ?
 576                  // element within the document
 577                  element.ownerDocument :
 578                  // element is window or document
 579                  element.document || element );
 580              this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
 581          }
 582  
 583          this._create();
 584          this._trigger( "create", null, this._getCreateEventData() );
 585          this._init();
 586      },
 587      _getCreateOptions: $.noop,
 588      _getCreateEventData: $.noop,
 589      _create: $.noop,
 590      _init: $.noop,
 591  
 592      destroy: function() {
 593          this._destroy();
 594          // we can probably remove the unbind calls in 2.0
 595          // all event bindings should go through this._on()
 596          this.element
 597              .unbind( this.eventNamespace )
 598              .removeData( this.widgetFullName )
 599              // support: jquery <1.6.3
 600              // http://bugs.jquery.com/ticket/9413
 601              .removeData( $.camelCase( this.widgetFullName ) );
 602          this.widget()
 603              .unbind( this.eventNamespace )
 604              .removeAttr( "aria-disabled" )
 605              .removeClass(
 606                  this.widgetFullName + "-disabled " +
 607                  "ui-state-disabled" );
 608  
 609          // clean up events and states
 610          this.bindings.unbind( this.eventNamespace );
 611          this.hoverable.removeClass( "ui-state-hover" );
 612          this.focusable.removeClass( "ui-state-focus" );
 613      },
 614      _destroy: $.noop,
 615  
 616      widget: function() {
 617          return this.element;
 618      },
 619  
 620      option: function( key, value ) {
 621          var options = key,
 622              parts,
 623              curOption,
 624              i;
 625  
 626          if ( arguments.length === 0 ) {
 627              // don't return a reference to the internal hash
 628              return $.widget.extend( {}, this.options );
 629          }
 630  
 631          if ( typeof key === "string" ) {
 632              // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 633              options = {};
 634              parts = key.split( "." );
 635              key = parts.shift();
 636              if ( parts.length ) {
 637                  curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
 638                  for ( i = 0; i < parts.length - 1; i++ ) {
 639                      curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
 640                      curOption = curOption[ parts[ i ] ];
 641                  }
 642                  key = parts.pop();
 643                  if ( arguments.length === 1 ) {
 644                      return curOption[ key ] === undefined ? null : curOption[ key ];
 645                  }
 646                  curOption[ key ] = value;
 647              } else {
 648                  if ( arguments.length === 1 ) {
 649                      return this.options[ key ] === undefined ? null : this.options[ key ];
 650                  }
 651                  options[ key ] = value;
 652              }
 653          }
 654  
 655          this._setOptions( options );
 656  
 657          return this;
 658      },
 659      _setOptions: function( options ) {
 660          var key;
 661  
 662          for ( key in options ) {
 663              this._setOption( key, options[ key ] );
 664          }
 665  
 666          return this;
 667      },
 668      _setOption: function( key, value ) {
 669          this.options[ key ] = value;
 670  
 671          if ( key === "disabled" ) {
 672              this.widget()
 673                  .toggleClass( this.widgetFullName + "-disabled", !!value );
 674  
 675              // If the widget is becoming disabled, then nothing is interactive
 676              if ( value ) {
 677                  this.hoverable.removeClass( "ui-state-hover" );
 678                  this.focusable.removeClass( "ui-state-focus" );
 679              }
 680          }
 681  
 682          return this;
 683      },
 684  
 685      enable: function() {
 686          return this._setOptions({ disabled: false });
 687      },
 688      disable: function() {
 689          return this._setOptions({ disabled: true });
 690      },
 691  
 692      _on: function( suppressDisabledCheck, element, handlers ) {
 693          var delegateElement,
 694              instance = this;
 695  
 696          // no suppressDisabledCheck flag, shuffle arguments
 697          if ( typeof suppressDisabledCheck !== "boolean" ) {
 698              handlers = element;
 699              element = suppressDisabledCheck;
 700              suppressDisabledCheck = false;
 701          }
 702  
 703          // no element argument, shuffle and use this.element
 704          if ( !handlers ) {
 705              handlers = element;
 706              element = this.element;
 707              delegateElement = this.widget();
 708          } else {
 709              element = delegateElement = $( element );
 710              this.bindings = this.bindings.add( element );
 711          }
 712  
 713          $.each( handlers, function( event, handler ) {
 714  			function handlerProxy() {
 715                  // allow widgets to customize the disabled handling
 716                  // - disabled as an array instead of boolean
 717                  // - disabled class as method for disabling individual parts
 718                  if ( !suppressDisabledCheck &&
 719                          ( instance.options.disabled === true ||
 720                              $( this ).hasClass( "ui-state-disabled" ) ) ) {
 721                      return;
 722                  }
 723                  return ( typeof handler === "string" ? instance[ handler ] : handler )
 724                      .apply( instance, arguments );
 725              }
 726  
 727              // copy the guid so direct unbinding works
 728              if ( typeof handler !== "string" ) {
 729                  handlerProxy.guid = handler.guid =
 730                      handler.guid || handlerProxy.guid || $.guid++;
 731              }
 732  
 733              var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
 734                  eventName = match[1] + instance.eventNamespace,
 735                  selector = match[2];
 736              if ( selector ) {
 737                  delegateElement.delegate( selector, eventName, handlerProxy );
 738              } else {
 739                  element.bind( eventName, handlerProxy );
 740              }
 741          });
 742      },
 743  
 744      _off: function( element, eventName ) {
 745          eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
 746          element.unbind( eventName ).undelegate( eventName );
 747      },
 748  
 749      _delay: function( handler, delay ) {
 750  		function handlerProxy() {
 751              return ( typeof handler === "string" ? instance[ handler ] : handler )
 752                  .apply( instance, arguments );
 753          }
 754          var instance = this;
 755          return setTimeout( handlerProxy, delay || 0 );
 756      },
 757  
 758      _hoverable: function( element ) {
 759          this.hoverable = this.hoverable.add( element );
 760          this._on( element, {
 761              mouseenter: function( event ) {
 762                  $( event.currentTarget ).addClass( "ui-state-hover" );
 763              },
 764              mouseleave: function( event ) {
 765                  $( event.currentTarget ).removeClass( "ui-state-hover" );
 766              }
 767          });
 768      },
 769  
 770      _focusable: function( element ) {
 771          this.focusable = this.focusable.add( element );
 772          this._on( element, {
 773              focusin: function( event ) {
 774                  $( event.currentTarget ).addClass( "ui-state-focus" );
 775              },
 776              focusout: function( event ) {
 777                  $( event.currentTarget ).removeClass( "ui-state-focus" );
 778              }
 779          });
 780      },
 781  
 782      _trigger: function( type, event, data ) {
 783          var prop, orig,
 784              callback = this.options[ type ];
 785  
 786          data = data || {};
 787          event = $.Event( event );
 788          event.type = ( type === this.widgetEventPrefix ?
 789              type :
 790              this.widgetEventPrefix + type ).toLowerCase();
 791          // the original event may come from any element
 792          // so we need to reset the target on the new event
 793          event.target = this.element[ 0 ];
 794  
 795          // copy original event properties over to the new event
 796          orig = event.originalEvent;
 797          if ( orig ) {
 798              for ( prop in orig ) {
 799                  if ( !( prop in event ) ) {
 800                      event[ prop ] = orig[ prop ];
 801                  }
 802              }
 803          }
 804  
 805          this.element.trigger( event, data );
 806          return !( $.isFunction( callback ) &&
 807              callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
 808              event.isDefaultPrevented() );
 809      }
 810  };
 811  
 812  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
 813      $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
 814          if ( typeof options === "string" ) {
 815              options = { effect: options };
 816          }
 817          var hasOptions,
 818              effectName = !options ?
 819                  method :
 820                  options === true || typeof options === "number" ?
 821                      defaultEffect :
 822                      options.effect || defaultEffect;
 823          options = options || {};
 824          if ( typeof options === "number" ) {
 825              options = { duration: options };
 826          }
 827          hasOptions = !$.isEmptyObject( options );
 828          options.complete = callback;
 829          if ( options.delay ) {
 830              element.delay( options.delay );
 831          }
 832          if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
 833              element[ method ]( options );
 834          } else if ( effectName !== method && element[ effectName ] ) {
 835              element[ effectName ]( options.duration, options.easing, callback );
 836          } else {
 837              element.queue(function( next ) {
 838                  $( this )[ method ]();
 839                  if ( callback ) {
 840                      callback.call( element[ 0 ] );
 841                  }
 842                  next();
 843              });
 844          }
 845      };
 846  });
 847  
 848  var widget = $.widget;
 849  
 850  
 851  /*!
 852   * jQuery UI Mouse 1.11.1
 853   * http://jqueryui.com
 854   *
 855   * Copyright 2014 jQuery Foundation and other contributors
 856   * Released under the MIT license.
 857   * http://jquery.org/license
 858   *
 859   * http://api.jqueryui.com/mouse/
 860   */
 861  
 862  
 863  var mouseHandled = false;
 864  $( document ).mouseup( function() {
 865      mouseHandled = false;
 866  });
 867  
 868  var mouse = $.widget("ui.mouse", {
 869      version: "1.11.1",
 870      options: {
 871          cancel: "input,textarea,button,select,option",
 872          distance: 1,
 873          delay: 0
 874      },
 875      _mouseInit: function() {
 876          var that = this;
 877  
 878          this.element
 879              .bind("mousedown." + this.widgetName, function(event) {
 880                  return that._mouseDown(event);
 881              })
 882              .bind("click." + this.widgetName, function(event) {
 883                  if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
 884                      $.removeData(event.target, that.widgetName + ".preventClickEvent");
 885                      event.stopImmediatePropagation();
 886                      return false;
 887                  }
 888              });
 889  
 890          this.started = false;
 891      },
 892  
 893      // TODO: make sure destroying one instance of mouse doesn't mess with
 894      // other instances of mouse
 895      _mouseDestroy: function() {
 896          this.element.unbind("." + this.widgetName);
 897          if ( this._mouseMoveDelegate ) {
 898              this.document
 899                  .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
 900                  .unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
 901          }
 902      },
 903  
 904      _mouseDown: function(event) {
 905          // don't let more than one widget handle mouseStart
 906          if ( mouseHandled ) {
 907              return;
 908          }
 909  
 910          // we may have missed mouseup (out of window)
 911          (this._mouseStarted && this._mouseUp(event));
 912  
 913          this._mouseDownEvent = event;
 914  
 915          var that = this,
 916              btnIsLeft = (event.which === 1),
 917              // event.target.nodeName works around a bug in IE 8 with
 918              // disabled inputs (#7620)
 919              elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
 920          if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 921              return true;
 922          }
 923  
 924          this.mouseDelayMet = !this.options.delay;
 925          if (!this.mouseDelayMet) {
 926              this._mouseDelayTimer = setTimeout(function() {
 927                  that.mouseDelayMet = true;
 928              }, this.options.delay);
 929          }
 930  
 931          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 932              this._mouseStarted = (this._mouseStart(event) !== false);
 933              if (!this._mouseStarted) {
 934                  event.preventDefault();
 935                  return true;
 936              }
 937          }
 938  
 939          // Click event may never have fired (Gecko & Opera)
 940          if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
 941              $.removeData(event.target, this.widgetName + ".preventClickEvent");
 942          }
 943  
 944          // these delegates are required to keep context
 945          this._mouseMoveDelegate = function(event) {
 946              return that._mouseMove(event);
 947          };
 948          this._mouseUpDelegate = function(event) {
 949              return that._mouseUp(event);
 950          };
 951  
 952          this.document
 953              .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
 954              .bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
 955  
 956          event.preventDefault();
 957  
 958          mouseHandled = true;
 959          return true;
 960      },
 961  
 962      _mouseMove: function(event) {
 963          // IE mouseup check - mouseup happened when mouse was out of window
 964          if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
 965              return this._mouseUp(event);
 966  
 967          // Iframe mouseup check - mouseup occurred in another document
 968          } else if ( !event.which ) {
 969              return this._mouseUp( event );
 970          }
 971  
 972          if (this._mouseStarted) {
 973              this._mouseDrag(event);
 974              return event.preventDefault();
 975          }
 976  
 977          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 978              this._mouseStarted =
 979                  (this._mouseStart(this._mouseDownEvent, event) !== false);
 980              (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
 981          }
 982  
 983          return !this._mouseStarted;
 984      },
 985  
 986      _mouseUp: function(event) {
 987          this.document
 988              .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
 989              .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
 990  
 991          if (this._mouseStarted) {
 992              this._mouseStarted = false;
 993  
 994              if (event.target === this._mouseDownEvent.target) {
 995                  $.data(event.target, this.widgetName + ".preventClickEvent", true);
 996              }
 997  
 998              this._mouseStop(event);
 999          }
1000  
1001          mouseHandled = false;
1002          return false;
1003      },
1004  
1005      _mouseDistanceMet: function(event) {
1006          return (Math.max(
1007                  Math.abs(this._mouseDownEvent.pageX - event.pageX),
1008                  Math.abs(this._mouseDownEvent.pageY - event.pageY)
1009              ) >= this.options.distance
1010          );
1011      },
1012  
1013      _mouseDelayMet: function(/* event */) {
1014          return this.mouseDelayMet;
1015      },
1016  
1017      // These are placeholder methods, to be overriden by extending plugin
1018      _mouseStart: function(/* event */) {},
1019      _mouseDrag: function(/* event */) {},
1020      _mouseStop: function(/* event */) {},
1021      _mouseCapture: function(/* event */) { return true; }
1022  });
1023  
1024  
1025  /*!
1026   * jQuery UI Position 1.11.1
1027   * http://jqueryui.com
1028   *
1029   * Copyright 2014 jQuery Foundation and other contributors
1030   * Released under the MIT license.
1031   * http://jquery.org/license
1032   *
1033   * http://api.jqueryui.com/position/
1034   */
1035  
1036  (function() {
1037  
1038  $.ui = $.ui || {};
1039  
1040  var cachedScrollbarWidth, supportsOffsetFractions,
1041      max = Math.max,
1042      abs = Math.abs,
1043      round = Math.round,
1044      rhorizontal = /left|center|right/,
1045      rvertical = /top|center|bottom/,
1046      roffset = /[\+\-]\d+(\.[\d]+)?%?/,
1047      rposition = /^\w+/,
1048      rpercent = /%$/,
1049      _position = $.fn.position;
1050  
1051  function getOffsets( offsets, width, height ) {
1052      return [
1053          parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1054          parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1055      ];
1056  }
1057  
1058  function parseCss( element, property ) {
1059      return parseInt( $.css( element, property ), 10 ) || 0;
1060  }
1061  
1062  function getDimensions( elem ) {
1063      var raw = elem[0];
1064      if ( raw.nodeType === 9 ) {
1065          return {
1066              width: elem.width(),
1067              height: elem.height(),
1068              offset: { top: 0, left: 0 }
1069          };
1070      }
1071      if ( $.isWindow( raw ) ) {
1072          return {
1073              width: elem.width(),
1074              height: elem.height(),
1075              offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1076          };
1077      }
1078      if ( raw.preventDefault ) {
1079          return {
1080              width: 0,
1081              height: 0,
1082              offset: { top: raw.pageY, left: raw.pageX }
1083          };
1084      }
1085      return {
1086          width: elem.outerWidth(),
1087          height: elem.outerHeight(),
1088          offset: elem.offset()
1089      };
1090  }
1091  
1092  $.position = {
1093      scrollbarWidth: function() {
1094          if ( cachedScrollbarWidth !== undefined ) {
1095              return cachedScrollbarWidth;
1096          }
1097          var w1, w2,
1098              div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1099              innerDiv = div.children()[0];
1100  
1101          $( "body" ).append( div );
1102          w1 = innerDiv.offsetWidth;
1103          div.css( "overflow", "scroll" );
1104  
1105          w2 = innerDiv.offsetWidth;
1106  
1107          if ( w1 === w2 ) {
1108              w2 = div[0].clientWidth;
1109          }
1110  
1111          div.remove();
1112  
1113          return (cachedScrollbarWidth = w1 - w2);
1114      },
1115      getScrollInfo: function( within ) {
1116          var overflowX = within.isWindow || within.isDocument ? "" :
1117                  within.element.css( "overflow-x" ),
1118              overflowY = within.isWindow || within.isDocument ? "" :
1119                  within.element.css( "overflow-y" ),
1120              hasOverflowX = overflowX === "scroll" ||
1121                  ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1122              hasOverflowY = overflowY === "scroll" ||
1123                  ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1124          return {
1125              width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1126              height: hasOverflowX ? $.position.scrollbarWidth() : 0
1127          };
1128      },
1129      getWithinInfo: function( element ) {
1130          var withinElement = $( element || window ),
1131              isWindow = $.isWindow( withinElement[0] ),
1132              isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
1133          return {
1134              element: withinElement,
1135              isWindow: isWindow,
1136              isDocument: isDocument,
1137              offset: withinElement.offset() || { left: 0, top: 0 },
1138              scrollLeft: withinElement.scrollLeft(),
1139              scrollTop: withinElement.scrollTop(),
1140  
1141              // support: jQuery 1.6.x
1142              // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
1143              width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
1144              height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
1145          };
1146      }
1147  };
1148  
1149  $.fn.position = function( options ) {
1150      if ( !options || !options.of ) {
1151          return _position.apply( this, arguments );
1152      }
1153  
1154      // make a copy, we don't want to modify arguments
1155      options = $.extend( {}, options );
1156  
1157      var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1158          target = $( options.of ),
1159          within = $.position.getWithinInfo( options.within ),
1160          scrollInfo = $.position.getScrollInfo( within ),
1161          collision = ( options.collision || "flip" ).split( " " ),
1162          offsets = {};
1163  
1164      dimensions = getDimensions( target );
1165      if ( target[0].preventDefault ) {
1166          // force left top to allow flipping
1167          options.at = "left top";
1168      }
1169      targetWidth = dimensions.width;
1170      targetHeight = dimensions.height;
1171      targetOffset = dimensions.offset;
1172      // clone to reuse original targetOffset later
1173      basePosition = $.extend( {}, targetOffset );
1174  
1175      // force my and at to have valid horizontal and vertical positions
1176      // if a value is missing or invalid, it will be converted to center
1177      $.each( [ "my", "at" ], function() {
1178          var pos = ( options[ this ] || "" ).split( " " ),
1179              horizontalOffset,
1180              verticalOffset;
1181  
1182          if ( pos.length === 1) {
1183              pos = rhorizontal.test( pos[ 0 ] ) ?
1184                  pos.concat( [ "center" ] ) :
1185                  rvertical.test( pos[ 0 ] ) ?
1186                      [ "center" ].concat( pos ) :
1187                      [ "center", "center" ];
1188          }
1189          pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1190          pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1191  
1192          // calculate offsets
1193          horizontalOffset = roffset.exec( pos[ 0 ] );
1194          verticalOffset = roffset.exec( pos[ 1 ] );
1195          offsets[ this ] = [
1196              horizontalOffset ? horizontalOffset[ 0 ] : 0,
1197              verticalOffset ? verticalOffset[ 0 ] : 0
1198          ];
1199  
1200          // reduce to just the positions without the offsets
1201          options[ this ] = [
1202              rposition.exec( pos[ 0 ] )[ 0 ],
1203              rposition.exec( pos[ 1 ] )[ 0 ]
1204          ];
1205      });
1206  
1207      // normalize collision option
1208      if ( collision.length === 1 ) {
1209          collision[ 1 ] = collision[ 0 ];
1210      }
1211  
1212      if ( options.at[ 0 ] === "right" ) {
1213          basePosition.left += targetWidth;
1214      } else if ( options.at[ 0 ] === "center" ) {
1215          basePosition.left += targetWidth / 2;
1216      }
1217  
1218      if ( options.at[ 1 ] === "bottom" ) {
1219          basePosition.top += targetHeight;
1220      } else if ( options.at[ 1 ] === "center" ) {
1221          basePosition.top += targetHeight / 2;
1222      }
1223  
1224      atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1225      basePosition.left += atOffset[ 0 ];
1226      basePosition.top += atOffset[ 1 ];
1227  
1228      return this.each(function() {
1229          var collisionPosition, using,
1230              elem = $( this ),
1231              elemWidth = elem.outerWidth(),
1232              elemHeight = elem.outerHeight(),
1233              marginLeft = parseCss( this, "marginLeft" ),
1234              marginTop = parseCss( this, "marginTop" ),
1235              collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1236              collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1237              position = $.extend( {}, basePosition ),
1238              myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1239  
1240          if ( options.my[ 0 ] === "right" ) {
1241              position.left -= elemWidth;
1242          } else if ( options.my[ 0 ] === "center" ) {
1243              position.left -= elemWidth / 2;
1244          }
1245  
1246          if ( options.my[ 1 ] === "bottom" ) {
1247              position.top -= elemHeight;
1248          } else if ( options.my[ 1 ] === "center" ) {
1249              position.top -= elemHeight / 2;
1250          }
1251  
1252          position.left += myOffset[ 0 ];
1253          position.top += myOffset[ 1 ];
1254  
1255          // if the browser doesn't support fractions, then round for consistent results
1256          if ( !supportsOffsetFractions ) {
1257              position.left = round( position.left );
1258              position.top = round( position.top );
1259          }
1260  
1261          collisionPosition = {
1262              marginLeft: marginLeft,
1263              marginTop: marginTop
1264          };
1265  
1266          $.each( [ "left", "top" ], function( i, dir ) {
1267              if ( $.ui.position[ collision[ i ] ] ) {
1268                  $.ui.position[ collision[ i ] ][ dir ]( position, {
1269                      targetWidth: targetWidth,
1270                      targetHeight: targetHeight,
1271                      elemWidth: elemWidth,
1272                      elemHeight: elemHeight,
1273                      collisionPosition: collisionPosition,
1274                      collisionWidth: collisionWidth,
1275                      collisionHeight: collisionHeight,
1276                      offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1277                      my: options.my,
1278                      at: options.at,
1279                      within: within,
1280                      elem: elem
1281                  });
1282              }
1283          });
1284  
1285          if ( options.using ) {
1286              // adds feedback as second argument to using callback, if present
1287              using = function( props ) {
1288                  var left = targetOffset.left - position.left,
1289                      right = left + targetWidth - elemWidth,
1290                      top = targetOffset.top - position.top,
1291                      bottom = top + targetHeight - elemHeight,
1292                      feedback = {
1293                          target: {
1294                              element: target,
1295                              left: targetOffset.left,
1296                              top: targetOffset.top,
1297                              width: targetWidth,
1298                              height: targetHeight
1299                          },
1300                          element: {
1301                              element: elem,
1302                              left: position.left,
1303                              top: position.top,
1304                              width: elemWidth,
1305                              height: elemHeight
1306                          },
1307                          horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1308                          vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1309                      };
1310                  if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1311                      feedback.horizontal = "center";
1312                  }
1313                  if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1314                      feedback.vertical = "middle";
1315                  }
1316                  if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1317                      feedback.important = "horizontal";
1318                  } else {
1319                      feedback.important = "vertical";
1320                  }
1321                  options.using.call( this, props, feedback );
1322              };
1323          }
1324  
1325          elem.offset( $.extend( position, { using: using } ) );
1326      });
1327  };
1328  
1329  $.ui.position = {
1330      fit: {
1331          left: function( position, data ) {
1332              var within = data.within,
1333                  withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1334                  outerWidth = within.width,
1335                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1336                  overLeft = withinOffset - collisionPosLeft,
1337                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1338                  newOverRight;
1339  
1340              // element is wider than within
1341              if ( data.collisionWidth > outerWidth ) {
1342                  // element is initially over the left side of within
1343                  if ( overLeft > 0 && overRight <= 0 ) {
1344                      newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1345                      position.left += overLeft - newOverRight;
1346                  // element is initially over right side of within
1347                  } else if ( overRight > 0 && overLeft <= 0 ) {
1348                      position.left = withinOffset;
1349                  // element is initially over both left and right sides of within
1350                  } else {
1351                      if ( overLeft > overRight ) {
1352                          position.left = withinOffset + outerWidth - data.collisionWidth;
1353                      } else {
1354                          position.left = withinOffset;
1355                      }
1356                  }
1357              // too far left -> align with left edge
1358              } else if ( overLeft > 0 ) {
1359                  position.left += overLeft;
1360              // too far right -> align with right edge
1361              } else if ( overRight > 0 ) {
1362                  position.left -= overRight;
1363              // adjust based on position and margin
1364              } else {
1365                  position.left = max( position.left - collisionPosLeft, position.left );
1366              }
1367          },
1368          top: function( position, data ) {
1369              var within = data.within,
1370                  withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1371                  outerHeight = data.within.height,
1372                  collisionPosTop = position.top - data.collisionPosition.marginTop,
1373                  overTop = withinOffset - collisionPosTop,
1374                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1375                  newOverBottom;
1376  
1377              // element is taller than within
1378              if ( data.collisionHeight > outerHeight ) {
1379                  // element is initially over the top of within
1380                  if ( overTop > 0 && overBottom <= 0 ) {
1381                      newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1382                      position.top += overTop - newOverBottom;
1383                  // element is initially over bottom of within
1384                  } else if ( overBottom > 0 && overTop <= 0 ) {
1385                      position.top = withinOffset;
1386                  // element is initially over both top and bottom of within
1387                  } else {
1388                      if ( overTop > overBottom ) {
1389                          position.top = withinOffset + outerHeight - data.collisionHeight;
1390                      } else {
1391                          position.top = withinOffset;
1392                      }
1393                  }
1394              // too far up -> align with top
1395              } else if ( overTop > 0 ) {
1396                  position.top += overTop;
1397              // too far down -> align with bottom edge
1398              } else if ( overBottom > 0 ) {
1399                  position.top -= overBottom;
1400              // adjust based on position and margin
1401              } else {
1402                  position.top = max( position.top - collisionPosTop, position.top );
1403              }
1404          }
1405      },
1406      flip: {
1407          left: function( position, data ) {
1408              var within = data.within,
1409                  withinOffset = within.offset.left + within.scrollLeft,
1410                  outerWidth = within.width,
1411                  offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1412                  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1413                  overLeft = collisionPosLeft - offsetLeft,
1414                  overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1415                  myOffset = data.my[ 0 ] === "left" ?
1416                      -data.elemWidth :
1417                      data.my[ 0 ] === "right" ?
1418                          data.elemWidth :
1419                          0,
1420                  atOffset = data.at[ 0 ] === "left" ?
1421                      data.targetWidth :
1422                      data.at[ 0 ] === "right" ?
1423                          -data.targetWidth :
1424                          0,
1425                  offset = -2 * data.offset[ 0 ],
1426                  newOverRight,
1427                  newOverLeft;
1428  
1429              if ( overLeft < 0 ) {
1430                  newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1431                  if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1432                      position.left += myOffset + atOffset + offset;
1433                  }
1434              } else if ( overRight > 0 ) {
1435                  newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1436                  if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1437                      position.left += myOffset + atOffset + offset;
1438                  }
1439              }
1440          },
1441          top: function( position, data ) {
1442              var within = data.within,
1443                  withinOffset = within.offset.top + within.scrollTop,
1444                  outerHeight = within.height,
1445                  offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1446                  collisionPosTop = position.top - data.collisionPosition.marginTop,
1447                  overTop = collisionPosTop - offsetTop,
1448                  overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1449                  top = data.my[ 1 ] === "top",
1450                  myOffset = top ?
1451                      -data.elemHeight :
1452                      data.my[ 1 ] === "bottom" ?
1453                          data.elemHeight :
1454                          0,
1455                  atOffset = data.at[ 1 ] === "top" ?
1456                      data.targetHeight :
1457                      data.at[ 1 ] === "bottom" ?
1458                          -data.targetHeight :
1459                          0,
1460                  offset = -2 * data.offset[ 1 ],
1461                  newOverTop,
1462                  newOverBottom;
1463              if ( overTop < 0 ) {
1464                  newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1465                  if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1466                      position.top += myOffset + atOffset + offset;
1467                  }
1468              } else if ( overBottom > 0 ) {
1469                  newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1470                  if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1471                      position.top += myOffset + atOffset + offset;
1472                  }
1473              }
1474          }
1475      },
1476      flipfit: {
1477          left: function() {
1478              $.ui.position.flip.left.apply( this, arguments );
1479              $.ui.position.fit.left.apply( this, arguments );
1480          },
1481          top: function() {
1482              $.ui.position.flip.top.apply( this, arguments );
1483              $.ui.position.fit.top.apply( this, arguments );
1484          }
1485      }
1486  };
1487  
1488  // fraction support test
1489  (function() {
1490      var testElement, testElementParent, testElementStyle, offsetLeft, i,
1491          body = document.getElementsByTagName( "body" )[ 0 ],
1492          div = document.createElement( "div" );
1493  
1494      //Create a "fake body" for testing based on method used in jQuery.support
1495      testElement = document.createElement( body ? "div" : "body" );
1496      testElementStyle = {
1497          visibility: "hidden",
1498          width: 0,
1499          height: 0,
1500          border: 0,
1501          margin: 0,
1502          background: "none"
1503      };
1504      if ( body ) {
1505          $.extend( testElementStyle, {
1506              position: "absolute",
1507              left: "-1000px",
1508              top: "-1000px"
1509          });
1510      }
1511      for ( i in testElementStyle ) {
1512          testElement.style[ i ] = testElementStyle[ i ];
1513      }
1514      testElement.appendChild( div );
1515      testElementParent = body || document.documentElement;
1516      testElementParent.insertBefore( testElement, testElementParent.firstChild );
1517  
1518      div.style.cssText = "position: absolute; left: 10.7432222px;";
1519  
1520      offsetLeft = $( div ).offset().left;
1521      supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
1522  
1523      testElement.innerHTML = "";
1524      testElementParent.removeChild( testElement );
1525  })();
1526  
1527  })();
1528  
1529  var position = $.ui.position;
1530  
1531  
1532  /*!
1533   * jQuery UI Accordion 1.11.1
1534   * http://jqueryui.com
1535   *
1536   * Copyright 2014 jQuery Foundation and other contributors
1537   * Released under the MIT license.
1538   * http://jquery.org/license
1539   *
1540   * http://api.jqueryui.com/accordion/
1541   */
1542  
1543  
1544  var accordion = $.widget( "ui.accordion", {
1545      version: "1.11.1",
1546      options: {
1547          active: 0,
1548          animate: {},
1549          collapsible: false,
1550          event: "click",
1551          header: "> li > :first-child,> :not(li):even",
1552          heightStyle: "auto",
1553          icons: {
1554              activeHeader: "ui-icon-triangle-1-s",
1555              header: "ui-icon-triangle-1-e"
1556          },
1557  
1558          // callbacks
1559          activate: null,
1560          beforeActivate: null
1561      },
1562  
1563      hideProps: {
1564          borderTopWidth: "hide",
1565          borderBottomWidth: "hide",
1566          paddingTop: "hide",
1567          paddingBottom: "hide",
1568          height: "hide"
1569      },
1570  
1571      showProps: {
1572          borderTopWidth: "show",
1573          borderBottomWidth: "show",
1574          paddingTop: "show",
1575          paddingBottom: "show",
1576          height: "show"
1577      },
1578  
1579      _create: function() {
1580          var options = this.options;
1581          this.prevShow = this.prevHide = $();
1582          this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
1583              // ARIA
1584              .attr( "role", "tablist" );
1585  
1586          // don't allow collapsible: false and active: false / null
1587          if ( !options.collapsible && (options.active === false || options.active == null) ) {
1588              options.active = 0;
1589          }
1590  
1591          this._processPanels();
1592          // handle negative values
1593          if ( options.active < 0 ) {
1594              options.active += this.headers.length;
1595          }
1596          this._refresh();
1597      },
1598  
1599      _getCreateEventData: function() {
1600          return {
1601              header: this.active,
1602              panel: !this.active.length ? $() : this.active.next()
1603          };
1604      },
1605  
1606      _createIcons: function() {
1607          var icons = this.options.icons;
1608          if ( icons ) {
1609              $( "<span>" )
1610                  .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
1611                  .prependTo( this.headers );
1612              this.active.children( ".ui-accordion-header-icon" )
1613                  .removeClass( icons.header )
1614                  .addClass( icons.activeHeader );
1615              this.headers.addClass( "ui-accordion-icons" );
1616          }
1617      },
1618  
1619      _destroyIcons: function() {
1620          this.headers
1621              .removeClass( "ui-accordion-icons" )
1622              .children( ".ui-accordion-header-icon" )
1623                  .remove();
1624      },
1625  
1626      _destroy: function() {
1627          var contents;
1628  
1629          // clean up main element
1630          this.element
1631              .removeClass( "ui-accordion ui-widget ui-helper-reset" )
1632              .removeAttr( "role" );
1633  
1634          // clean up headers
1635          this.headers
1636              .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
1637                  "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
1638              .removeAttr( "role" )
1639              .removeAttr( "aria-expanded" )
1640              .removeAttr( "aria-selected" )
1641              .removeAttr( "aria-controls" )
1642              .removeAttr( "tabIndex" )
1643              .removeUniqueId();
1644  
1645          this._destroyIcons();
1646  
1647          // clean up content panels
1648          contents = this.headers.next()
1649              .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
1650                  "ui-accordion-content ui-accordion-content-active ui-state-disabled" )
1651              .css( "display", "" )
1652              .removeAttr( "role" )
1653              .removeAttr( "aria-hidden" )
1654              .removeAttr( "aria-labelledby" )
1655              .removeUniqueId();
1656  
1657          if ( this.options.heightStyle !== "content" ) {
1658              contents.css( "height", "" );
1659          }
1660      },
1661  
1662      _setOption: function( key, value ) {
1663          if ( key === "active" ) {
1664              // _activate() will handle invalid values and update this.options
1665              this._activate( value );
1666              return;
1667          }
1668  
1669          if ( key === "event" ) {
1670              if ( this.options.event ) {
1671                  this._off( this.headers, this.options.event );
1672              }
1673              this._setupEvents( value );
1674          }
1675  
1676          this._super( key, value );
1677  
1678          // setting collapsible: false while collapsed; open first panel
1679          if ( key === "collapsible" && !value && this.options.active === false ) {
1680              this._activate( 0 );
1681          }
1682  
1683          if ( key === "icons" ) {
1684              this._destroyIcons();
1685              if ( value ) {
1686                  this._createIcons();
1687              }
1688          }
1689  
1690          // #5332 - opacity doesn't cascade to positioned elements in IE
1691          // so we need to add the disabled class to the headers and panels
1692          if ( key === "disabled" ) {
1693              this.element
1694                  .toggleClass( "ui-state-disabled", !!value )
1695                  .attr( "aria-disabled", value );
1696              this.headers.add( this.headers.next() )
1697                  .toggleClass( "ui-state-disabled", !!value );
1698          }
1699      },
1700  
1701      _keydown: function( event ) {
1702          if ( event.altKey || event.ctrlKey ) {
1703              return;
1704          }
1705  
1706          var keyCode = $.ui.keyCode,
1707              length = this.headers.length,
1708              currentIndex = this.headers.index( event.target ),
1709              toFocus = false;
1710  
1711          switch ( event.keyCode ) {
1712              case keyCode.RIGHT:
1713              case keyCode.DOWN:
1714                  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
1715                  break;
1716              case keyCode.LEFT:
1717              case keyCode.UP:
1718                  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
1719                  break;
1720              case keyCode.SPACE:
1721              case keyCode.ENTER:
1722                  this._eventHandler( event );
1723                  break;
1724              case keyCode.HOME:
1725                  toFocus = this.headers[ 0 ];
1726                  break;
1727              case keyCode.END:
1728                  toFocus = this.headers[ length - 1 ];
1729                  break;
1730          }
1731  
1732          if ( toFocus ) {
1733              $( event.target ).attr( "tabIndex", -1 );
1734              $( toFocus ).attr( "tabIndex", 0 );
1735              toFocus.focus();
1736              event.preventDefault();
1737          }
1738      },
1739  
1740      _panelKeyDown: function( event ) {
1741          if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
1742              $( event.currentTarget ).prev().focus();
1743          }
1744      },
1745  
1746      refresh: function() {
1747          var options = this.options;
1748          this._processPanels();
1749  
1750          // was collapsed or no panel
1751          if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
1752              options.active = false;
1753              this.active = $();
1754          // active false only when collapsible is true
1755          } else if ( options.active === false ) {
1756              this._activate( 0 );
1757          // was active, but active panel is gone
1758          } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
1759              // all remaining panel are disabled
1760              if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
1761                  options.active = false;
1762                  this.active = $();
1763              // activate previous panel
1764              } else {
1765                  this._activate( Math.max( 0, options.active - 1 ) );
1766              }
1767          // was active, active panel still exists
1768          } else {
1769              // make sure active index is correct
1770              options.active = this.headers.index( this.active );
1771          }
1772  
1773          this._destroyIcons();
1774  
1775          this._refresh();
1776      },
1777  
1778      _processPanels: function() {
1779          this.headers = this.element.find( this.options.header )
1780              .addClass( "ui-accordion-header ui-state-default ui-corner-all" );
1781  
1782          this.headers.next()
1783              .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
1784              .filter( ":not(.ui-accordion-content-active)" )
1785              .hide();
1786      },
1787  
1788      _refresh: function() {
1789          var maxHeight,
1790              options = this.options,
1791              heightStyle = options.heightStyle,
1792              parent = this.element.parent();
1793  
1794          this.active = this._findActive( options.active )
1795              .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
1796              .removeClass( "ui-corner-all" );
1797          this.active.next()
1798              .addClass( "ui-accordion-content-active" )
1799              .show();
1800  
1801          this.headers
1802              .attr( "role", "tab" )
1803              .each(function() {
1804                  var header = $( this ),
1805                      headerId = header.uniqueId().attr( "id" ),
1806                      panel = header.next(),
1807                      panelId = panel.uniqueId().attr( "id" );
1808                  header.attr( "aria-controls", panelId );
1809                  panel.attr( "aria-labelledby", headerId );
1810              })
1811              .next()
1812                  .attr( "role", "tabpanel" );
1813  
1814          this.headers
1815              .not( this.active )
1816              .attr({
1817                  "aria-selected": "false",
1818                  "aria-expanded": "false",
1819                  tabIndex: -1
1820              })
1821              .next()
1822                  .attr({
1823                      "aria-hidden": "true"
1824                  })
1825                  .hide();
1826  
1827          // make sure at least one header is in the tab order
1828          if ( !this.active.length ) {
1829              this.headers.eq( 0 ).attr( "tabIndex", 0 );
1830          } else {
1831              this.active.attr({
1832                  "aria-selected": "true",
1833                  "aria-expanded": "true",
1834                  tabIndex: 0
1835              })
1836              .next()
1837                  .attr({
1838                      "aria-hidden": "false"
1839                  });
1840          }
1841  
1842          this._createIcons();
1843  
1844          this._setupEvents( options.event );
1845  
1846          if ( heightStyle === "fill" ) {
1847              maxHeight = parent.height();
1848              this.element.siblings( ":visible" ).each(function() {
1849                  var elem = $( this ),
1850                      position = elem.css( "position" );
1851  
1852                  if ( position === "absolute" || position === "fixed" ) {
1853                      return;
1854                  }
1855                  maxHeight -= elem.outerHeight( true );
1856              });
1857  
1858              this.headers.each(function() {
1859                  maxHeight -= $( this ).outerHeight( true );
1860              });
1861  
1862              this.headers.next()
1863                  .each(function() {
1864                      $( this ).height( Math.max( 0, maxHeight -
1865                          $( this ).innerHeight() + $( this ).height() ) );
1866                  })
1867                  .css( "overflow", "auto" );
1868          } else if ( heightStyle === "auto" ) {
1869              maxHeight = 0;
1870              this.headers.next()
1871                  .each(function() {
1872                      maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
1873                  })
1874                  .height( maxHeight );
1875          }
1876      },
1877  
1878      _activate: function( index ) {
1879          var active = this._findActive( index )[ 0 ];
1880  
1881          // trying to activate the already active panel
1882          if ( active === this.active[ 0 ] ) {
1883              return;
1884          }
1885  
1886          // trying to collapse, simulate a click on the currently active header
1887          active = active || this.active[ 0 ];
1888  
1889          this._eventHandler({
1890              target: active,
1891              currentTarget: active,
1892              preventDefault: $.noop
1893          });
1894      },
1895  
1896      _findActive: function( selector ) {
1897          return typeof selector === "number" ? this.headers.eq( selector ) : $();
1898      },
1899  
1900      _setupEvents: function( event ) {
1901          var events = {
1902              keydown: "_keydown"
1903          };
1904          if ( event ) {
1905              $.each( event.split( " " ), function( index, eventName ) {
1906                  events[ eventName ] = "_eventHandler";
1907              });
1908          }
1909  
1910          this._off( this.headers.add( this.headers.next() ) );
1911          this._on( this.headers, events );
1912          this._on( this.headers.next(), { keydown: "_panelKeyDown" });
1913          this._hoverable( this.headers );
1914          this._focusable( this.headers );
1915      },
1916  
1917      _eventHandler: function( event ) {
1918          var options = this.options,
1919              active = this.active,
1920              clicked = $( event.currentTarget ),
1921              clickedIsActive = clicked[ 0 ] === active[ 0 ],
1922              collapsing = clickedIsActive && options.collapsible,
1923              toShow = collapsing ? $() : clicked.next(),
1924              toHide = active.next(),
1925              eventData = {
1926                  oldHeader: active,
1927                  oldPanel: toHide,
1928                  newHeader: collapsing ? $() : clicked,
1929                  newPanel: toShow
1930              };
1931  
1932          event.preventDefault();
1933  
1934          if (
1935                  // click on active header, but not collapsible
1936                  ( clickedIsActive && !options.collapsible ) ||
1937                  // allow canceling activation
1938                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
1939              return;
1940          }
1941  
1942          options.active = collapsing ? false : this.headers.index( clicked );
1943  
1944          // when the call to ._toggle() comes after the class changes
1945          // it causes a very odd bug in IE 8 (see #6720)
1946          this.active = clickedIsActive ? $() : clicked;
1947          this._toggle( eventData );
1948  
1949          // switch classes
1950          // corner classes on the previously active header stay after the animation
1951          active.removeClass( "ui-accordion-header-active ui-state-active" );
1952          if ( options.icons ) {
1953              active.children( ".ui-accordion-header-icon" )
1954                  .removeClass( options.icons.activeHeader )
1955                  .addClass( options.icons.header );
1956          }
1957  
1958          if ( !clickedIsActive ) {
1959              clicked
1960                  .removeClass( "ui-corner-all" )
1961                  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
1962              if ( options.icons ) {
1963                  clicked.children( ".ui-accordion-header-icon" )
1964                      .removeClass( options.icons.header )
1965                      .addClass( options.icons.activeHeader );
1966              }
1967  
1968              clicked
1969                  .next()
1970                  .addClass( "ui-accordion-content-active" );
1971          }
1972      },
1973  
1974      _toggle: function( data ) {
1975          var toShow = data.newPanel,
1976              toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
1977  
1978          // handle activating a panel during the animation for another activation
1979          this.prevShow.add( this.prevHide ).stop( true, true );
1980          this.prevShow = toShow;
1981          this.prevHide = toHide;
1982  
1983          if ( this.options.animate ) {
1984              this._animate( toShow, toHide, data );
1985          } else {
1986              toHide.hide();
1987              toShow.show();
1988              this._toggleComplete( data );
1989          }
1990  
1991          toHide.attr({
1992              "aria-hidden": "true"
1993          });
1994          toHide.prev().attr( "aria-selected", "false" );
1995          // if we're switching panels, remove the old header from the tab order
1996          // if we're opening from collapsed state, remove the previous header from the tab order
1997          // if we're collapsing, then keep the collapsing header in the tab order
1998          if ( toShow.length && toHide.length ) {
1999              toHide.prev().attr({
2000                  "tabIndex": -1,
2001                  "aria-expanded": "false"
2002              });
2003          } else if ( toShow.length ) {
2004              this.headers.filter(function() {
2005                  return $( this ).attr( "tabIndex" ) === 0;
2006              })
2007              .attr( "tabIndex", -1 );
2008          }
2009  
2010          toShow
2011              .attr( "aria-hidden", "false" )
2012              .prev()
2013                  .attr({
2014                      "aria-selected": "true",
2015                      tabIndex: 0,
2016                      "aria-expanded": "true"
2017                  });
2018      },
2019  
2020      _animate: function( toShow, toHide, data ) {
2021          var total, easing, duration,
2022              that = this,
2023              adjust = 0,
2024              down = toShow.length &&
2025                  ( !toHide.length || ( toShow.index() < toHide.index() ) ),
2026              animate = this.options.animate || {},
2027              options = down && animate.down || animate,
2028              complete = function() {
2029                  that._toggleComplete( data );
2030              };
2031  
2032          if ( typeof options === "number" ) {
2033              duration = options;
2034          }
2035          if ( typeof options === "string" ) {
2036              easing = options;
2037          }
2038          // fall back from options to animation in case of partial down settings
2039          easing = easing || options.easing || animate.easing;
2040          duration = duration || options.duration || animate.duration;
2041  
2042          if ( !toHide.length ) {
2043              return toShow.animate( this.showProps, duration, easing, complete );
2044          }
2045          if ( !toShow.length ) {
2046              return toHide.animate( this.hideProps, duration, easing, complete );
2047          }
2048  
2049          total = toShow.show().outerHeight();
2050          toHide.animate( this.hideProps, {
2051              duration: duration,
2052              easing: easing,
2053              step: function( now, fx ) {
2054                  fx.now = Math.round( now );
2055              }
2056          });
2057          toShow
2058              .hide()
2059              .animate( this.showProps, {
2060                  duration: duration,
2061                  easing: easing,
2062                  complete: complete,
2063                  step: function( now, fx ) {
2064                      fx.now = Math.round( now );
2065                      if ( fx.prop !== "height" ) {
2066                          adjust += fx.now;
2067                      } else if ( that.options.heightStyle !== "content" ) {
2068                          fx.now = Math.round( total - toHide.outerHeight() - adjust );
2069                          adjust = 0;
2070                      }
2071                  }
2072              });
2073      },
2074  
2075      _toggleComplete: function( data ) {
2076          var toHide = data.oldPanel;
2077  
2078          toHide
2079              .removeClass( "ui-accordion-content-active" )
2080              .prev()
2081                  .removeClass( "ui-corner-top" )
2082                  .addClass( "ui-corner-all" );
2083  
2084          // Work around for rendering bug in IE (#5421)
2085          if ( toHide.length ) {
2086              toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
2087          }
2088          this._trigger( "activate", null, data );
2089      }
2090  });
2091  
2092  
2093  /*!
2094   * jQuery UI Menu 1.11.1
2095   * http://jqueryui.com
2096   *
2097   * Copyright 2014 jQuery Foundation and other contributors
2098   * Released under the MIT license.
2099   * http://jquery.org/license
2100   *
2101   * http://api.jqueryui.com/menu/
2102   */
2103  
2104  
2105  var menu = $.widget( "ui.menu", {
2106      version: "1.11.1",
2107      defaultElement: "<ul>",
2108      delay: 300,
2109      options: {
2110          icons: {
2111              submenu: "ui-icon-carat-1-e"
2112          },
2113          items: "> *",
2114          menus: "ul",
2115          position: {
2116              my: "left-1 top",
2117              at: "right top"
2118          },
2119          role: "menu",
2120  
2121          // callbacks
2122          blur: null,
2123          focus: null,
2124          select: null
2125      },
2126  
2127      _create: function() {
2128          this.activeMenu = this.element;
2129  
2130          // Flag used to prevent firing of the click handler
2131          // as the event bubbles up through nested menus
2132          this.mouseHandled = false;
2133          this.element
2134              .uniqueId()
2135              .addClass( "ui-menu ui-widget ui-widget-content" )
2136              .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
2137              .attr({
2138                  role: this.options.role,
2139                  tabIndex: 0
2140              });
2141  
2142          if ( this.options.disabled ) {
2143              this.element
2144                  .addClass( "ui-state-disabled" )
2145                  .attr( "aria-disabled", "true" );
2146          }
2147  
2148          this._on({
2149              // Prevent focus from sticking to links inside menu after clicking
2150              // them (focus should always stay on UL during navigation).
2151              "mousedown .ui-menu-item": function( event ) {
2152                  event.preventDefault();
2153              },
2154              "click .ui-menu-item": function( event ) {
2155                  var target = $( event.target );
2156                  if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
2157                      this.select( event );
2158  
2159                      // Only set the mouseHandled flag if the event will bubble, see #9469.
2160                      if ( !event.isPropagationStopped() ) {
2161                          this.mouseHandled = true;
2162                      }
2163  
2164                      // Open submenu on click
2165                      if ( target.has( ".ui-menu" ).length ) {
2166                          this.expand( event );
2167                      } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
2168  
2169                          // Redirect focus to the menu
2170                          this.element.trigger( "focus", [ true ] );
2171  
2172                          // If the active item is on the top level, let it stay active.
2173                          // Otherwise, blur the active item since it is no longer visible.
2174                          if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
2175                              clearTimeout( this.timer );
2176                          }
2177                      }
2178                  }
2179              },
2180              "mouseenter .ui-menu-item": function( event ) {
2181                  var target = $( event.currentTarget );
2182                  // Remove ui-state-active class from siblings of the newly focused menu item
2183                  // to avoid a jump caused by adjacent elements both having a class with a border
2184                  target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
2185                  this.focus( event, target );
2186              },
2187              mouseleave: "collapseAll",
2188              "mouseleave .ui-menu": "collapseAll",
2189              focus: function( event, keepActiveItem ) {
2190                  // If there's already an active item, keep it active
2191                  // If not, activate the first item
2192                  var item = this.active || this.element.find( this.options.items ).eq( 0 );
2193  
2194                  if ( !keepActiveItem ) {
2195                      this.focus( event, item );
2196                  }
2197              },
2198              blur: function( event ) {
2199                  this._delay(function() {
2200                      if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
2201                          this.collapseAll( event );
2202                      }
2203                  });
2204              },
2205              keydown: "_keydown"
2206          });
2207  
2208          this.refresh();
2209  
2210          // Clicks outside of a menu collapse any open menus
2211          this._on( this.document, {
2212              click: function( event ) {
2213                  if ( this._closeOnDocumentClick( event ) ) {
2214                      this.collapseAll( event );
2215                  }
2216  
2217                  // Reset the mouseHandled flag
2218                  this.mouseHandled = false;
2219              }
2220          });
2221      },
2222  
2223      _destroy: function() {
2224          // Destroy (sub)menus
2225          this.element
2226              .removeAttr( "aria-activedescendant" )
2227              .find( ".ui-menu" ).addBack()
2228                  .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
2229                  .removeAttr( "role" )
2230                  .removeAttr( "tabIndex" )
2231                  .removeAttr( "aria-labelledby" )
2232                  .removeAttr( "aria-expanded" )
2233                  .removeAttr( "aria-hidden" )
2234                  .removeAttr( "aria-disabled" )
2235                  .removeUniqueId()
2236                  .show();
2237  
2238          // Destroy menu items
2239          this.element.find( ".ui-menu-item" )
2240              .removeClass( "ui-menu-item" )
2241              .removeAttr( "role" )
2242              .removeAttr( "aria-disabled" )
2243              .removeUniqueId()
2244              .removeClass( "ui-state-hover" )
2245              .removeAttr( "tabIndex" )
2246              .removeAttr( "role" )
2247              .removeAttr( "aria-haspopup" )
2248              .children().each( function() {
2249                  var elem = $( this );
2250                  if ( elem.data( "ui-menu-submenu-carat" ) ) {
2251                      elem.remove();
2252                  }
2253              });
2254  
2255          // Destroy menu dividers
2256          this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
2257      },
2258  
2259      _keydown: function( event ) {
2260          var match, prev, character, skip, regex,
2261              preventDefault = true;
2262  
2263  		function escape( value ) {
2264              return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
2265          }
2266  
2267          switch ( event.keyCode ) {
2268          case $.ui.keyCode.PAGE_UP:
2269              this.previousPage( event );
2270              break;
2271          case $.ui.keyCode.PAGE_DOWN:
2272              this.nextPage( event );
2273              break;
2274          case $.ui.keyCode.HOME:
2275              this._move( "first", "first", event );
2276              break;
2277          case $.ui.keyCode.END:
2278              this._move( "last", "last", event );
2279              break;
2280          case $.ui.keyCode.UP:
2281              this.previous( event );
2282              break;
2283          case $.ui.keyCode.DOWN:
2284              this.next( event );
2285              break;
2286          case $.ui.keyCode.LEFT:
2287              this.collapse( event );
2288              break;
2289          case $.ui.keyCode.RIGHT:
2290              if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
2291                  this.expand( event );
2292              }
2293              break;
2294          case $.ui.keyCode.ENTER:
2295          case $.ui.keyCode.SPACE:
2296              this._activate( event );
2297              break;
2298          case $.ui.keyCode.ESCAPE:
2299              this.collapse( event );
2300              break;
2301          default:
2302              preventDefault = false;
2303              prev = this.previousFilter || "";
2304              character = String.fromCharCode( event.keyCode );
2305              skip = false;
2306  
2307              clearTimeout( this.filterTimer );
2308  
2309              if ( character === prev ) {
2310                  skip = true;
2311              } else {
2312                  character = prev + character;
2313              }
2314  
2315              regex = new RegExp( "^" + escape( character ), "i" );
2316              match = this.activeMenu.find( this.options.items ).filter(function() {
2317                  return regex.test( $( this ).text() );
2318              });
2319              match = skip && match.index( this.active.next() ) !== -1 ?
2320                  this.active.nextAll( ".ui-menu-item" ) :
2321                  match;
2322  
2323              // If no matches on the current filter, reset to the last character pressed
2324              // to move down the menu to the first item that starts with that character
2325              if ( !match.length ) {
2326                  character = String.fromCharCode( event.keyCode );
2327                  regex = new RegExp( "^" + escape( character ), "i" );
2328                  match = this.activeMenu.find( this.options.items ).filter(function() {
2329                      return regex.test( $( this ).text() );
2330                  });
2331              }
2332  
2333              if ( match.length ) {
2334                  this.focus( event, match );
2335                  if ( match.length > 1 ) {
2336                      this.previousFilter = character;
2337                      this.filterTimer = this._delay(function() {
2338                          delete this.previousFilter;
2339                      }, 1000 );
2340                  } else {
2341                      delete this.previousFilter;
2342                  }
2343              } else {
2344                  delete this.previousFilter;
2345              }
2346          }
2347  
2348          if ( preventDefault ) {
2349              event.preventDefault();
2350          }
2351      },
2352  
2353      _activate: function( event ) {
2354          if ( !this.active.is( ".ui-state-disabled" ) ) {
2355              if ( this.active.is( "[aria-haspopup='true']" ) ) {
2356                  this.expand( event );
2357              } else {
2358                  this.select( event );
2359              }
2360          }
2361      },
2362  
2363      refresh: function() {
2364          var menus, items,
2365              that = this,
2366              icon = this.options.icons.submenu,
2367              submenus = this.element.find( this.options.menus );
2368  
2369          this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
2370  
2371          // Initialize nested menus
2372          submenus.filter( ":not(.ui-menu)" )
2373              .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
2374              .hide()
2375              .attr({
2376                  role: this.options.role,
2377                  "aria-hidden": "true",
2378                  "aria-expanded": "false"
2379              })
2380              .each(function() {
2381                  var menu = $( this ),
2382                      item = menu.parent(),
2383                      submenuCarat = $( "<span>" )
2384                          .addClass( "ui-menu-icon ui-icon " + icon )
2385                          .data( "ui-menu-submenu-carat", true );
2386  
2387                  item
2388                      .attr( "aria-haspopup", "true" )
2389                      .prepend( submenuCarat );
2390                  menu.attr( "aria-labelledby", item.attr( "id" ) );
2391              });
2392  
2393          menus = submenus.add( this.element );
2394          items = menus.find( this.options.items );
2395  
2396          // Initialize menu-items containing spaces and/or dashes only as dividers
2397          items.not( ".ui-menu-item" ).each(function() {
2398              var item = $( this );
2399              if ( that._isDivider( item ) ) {
2400                  item.addClass( "ui-widget-content ui-menu-divider" );
2401              }
2402          });
2403  
2404          // Don't refresh list items that are already adapted
2405          items.not( ".ui-menu-item, .ui-menu-divider" )
2406              .addClass( "ui-menu-item" )
2407              .uniqueId()
2408              .attr({
2409                  tabIndex: -1,
2410                  role: this._itemRole()
2411              });
2412  
2413          // Add aria-disabled attribute to any disabled menu item
2414          items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
2415  
2416          // If the active item has been removed, blur the menu
2417          if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
2418              this.blur();
2419          }
2420      },
2421  
2422      _itemRole: function() {
2423          return {
2424              menu: "menuitem",
2425              listbox: "option"
2426          }[ this.options.role ];
2427      },
2428  
2429      _setOption: function( key, value ) {
2430          if ( key === "icons" ) {
2431              this.element.find( ".ui-menu-icon" )
2432                  .removeClass( this.options.icons.submenu )
2433                  .addClass( value.submenu );
2434          }
2435          if ( key === "disabled" ) {
2436              this.element
2437                  .toggleClass( "ui-state-disabled", !!value )
2438                  .attr( "aria-disabled", value );
2439          }
2440          this._super( key, value );
2441      },
2442  
2443      focus: function( event, item ) {
2444          var nested, focused;
2445          this.blur( event, event && event.type === "focus" );
2446  
2447          this._scrollIntoView( item );
2448  
2449          this.active = item.first();
2450          focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
2451          // Only update aria-activedescendant if there's a role
2452          // otherwise we assume focus is managed elsewhere
2453          if ( this.options.role ) {
2454              this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
2455          }
2456  
2457          // Highlight active parent menu item, if any
2458          this.active
2459              .parent()
2460              .closest( ".ui-menu-item" )
2461              .addClass( "ui-state-active" );
2462  
2463          if ( event && event.type === "keydown" ) {
2464              this._close();
2465          } else {
2466              this.timer = this._delay(function() {
2467                  this._close();
2468              }, this.delay );
2469          }
2470  
2471          nested = item.children( ".ui-menu" );
2472          if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
2473              this._startOpening(nested);
2474          }
2475          this.activeMenu = item.parent();
2476  
2477          this._trigger( "focus", event, { item: item } );
2478      },
2479  
2480      _scrollIntoView: function( item ) {
2481          var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
2482          if ( this._hasScroll() ) {
2483              borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
2484              paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
2485              offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
2486              scroll = this.activeMenu.scrollTop();
2487              elementHeight = this.activeMenu.height();
2488              itemHeight = item.outerHeight();
2489  
2490              if ( offset < 0 ) {
2491                  this.activeMenu.scrollTop( scroll + offset );
2492              } else if ( offset + itemHeight > elementHeight ) {
2493                  this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
2494              }
2495          }
2496      },
2497  
2498      blur: function( event, fromFocus ) {
2499          if ( !fromFocus ) {
2500              clearTimeout( this.timer );
2501          }
2502  
2503          if ( !this.active ) {
2504              return;
2505          }
2506  
2507          this.active.removeClass( "ui-state-focus" );
2508          this.active = null;
2509  
2510          this._trigger( "blur", event, { item: this.active } );
2511      },
2512  
2513      _startOpening: function( submenu ) {
2514          clearTimeout( this.timer );
2515  
2516          // Don't open if already open fixes a Firefox bug that caused a .5 pixel
2517          // shift in the submenu position when mousing over the carat icon
2518          if ( submenu.attr( "aria-hidden" ) !== "true" ) {
2519              return;
2520          }
2521  
2522          this.timer = this._delay(function() {
2523              this._close();
2524              this._open( submenu );
2525          }, this.delay );
2526      },
2527  
2528      _open: function( submenu ) {
2529          var position = $.extend({
2530              of: this.active
2531          }, this.options.position );
2532  
2533          clearTimeout( this.timer );
2534          this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
2535              .hide()
2536              .attr( "aria-hidden", "true" );
2537  
2538          submenu
2539              .show()
2540              .removeAttr( "aria-hidden" )
2541              .attr( "aria-expanded", "true" )
2542              .position( position );
2543      },
2544  
2545      collapseAll: function( event, all ) {
2546          clearTimeout( this.timer );
2547          this.timer = this._delay(function() {
2548              // If we were passed an event, look for the submenu that contains the event
2549              var currentMenu = all ? this.element :
2550                  $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
2551  
2552              // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
2553              if ( !currentMenu.length ) {
2554                  currentMenu = this.element;
2555              }
2556  
2557              this._close( currentMenu );
2558  
2559              this.blur( event );
2560              this.activeMenu = currentMenu;
2561          }, this.delay );
2562      },
2563  
2564      // With no arguments, closes the currently active menu - if nothing is active
2565      // it closes all menus.  If passed an argument, it will search for menus BELOW
2566      _close: function( startMenu ) {
2567          if ( !startMenu ) {
2568              startMenu = this.active ? this.active.parent() : this.element;
2569          }
2570  
2571          startMenu
2572              .find( ".ui-menu" )
2573                  .hide()
2574                  .attr( "aria-hidden", "true" )
2575                  .attr( "aria-expanded", "false" )
2576              .end()
2577              .find( ".ui-state-active" ).not( ".ui-state-focus" )
2578                  .removeClass( "ui-state-active" );
2579      },
2580  
2581      _closeOnDocumentClick: function( event ) {
2582          return !$( event.target ).closest( ".ui-menu" ).length;
2583      },
2584  
2585      _isDivider: function( item ) {
2586  
2587          // Match hyphen, em dash, en dash
2588          return !/[^\-\u2014\u2013\s]/.test( item.text() );
2589      },
2590  
2591      collapse: function( event ) {
2592          var newItem = this.active &&
2593              this.active.parent().closest( ".ui-menu-item", this.element );
2594          if ( newItem && newItem.length ) {
2595              this._close();
2596              this.focus( event, newItem );
2597          }
2598      },
2599  
2600      expand: function( event ) {
2601          var newItem = this.active &&
2602              this.active
2603                  .children( ".ui-menu " )
2604                  .find( this.options.items )
2605                  .first();
2606  
2607          if ( newItem && newItem.length ) {
2608              this._open( newItem.parent() );
2609  
2610              // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
2611              this._delay(function() {
2612                  this.focus( event, newItem );
2613              });
2614          }
2615      },
2616  
2617      next: function( event ) {
2618          this._move( "next", "first", event );
2619      },
2620  
2621      previous: function( event ) {
2622          this._move( "prev", "last", event );
2623      },
2624  
2625      isFirstItem: function() {
2626          return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
2627      },
2628  
2629      isLastItem: function() {
2630          return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
2631      },
2632  
2633      _move: function( direction, filter, event ) {
2634          var next;
2635          if ( this.active ) {
2636              if ( direction === "first" || direction === "last" ) {
2637                  next = this.active
2638                      [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
2639                      .eq( -1 );
2640              } else {
2641                  next = this.active
2642                      [ direction + "All" ]( ".ui-menu-item" )
2643                      .eq( 0 );
2644              }
2645          }
2646          if ( !next || !next.length || !this.active ) {
2647              next = this.activeMenu.find( this.options.items )[ filter ]();
2648          }
2649  
2650          this.focus( event, next );
2651      },
2652  
2653      nextPage: function( event ) {
2654          var item, base, height;
2655  
2656          if ( !this.active ) {
2657              this.next( event );
2658              return;
2659          }
2660          if ( this.isLastItem() ) {
2661              return;
2662          }
2663          if ( this._hasScroll() ) {
2664              base = this.active.offset().top;
2665              height = this.element.height();
2666              this.active.nextAll( ".ui-menu-item" ).each(function() {
2667                  item = $( this );
2668                  return item.offset().top - base - height < 0;
2669              });
2670  
2671              this.focus( event, item );
2672          } else {
2673              this.focus( event, this.activeMenu.find( this.options.items )
2674                  [ !this.active ? "first" : "last" ]() );
2675          }
2676      },
2677  
2678      previousPage: function( event ) {
2679          var item, base, height;
2680          if ( !this.active ) {
2681              this.next( event );
2682              return;
2683          }
2684          if ( this.isFirstItem() ) {
2685              return;
2686          }
2687          if ( this._hasScroll() ) {
2688              base = this.active.offset().top;
2689              height = this.element.height();
2690              this.active.prevAll( ".ui-menu-item" ).each(function() {
2691                  item = $( this );
2692                  return item.offset().top - base + height > 0;
2693              });
2694  
2695              this.focus( event, item );
2696          } else {
2697              this.focus( event, this.activeMenu.find( this.options.items ).first() );
2698          }
2699      },
2700  
2701      _hasScroll: function() {
2702          return this.element.outerHeight() < this.element.prop( "scrollHeight" );
2703      },
2704  
2705      select: function( event ) {
2706          // TODO: It should never be possible to not have an active item at this
2707          // point, but the tests don't trigger mouseenter before click.
2708          this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
2709          var ui = { item: this.active };
2710          if ( !this.active.has( ".ui-menu" ).length ) {
2711              this.collapseAll( event, true );
2712          }
2713          this._trigger( "select", event, ui );
2714      }
2715  });
2716  
2717  
2718  /*!
2719   * jQuery UI Autocomplete 1.11.1
2720   * http://jqueryui.com
2721   *
2722   * Copyright 2014 jQuery Foundation and other contributors
2723   * Released under the MIT license.
2724   * http://jquery.org/license
2725   *
2726   * http://api.jqueryui.com/autocomplete/
2727   */
2728  
2729  
2730  $.widget( "ui.autocomplete", {
2731      version: "1.11.1",
2732      defaultElement: "<input>",
2733      options: {
2734          appendTo: null,
2735          autoFocus: false,
2736          delay: 300,
2737          minLength: 1,
2738          position: {
2739              my: "left top",
2740              at: "left bottom",
2741              collision: "none"
2742          },
2743          source: null,
2744  
2745          // callbacks
2746          change: null,
2747          close: null,
2748          focus: null,
2749          open: null,
2750          response: null,
2751          search: null,
2752          select: null
2753      },
2754  
2755      requestIndex: 0,
2756      pending: 0,
2757  
2758      _create: function() {
2759          // Some browsers only repeat keydown events, not keypress events,
2760          // so we use the suppressKeyPress flag to determine if we've already
2761          // handled the keydown event. #7269
2762          // Unfortunately the code for & in keypress is the same as the up arrow,
2763          // so we use the suppressKeyPressRepeat flag to avoid handling keypress
2764          // events when we know the keydown event was used to modify the
2765          // search term. #7799
2766          var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
2767              nodeName = this.element[ 0 ].nodeName.toLowerCase(),
2768              isTextarea = nodeName === "textarea",
2769              isInput = nodeName === "input";
2770  
2771          this.isMultiLine =
2772              // Textareas are always multi-line
2773              isTextarea ? true :
2774              // Inputs are always single-line, even if inside a contentEditable element
2775              // IE also treats inputs as contentEditable
2776              isInput ? false :
2777              // All other element types are determined by whether or not they're contentEditable
2778              this.element.prop( "isContentEditable" );
2779  
2780          this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
2781          this.isNewMenu = true;
2782  
2783          this.element
2784              .addClass( "ui-autocomplete-input" )
2785              .attr( "autocomplete", "off" );
2786  
2787          this._on( this.element, {
2788              keydown: function( event ) {
2789                  if ( this.element.prop( "readOnly" ) ) {
2790                      suppressKeyPress = true;
2791                      suppressInput = true;
2792                      suppressKeyPressRepeat = true;
2793                      return;
2794                  }
2795  
2796                  suppressKeyPress = false;
2797                  suppressInput = false;
2798                  suppressKeyPressRepeat = false;
2799                  var keyCode = $.ui.keyCode;
2800                  switch ( event.keyCode ) {
2801                  case keyCode.PAGE_UP:
2802                      suppressKeyPress = true;
2803                      this._move( "previousPage", event );
2804                      break;
2805                  case keyCode.PAGE_DOWN:
2806                      suppressKeyPress = true;
2807                      this._move( "nextPage", event );
2808                      break;
2809                  case keyCode.UP:
2810                      suppressKeyPress = true;
2811                      this._keyEvent( "previous", event );
2812                      break;
2813                  case keyCode.DOWN:
2814                      suppressKeyPress = true;
2815                      this._keyEvent( "next", event );
2816                      break;
2817                  case keyCode.ENTER:
2818                      // when menu is open and has focus
2819                      if ( this.menu.active ) {
2820                          // #6055 - Opera still allows the keypress to occur
2821                          // which causes forms to submit
2822                          suppressKeyPress = true;
2823                          event.preventDefault();
2824                          this.menu.select( event );
2825                      }
2826                      break;
2827                  case keyCode.TAB:
2828                      if ( this.menu.active ) {
2829                          this.menu.select( event );
2830                      }
2831                      break;
2832                  case keyCode.ESCAPE:
2833                      if ( this.menu.element.is( ":visible" ) ) {
2834                          if ( !this.isMultiLine ) {
2835                              this._value( this.term );
2836                          }
2837                          this.close( event );
2838                          // Different browsers have different default behavior for escape
2839                          // Single press can mean undo or clear
2840                          // Double press in IE means clear the whole form
2841                          event.preventDefault();
2842                      }
2843                      break;
2844                  default:
2845                      suppressKeyPressRepeat = true;
2846                      // search timeout should be triggered before the input value is changed
2847                      this._searchTimeout( event );
2848                      break;
2849                  }
2850              },
2851              keypress: function( event ) {
2852                  if ( suppressKeyPress ) {
2853                      suppressKeyPress = false;
2854                      if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
2855                          event.preventDefault();
2856                      }
2857                      return;
2858                  }
2859                  if ( suppressKeyPressRepeat ) {
2860                      return;
2861                  }
2862  
2863                  // replicate some key handlers to allow them to repeat in Firefox and Opera
2864                  var keyCode = $.ui.keyCode;
2865                  switch ( event.keyCode ) {
2866                  case keyCode.PAGE_UP:
2867                      this._move( "previousPage", event );
2868                      break;
2869                  case keyCode.PAGE_DOWN:
2870                      this._move( "nextPage", event );
2871                      break;
2872                  case keyCode.UP:
2873                      this._keyEvent( "previous", event );
2874                      break;
2875                  case keyCode.DOWN:
2876                      this._keyEvent( "next", event );
2877                      break;
2878                  }
2879              },
2880              input: function( event ) {
2881                  if ( suppressInput ) {
2882                      suppressInput = false;
2883                      event.preventDefault();
2884                      return;
2885                  }
2886                  this._searchTimeout( event );
2887              },
2888              focus: function() {
2889                  this.selectedItem = null;
2890                  this.previous = this._value();
2891              },
2892              blur: function( event ) {
2893                  if ( this.cancelBlur ) {
2894                      delete this.cancelBlur;
2895                      return;
2896                  }
2897  
2898                  clearTimeout( this.searching );
2899                  this.close( event );
2900                  this._change( event );
2901              }
2902          });
2903  
2904          this._initSource();
2905          this.menu = $( "<ul>" )
2906              .addClass( "ui-autocomplete ui-front" )
2907              .appendTo( this._appendTo() )
2908              .menu({
2909                  // disable ARIA support, the live region takes care of that
2910                  role: null
2911              })
2912              .hide()
2913              .menu( "instance" );
2914  
2915          this._on( this.menu.element, {
2916              mousedown: function( event ) {
2917                  // prevent moving focus out of the text field
2918                  event.preventDefault();
2919  
2920                  // IE doesn't prevent moving focus even with event.preventDefault()
2921                  // so we set a flag to know when we should ignore the blur event
2922                  this.cancelBlur = true;
2923                  this._delay(function() {
2924                      delete this.cancelBlur;
2925                  });
2926  
2927                  // clicking on the scrollbar causes focus to shift to the body
2928                  // but we can't detect a mouseup or a click immediately afterward
2929                  // so we have to track the next mousedown and close the menu if
2930                  // the user clicks somewhere outside of the autocomplete
2931                  var menuElement = this.menu.element[ 0 ];
2932                  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
2933                      this._delay(function() {
2934                          var that = this;
2935                          this.document.one( "mousedown", function( event ) {
2936                              if ( event.target !== that.element[ 0 ] &&
2937                                      event.target !== menuElement &&
2938                                      !$.contains( menuElement, event.target ) ) {
2939                                  that.close();
2940                              }
2941                          });
2942                      });
2943                  }
2944              },
2945              menufocus: function( event, ui ) {
2946                  var label, item;
2947                  // support: Firefox
2948                  // Prevent accidental activation of menu items in Firefox (#7024 #9118)
2949                  if ( this.isNewMenu ) {
2950                      this.isNewMenu = false;
2951                      if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
2952                          this.menu.blur();
2953  
2954                          this.document.one( "mousemove", function() {
2955                              $( event.target ).trigger( event.originalEvent );
2956                          });
2957  
2958                          return;
2959                      }
2960                  }
2961  
2962                  item = ui.item.data( "ui-autocomplete-item" );
2963                  if ( false !== this._trigger( "focus", event, { item: item } ) ) {
2964                      // use value to match what will end up in the input, if it was a key event
2965                      if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
2966                          this._value( item.value );
2967                      }
2968                  }
2969  
2970                  // Announce the value in the liveRegion
2971                  label = ui.item.attr( "aria-label" ) || item.value;
2972                  if ( label && $.trim( label ).length ) {
2973                      this.liveRegion.children().hide();
2974                      $( "<div>" ).text( label ).appendTo( this.liveRegion );
2975                  }
2976              },
2977              menuselect: function( event, ui ) {
2978                  var item = ui.item.data( "ui-autocomplete-item" ),
2979                      previous = this.previous;
2980  
2981                  // only trigger when focus was lost (click on menu)
2982                  if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
2983                      this.element.focus();
2984                      this.previous = previous;
2985                      // #6109 - IE triggers two focus events and the second
2986                      // is asynchronous, so we need to reset the previous
2987                      // term synchronously and asynchronously :-(
2988                      this._delay(function() {
2989                          this.previous = previous;
2990                          this.selectedItem = item;
2991                      });
2992                  }
2993  
2994                  if ( false !== this._trigger( "select", event, { item: item } ) ) {
2995                      this._value( item.value );
2996                  }
2997                  // reset the term after the select event
2998                  // this allows custom select handling to work properly
2999                  this.term = this._value();
3000  
3001                  this.close( event );
3002                  this.selectedItem = item;
3003              }
3004          });
3005  
3006          this.liveRegion = $( "<span>", {
3007                  role: "status",
3008                  "aria-live": "assertive",
3009                  "aria-relevant": "additions"
3010              })
3011              .addClass( "ui-helper-hidden-accessible" )
3012              .appendTo( this.document[ 0 ].body );
3013  
3014          // turning off autocomplete prevents the browser from remembering the
3015          // value when navigating through history, so we re-enable autocomplete
3016          // if the page is unloaded before the widget is destroyed. #7790
3017          this._on( this.window, {
3018              beforeunload: function() {
3019                  this.element.removeAttr( "autocomplete" );
3020              }
3021          });
3022      },
3023  
3024      _destroy: function() {
3025          clearTimeout( this.searching );
3026          this.element
3027              .removeClass( "ui-autocomplete-input" )
3028              .removeAttr( "autocomplete" );
3029          this.menu.element.remove();
3030          this.liveRegion.remove();
3031      },
3032  
3033      _setOption: function( key, value ) {
3034          this._super( key, value );
3035          if ( key === "source" ) {
3036              this._initSource();
3037          }
3038          if ( key === "appendTo" ) {
3039              this.menu.element.appendTo( this._appendTo() );
3040          }
3041          if ( key === "disabled" && value && this.xhr ) {
3042              this.xhr.abort();
3043          }
3044      },
3045  
3046      _appendTo: function() {
3047          var element = this.options.appendTo;
3048  
3049          if ( element ) {
3050              element = element.jquery || element.nodeType ?
3051                  $( element ) :
3052                  this.document.find( element ).eq( 0 );
3053          }
3054  
3055          if ( !element || !element[ 0 ] ) {
3056              element = this.element.closest( ".ui-front" );
3057          }
3058  
3059          if ( !element.length ) {
3060              element = this.document[ 0 ].body;
3061          }
3062  
3063          return element;
3064      },
3065  
3066      _initSource: function() {
3067          var array, url,
3068              that = this;
3069          if ( $.isArray( this.options.source ) ) {
3070              array = this.options.source;
3071              this.source = function( request, response ) {
3072                  response( $.ui.autocomplete.filter( array, request.term ) );
3073              };
3074          } else if ( typeof this.options.source === "string" ) {
3075              url = this.options.source;
3076              this.source = function( request, response ) {
3077                  if ( that.xhr ) {
3078                      that.xhr.abort();
3079                  }
3080                  that.xhr = $.ajax({
3081                      url: url,
3082                      data: request,
3083                      dataType: "json",
3084                      success: function( data ) {
3085                          response( data );
3086                      },
3087                      error: function() {
3088                          response([]);
3089                      }
3090                  });
3091              };
3092          } else {
3093              this.source = this.options.source;
3094          }
3095      },
3096  
3097      _searchTimeout: function( event ) {
3098          clearTimeout( this.searching );
3099          this.searching = this._delay(function() {
3100  
3101              // Search if the value has changed, or if the user retypes the same value (see #7434)
3102              var equalValues = this.term === this._value(),
3103                  menuVisible = this.menu.element.is( ":visible" ),
3104                  modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
3105  
3106              if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
3107                  this.selectedItem = null;
3108                  this.search( null, event );
3109              }
3110          }, this.options.delay );
3111      },
3112  
3113      search: function( value, event ) {
3114          value = value != null ? value : this._value();
3115  
3116          // always save the actual value, not the one passed as an argument
3117          this.term = this._value();
3118  
3119          if ( value.length < this.options.minLength ) {
3120              return this.close( event );
3121          }
3122  
3123          if ( this._trigger( "search", event ) === false ) {
3124              return;
3125          }
3126  
3127          return this._search( value );
3128      },
3129  
3130      _search: function( value ) {
3131          this.pending++;
3132          this.element.addClass( "ui-autocomplete-loading" );
3133          this.cancelSearch = false;
3134  
3135          this.source( { term: value }, this._response() );
3136      },
3137  
3138      _response: function() {
3139          var index = ++this.requestIndex;
3140  
3141          return $.proxy(function( content ) {
3142              if ( index === this.requestIndex ) {
3143                  this.__response( content );
3144              }
3145  
3146              this.pending--;
3147              if ( !this.pending ) {
3148                  this.element.removeClass( "ui-autocomplete-loading" );
3149              }
3150          }, this );
3151      },
3152  
3153      __response: function( content ) {
3154          if ( content ) {
3155              content = this._normalize( content );
3156          }
3157          this._trigger( "response", null, { content: content } );
3158          if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
3159              this._suggest( content );
3160              this._trigger( "open" );
3161          } else {
3162              // use ._close() instead of .close() so we don't cancel future searches
3163              this._close();
3164          }
3165      },
3166  
3167      close: function( event ) {
3168          this.cancelSearch = true;
3169          this._close( event );
3170      },
3171  
3172      _close: function( event ) {
3173          if ( this.menu.element.is( ":visible" ) ) {
3174              this.menu.element.hide();
3175              this.menu.blur();
3176              this.isNewMenu = true;
3177              this._trigger( "close", event );
3178          }
3179      },
3180  
3181      _change: function( event ) {
3182          if ( this.previous !== this._value() ) {
3183              this._trigger( "change", event, { item: this.selectedItem } );
3184          }
3185      },
3186  
3187      _normalize: function( items ) {
3188          // assume all items have the right format when the first item is complete
3189          if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
3190              return items;
3191          }
3192          return $.map( items, function( item ) {
3193              if ( typeof item === "string" ) {
3194                  return {
3195                      label: item,
3196                      value: item
3197                  };
3198              }
3199              return $.extend( {}, item, {
3200                  label: item.label || item.value,
3201                  value: item.value || item.label
3202              });
3203          });
3204      },
3205  
3206      _suggest: function( items ) {
3207          var ul = this.menu.element.empty();
3208          this._renderMenu( ul, items );
3209          this.isNewMenu = true;
3210          this.menu.refresh();
3211  
3212          // size and position menu
3213          ul.show();
3214          this._resizeMenu();
3215          ul.position( $.extend({
3216              of: this.element
3217          }, this.options.position ) );
3218  
3219          if ( this.options.autoFocus ) {
3220              this.menu.next();
3221          }
3222      },
3223  
3224      _resizeMenu: function() {
3225          var ul = this.menu.element;
3226          ul.outerWidth( Math.max(
3227              // Firefox wraps long text (possibly a rounding bug)
3228              // so we add 1px to avoid the wrapping (#7513)
3229              ul.width( "" ).outerWidth() + 1,
3230              this.element.outerWidth()
3231          ) );
3232      },
3233  
3234      _renderMenu: function( ul, items ) {
3235          var that = this;
3236          $.each( items, function( index, item ) {
3237              that._renderItemData( ul, item );
3238          });
3239      },
3240  
3241      _renderItemData: function( ul, item ) {
3242          return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
3243      },
3244  
3245      _renderItem: function( ul, item ) {
3246          return $( "<li>" ).text( item.label ).appendTo( ul );
3247      },
3248  
3249      _move: function( direction, event ) {
3250          if ( !this.menu.element.is( ":visible" ) ) {
3251              this.search( null, event );
3252              return;
3253          }
3254          if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
3255                  this.menu.isLastItem() && /^next/.test( direction ) ) {
3256  
3257              if ( !this.isMultiLine ) {
3258                  this._value( this.term );
3259              }
3260  
3261              this.menu.blur();
3262              return;
3263          }
3264          this.menu[ direction ]( event );
3265      },
3266  
3267      widget: function() {
3268          return this.menu.element;
3269      },
3270  
3271      _value: function() {
3272          return this.valueMethod.apply( this.element, arguments );
3273      },
3274  
3275      _keyEvent: function( keyEvent, event ) {
3276          if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
3277              this._move( keyEvent, event );
3278  
3279              // prevents moving cursor to beginning/end of the text field in some browsers
3280              event.preventDefault();
3281          }
3282      }
3283  });
3284  
3285  $.extend( $.ui.autocomplete, {
3286      escapeRegex: function( value ) {
3287          return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
3288      },
3289      filter: function( array, term ) {
3290          var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
3291          return $.grep( array, function( value ) {
3292              return matcher.test( value.label || value.value || value );
3293          });
3294      }
3295  });
3296  
3297  // live region extension, adding a `messages` option
3298  // NOTE: This is an experimental API. We are still investigating
3299  // a full solution for string manipulation and internationalization.
3300  $.widget( "ui.autocomplete", $.ui.autocomplete, {
3301      options: {
3302          messages: {
3303              noResults: "No search results.",
3304              results: function( amount ) {
3305                  return amount + ( amount > 1 ? " results are" : " result is" ) +
3306                      " available, use up and down arrow keys to navigate.";
3307              }
3308          }
3309      },
3310  
3311      __response: function( content ) {
3312          var message;
3313          this._superApply( arguments );
3314          if ( this.options.disabled || this.cancelSearch ) {
3315              return;
3316          }
3317          if ( content && content.length ) {
3318              message = this.options.messages.results( content.length );
3319          } else {
3320              message = this.options.messages.noResults;
3321          }
3322          this.liveRegion.children().hide();
3323          $( "<div>" ).text( message ).appendTo( this.liveRegion );
3324      }
3325  });
3326  
3327  var autocomplete = $.ui.autocomplete;
3328  
3329  
3330  /*!
3331   * jQuery UI Button 1.11.1
3332   * http://jqueryui.com
3333   *
3334   * Copyright 2014 jQuery Foundation and other contributors
3335   * Released under the MIT license.
3336   * http://jquery.org/license
3337   *
3338   * http://api.jqueryui.com/button/
3339   */
3340  
3341  
3342  var lastActive,
3343      baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
3344      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",
3345      formResetHandler = function() {
3346          var form = $( this );
3347          setTimeout(function() {
3348              form.find( ":ui-button" ).button( "refresh" );
3349          }, 1 );
3350      },
3351      radioGroup = function( radio ) {
3352          var name = radio.name,
3353              form = radio.form,
3354              radios = $( [] );
3355          if ( name ) {
3356              name = name.replace( /'/g, "\\'" );
3357              if ( form ) {
3358                  radios = $( form ).find( "[name='" + name + "'][type=radio]" );
3359              } else {
3360                  radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
3361                      .filter(function() {
3362                          return !this.form;
3363                      });
3364              }
3365          }
3366          return radios;
3367      };
3368  
3369  $.widget( "ui.button", {
3370      version: "1.11.1",
3371      defaultElement: "<button>",
3372      options: {
3373          disabled: null,
3374          text: true,
3375          label: null,
3376          icons: {
3377              primary: null,
3378              secondary: null
3379          }
3380      },
3381      _create: function() {
3382          this.element.closest( "form" )
3383              .unbind( "reset" + this.eventNamespace )
3384              .bind( "reset" + this.eventNamespace, formResetHandler );
3385  
3386          if ( typeof this.options.disabled !== "boolean" ) {
3387              this.options.disabled = !!this.element.prop( "disabled" );
3388          } else {
3389              this.element.prop( "disabled", this.options.disabled );
3390          }
3391  
3392          this._determineButtonType();
3393          this.hasTitle = !!this.buttonElement.attr( "title" );
3394  
3395          var that = this,
3396              options = this.options,
3397              toggleButton = this.type === "checkbox" || this.type === "radio",
3398              activeClass = !toggleButton ? "ui-state-active" : "";
3399  
3400          if ( options.label === null ) {
3401              options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
3402          }
3403  
3404          this._hoverable( this.buttonElement );
3405  
3406          this.buttonElement
3407              .addClass( baseClasses )
3408              .attr( "role", "button" )
3409              .bind( "mouseenter" + this.eventNamespace, function() {
3410                  if ( options.disabled ) {
3411                      return;
3412                  }
3413                  if ( this === lastActive ) {
3414                      $( this ).addClass( "ui-state-active" );
3415                  }
3416              })
3417              .bind( "mouseleave" + this.eventNamespace, function() {
3418                  if ( options.disabled ) {
3419                      return;
3420                  }
3421                  $( this ).removeClass( activeClass );
3422              })
3423              .bind( "click" + this.eventNamespace, function( event ) {
3424                  if ( options.disabled ) {
3425                      event.preventDefault();
3426                      event.stopImmediatePropagation();
3427                  }
3428              });
3429  
3430          // Can't use _focusable() because the element that receives focus
3431          // and the element that gets the ui-state-focus class are different
3432          this._on({
3433              focus: function() {
3434                  this.buttonElement.addClass( "ui-state-focus" );
3435              },
3436              blur: function() {
3437                  this.buttonElement.removeClass( "ui-state-focus" );
3438              }
3439          });
3440  
3441          if ( toggleButton ) {
3442              this.element.bind( "change" + this.eventNamespace, function() {
3443                  that.refresh();
3444              });
3445          }
3446  
3447          if ( this.type === "checkbox" ) {
3448              this.buttonElement.bind( "click" + this.eventNamespace, function() {
3449                  if ( options.disabled ) {
3450                      return false;
3451                  }
3452              });
3453          } else if ( this.type === "radio" ) {
3454              this.buttonElement.bind( "click" + this.eventNamespace, function() {
3455                  if ( options.disabled ) {
3456                      return false;
3457                  }
3458                  $( this ).addClass( "ui-state-active" );
3459                  that.buttonElement.attr( "aria-pressed", "true" );
3460  
3461                  var radio = that.element[ 0 ];
3462                  radioGroup( radio )
3463                      .not( radio )
3464                      .map(function() {
3465                          return $( this ).button( "widget" )[ 0 ];
3466                      })
3467                      .removeClass( "ui-state-active" )
3468                      .attr( "aria-pressed", "false" );
3469              });
3470          } else {
3471              this.buttonElement
3472                  .bind( "mousedown" + this.eventNamespace, function() {
3473                      if ( options.disabled ) {
3474                          return false;
3475                      }
3476                      $( this ).addClass( "ui-state-active" );
3477                      lastActive = this;
3478                      that.document.one( "mouseup", function() {
3479                          lastActive = null;
3480                      });
3481                  })
3482                  .bind( "mouseup" + this.eventNamespace, function() {
3483                      if ( options.disabled ) {
3484                          return false;
3485                      }
3486                      $( this ).removeClass( "ui-state-active" );
3487                  })
3488                  .bind( "keydown" + this.eventNamespace, function(event) {
3489                      if ( options.disabled ) {
3490                          return false;
3491                      }
3492                      if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
3493                          $( this ).addClass( "ui-state-active" );
3494                      }
3495                  })
3496                  // see #8559, we bind to blur here in case the button element loses
3497                  // focus between keydown and keyup, it would be left in an "active" state
3498                  .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
3499                      $( this ).removeClass( "ui-state-active" );
3500                  });
3501  
3502              if ( this.buttonElement.is("a") ) {
3503                  this.buttonElement.keyup(function(event) {
3504                      if ( event.keyCode === $.ui.keyCode.SPACE ) {
3505                          // TODO pass through original event correctly (just as 2nd argument doesn't work)
3506                          $( this ).click();
3507                      }
3508                  });
3509              }
3510          }
3511  
3512          this._setOption( "disabled", options.disabled );
3513          this._resetButton();
3514      },
3515  
3516      _determineButtonType: function() {
3517          var ancestor, labelSelector, checked;
3518  
3519          if ( this.element.is("[type=checkbox]") ) {
3520              this.type = "checkbox";
3521          } else if ( this.element.is("[type=radio]") ) {
3522              this.type = "radio";
3523          } else if ( this.element.is("input") ) {
3524              this.type = "input";
3525          } else {
3526              this.type = "button";
3527          }
3528  
3529          if ( this.type === "checkbox" || this.type === "radio" ) {
3530              // we don't search against the document in case the element
3531              // is disconnected from the DOM
3532              ancestor = this.element.parents().last();
3533              labelSelector = "label[for='" + this.element.attr("id") + "']";
3534              this.buttonElement = ancestor.find( labelSelector );
3535              if ( !this.buttonElement.length ) {
3536                  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
3537                  this.buttonElement = ancestor.filter( labelSelector );
3538                  if ( !this.buttonElement.length ) {
3539                      this.buttonElement = ancestor.find( labelSelector );
3540                  }
3541              }
3542              this.element.addClass( "ui-helper-hidden-accessible" );
3543  
3544              checked = this.element.is( ":checked" );
3545              if ( checked ) {
3546                  this.buttonElement.addClass( "ui-state-active" );
3547              }
3548              this.buttonElement.prop( "aria-pressed", checked );
3549          } else {
3550              this.buttonElement = this.element;
3551          }
3552      },
3553  
3554      widget: function() {
3555          return this.buttonElement;
3556      },
3557  
3558      _destroy: function() {
3559          this.element
3560              .removeClass( "ui-helper-hidden-accessible" );
3561          this.buttonElement
3562              .removeClass( baseClasses + " ui-state-active " + typeClasses )
3563              .removeAttr( "role" )
3564              .removeAttr( "aria-pressed" )
3565              .html( this.buttonElement.find(".ui-button-text").html() );
3566  
3567          if ( !this.hasTitle ) {
3568              this.buttonElement.removeAttr( "title" );
3569          }
3570      },
3571  
3572      _setOption: function( key, value ) {
3573          this._super( key, value );
3574          if ( key === "disabled" ) {
3575              this.widget().toggleClass( "ui-state-disabled", !!value );
3576              this.element.prop( "disabled", !!value );
3577              if ( value ) {
3578                  if ( this.type === "checkbox" || this.type === "radio" ) {
3579                      this.buttonElement.removeClass( "ui-state-focus" );
3580                  } else {
3581                      this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
3582                  }
3583              }
3584              return;
3585          }
3586          this._resetButton();
3587      },
3588  
3589      refresh: function() {
3590          //See #8237 & #8828
3591          var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
3592  
3593          if ( isDisabled !== this.options.disabled ) {
3594              this._setOption( "disabled", isDisabled );
3595          }
3596          if ( this.type === "radio" ) {
3597              radioGroup( this.element[0] ).each(function() {
3598                  if ( $( this ).is( ":checked" ) ) {
3599                      $( this ).button( "widget" )
3600                          .addClass( "ui-state-active" )
3601                          .attr( "aria-pressed", "true" );
3602                  } else {
3603                      $( this ).button( "widget" )
3604                          .removeClass( "ui-state-active" )
3605                          .attr( "aria-pressed", "false" );
3606                  }
3607              });
3608          } else if ( this.type === "checkbox" ) {
3609              if ( this.element.is( ":checked" ) ) {
3610                  this.buttonElement
3611                      .addClass( "ui-state-active" )
3612                      .attr( "aria-pressed", "true" );
3613              } else {
3614                  this.buttonElement
3615                      .removeClass( "ui-state-active" )
3616                      .attr( "aria-pressed", "false" );
3617              }
3618          }
3619      },
3620  
3621      _resetButton: function() {
3622          if ( this.type === "input" ) {
3623              if ( this.options.label ) {
3624                  this.element.val( this.options.label );
3625              }
3626              return;
3627          }
3628          var buttonElement = this.buttonElement.removeClass( typeClasses ),
3629              buttonText = $( "<span></span>", this.document[0] )
3630                  .addClass( "ui-button-text" )
3631                  .html( this.options.label )
3632                  .appendTo( buttonElement.empty() )
3633                  .text(),
3634              icons = this.options.icons,
3635              multipleIcons = icons.primary && icons.secondary,
3636              buttonClasses = [];
3637  
3638          if ( icons.primary || icons.secondary ) {
3639              if ( this.options.text ) {
3640                  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
3641              }
3642  
3643              if ( icons.primary ) {
3644                  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
3645              }
3646  
3647              if ( icons.secondary ) {
3648                  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
3649              }
3650  
3651              if ( !this.options.text ) {
3652                  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
3653  
3654                  if ( !this.hasTitle ) {
3655                      buttonElement.attr( "title", $.trim( buttonText ) );
3656                  }
3657              }
3658          } else {
3659              buttonClasses.push( "ui-button-text-only" );
3660          }
3661          buttonElement.addClass( buttonClasses.join( " " ) );
3662      }
3663  });
3664  
3665  $.widget( "ui.buttonset", {
3666      version: "1.11.1",
3667      options: {
3668          items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
3669      },
3670  
3671      _create: function() {
3672          this.element.addClass( "ui-buttonset" );
3673      },
3674  
3675      _init: function() {
3676          this.refresh();
3677      },
3678  
3679      _setOption: function( key, value ) {
3680          if ( key === "disabled" ) {
3681              this.buttons.button( "option", key, value );
3682          }
3683  
3684          this._super( key, value );
3685      },
3686  
3687      refresh: function() {
3688          var rtl = this.element.css( "direction" ) === "rtl",
3689              allButtons = this.element.find( this.options.items ),
3690              existingButtons = allButtons.filter( ":ui-button" );
3691  
3692          // Initialize new buttons
3693          allButtons.not( ":ui-button" ).button();
3694  
3695          // Refresh existing buttons
3696          existingButtons.button( "refresh" );
3697  
3698          this.buttons = allButtons
3699              .map(function() {
3700                  return $( this ).button( "widget" )[ 0 ];
3701              })
3702                  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
3703                  .filter( ":first" )
3704                      .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
3705                  .end()
3706                  .filter( ":last" )
3707                      .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
3708                  .end()
3709              .end();
3710      },
3711  
3712      _destroy: function() {
3713          this.element.removeClass( "ui-buttonset" );
3714          this.buttons
3715              .map(function() {
3716                  return $( this ).button( "widget" )[ 0 ];
3717              })
3718                  .removeClass( "ui-corner-left ui-corner-right" )
3719              .end()
3720              .button( "destroy" );
3721      }
3722  });
3723  
3724  var button = $.ui.button;
3725  
3726  
3727  /*!
3728   * jQuery UI Datepicker 1.11.1
3729   * http://jqueryui.com
3730   *
3731   * Copyright 2014 jQuery Foundation and other contributors
3732   * Released under the MIT license.
3733   * http://jquery.org/license
3734   *
3735   * http://api.jqueryui.com/datepicker/
3736   */
3737  
3738  
3739  $.extend($.ui, { datepicker: { version: "1.11.1" } });
3740  
3741  var datepicker_instActive;
3742  
3743  function datepicker_getZindex( elem ) {
3744      var position, value;
3745      while ( elem.length && elem[ 0 ] !== document ) {
3746          // Ignore z-index if position is set to a value where z-index is ignored by the browser
3747          // This makes behavior of this function consistent across browsers
3748          // WebKit always returns auto if the element is positioned
3749          position = elem.css( "position" );
3750          if ( position === "absolute" || position === "relative" || position === "fixed" ) {
3751              // IE returns 0 when zIndex is not specified
3752              // other browsers return a string
3753              // we ignore the case of nested elements with an explicit value of 0
3754              // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
3755              value = parseInt( elem.css( "zIndex" ), 10 );
3756              if ( !isNaN( value ) && value !== 0 ) {
3757                  return value;
3758              }
3759          }
3760          elem = elem.parent();
3761      }
3762  
3763      return 0;
3764  }
3765  /* Date picker manager.
3766     Use the singleton instance of this class, $.datepicker, to interact with the date picker.
3767     Settings for (groups of) date pickers are maintained in an instance object,
3768     allowing multiple different settings on the same page. */
3769  
3770  function Datepicker() {
3771      this._curInst = null; // The current instance in use
3772      this._keyEvent = false; // If the last event was a key event
3773      this._disabledInputs = []; // List of date picker inputs that have been disabled
3774      this._datepickerShowing = false; // True if the popup picker is showing , false if not
3775      this._inDialog = false; // True if showing within a "dialog", false if not
3776      this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
3777      this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
3778      this._appendClass = "ui-datepicker-append"; // The name of the append marker class
3779      this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
3780      this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
3781      this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
3782      this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
3783      this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
3784      this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
3785      this.regional = []; // Available regional settings, indexed by language code
3786      this.regional[""] = { // Default regional settings
3787          closeText: "Done", // Display text for close link
3788          prevText: "Prev", // Display text for previous month link
3789          nextText: "Next", // Display text for next month link
3790          currentText: "Today", // Display text for current month link
3791          monthNames: ["January","February","March","April","May","June",
3792              "July","August","September","October","November","December"], // Names of months for drop-down and formatting
3793          monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
3794          dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
3795          dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
3796          dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
3797          weekHeader: "Wk", // Column header for week of the year
3798          dateFormat: "mm/dd/yy", // See format options on parseDate
3799          firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
3800          isRTL: false, // True if right-to-left language, false if left-to-right
3801          showMonthAfterYear: false, // True if the year select precedes month, false for month then year
3802          yearSuffix: "" // Additional text to append to the year in the month headers
3803      };
3804      this._defaults = { // Global defaults for all the date picker instances
3805          showOn: "focus", // "focus" for popup on focus,
3806              // "button" for trigger button, or "both" for either
3807          showAnim: "fadeIn", // Name of jQuery animation for popup
3808          showOptions: {}, // Options for enhanced animations
3809          defaultDate: null, // Used when field is blank: actual date,
3810              // +/-number for offset from today, null for today
3811          appendText: "", // Display text following the input box, e.g. showing the format
3812          buttonText: "...", // Text for trigger button
3813          buttonImage: "", // URL for trigger button image
3814          buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
3815          hideIfNoPrevNext: false, // True to hide next/previous month links
3816              // if not applicable, false to just disable them
3817          navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
3818          gotoCurrent: false, // True if today link goes back to current selection instead
3819          changeMonth: false, // True if month can be selected directly, false if only prev/next
3820          changeYear: false, // True if year can be selected directly, false if only prev/next
3821          yearRange: "c-10:c+10", // Range of years to display in drop-down,
3822              // either relative to today's year (-nn:+nn), relative to currently displayed year
3823              // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
3824          showOtherMonths: false, // True to show dates in other months, false to leave blank
3825          selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
3826          showWeek: false, // True to show week of the year, false to not show it
3827          calculateWeek: this.iso8601Week, // How to calculate the week of the year,
3828              // takes a Date and returns the number of the week for it
3829          shortYearCutoff: "+10", // Short year values < this are in the current century,
3830              // > this are in the previous century,
3831              // string value starting with "+" for current year + value
3832          minDate: null, // The earliest selectable date, or null for no limit
3833          maxDate: null, // The latest selectable date, or null for no limit
3834          duration: "fast", // Duration of display/closure
3835          beforeShowDay: null, // Function that takes a date and returns an array with
3836              // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
3837              // [2] = cell title (optional), e.g. $.datepicker.noWeekends
3838          beforeShow: null, // Function that takes an input field and
3839              // returns a set of custom settings for the date picker
3840          onSelect: null, // Define a callback function when a date is selected
3841          onChangeMonthYear: null, // Define a callback function when the month or year is changed
3842          onClose: null, // Define a callback function when the datepicker is closed
3843          numberOfMonths: 1, // Number of months to show at a time
3844          showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
3845          stepMonths: 1, // Number of months to step back/forward
3846          stepBigMonths: 12, // Number of months to step back/forward for the big links
3847          altField: "", // Selector for an alternate field to store selected dates into
3848          altFormat: "", // The date format to use for the alternate field
3849          constrainInput: true, // The input is constrained by the current date format
3850          showButtonPanel: false, // True to show button panel, false to not show it
3851          autoSize: false, // True to size the input for the date format, false to leave as is
3852          disabled: false // The initial disabled state
3853      };
3854      $.extend(this._defaults, this.regional[""]);
3855      this.regional.en = $.extend( true, {}, this.regional[ "" ]);
3856      this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
3857      this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
3858  }
3859  
3860  $.extend(Datepicker.prototype, {
3861      /* Class name added to elements to indicate already configured with a date picker. */
3862      markerClassName: "hasDatepicker",
3863  
3864      //Keep track of the maximum number of rows displayed (see #7043)
3865      maxRows: 4,
3866  
3867      // TODO rename to "widget" when switching to widget factory
3868      _widgetDatepicker: function() {
3869          return this.dpDiv;
3870      },
3871  
3872      /* Override the default settings for all instances of the date picker.
3873       * @param  settings  object - the new settings to use as defaults (anonymous object)
3874       * @return the manager object
3875       */
3876      setDefaults: function(settings) {
3877          datepicker_extendRemove(this._defaults, settings || {});
3878          return this;
3879      },
3880  
3881      /* Attach the date picker to a jQuery selection.
3882       * @param  target    element - the target input field or division or span
3883       * @param  settings  object - the new settings to use for this date picker instance (anonymous)
3884       */
3885      _attachDatepicker: function(target, settings) {
3886          var nodeName, inline, inst;
3887          nodeName = target.nodeName.toLowerCase();
3888          inline = (nodeName === "div" || nodeName === "span");
3889          if (!target.id) {
3890              this.uuid += 1;
3891              target.id = "dp" + this.uuid;
3892          }
3893          inst = this._newInst($(target), inline);
3894          inst.settings = $.extend({}, settings || {});
3895          if (nodeName === "input") {
3896              this._connectDatepicker(target, inst);
3897          } else if (inline) {
3898              this._inlineDatepicker(target, inst);
3899          }
3900      },
3901  
3902      /* Create a new instance object. */
3903      _newInst: function(target, inline) {
3904          var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
3905          return {id: id, input: target, // associated target
3906              selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
3907              drawMonth: 0, drawYear: 0, // month being drawn
3908              inline: inline, // is datepicker inline or not
3909              dpDiv: (!inline ? this.dpDiv : // presentation div
3910              datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
3911      },
3912  
3913      /* Attach the date picker to an input field. */
3914      _connectDatepicker: function(target, inst) {
3915          var input = $(target);
3916          inst.append = $([]);
3917          inst.trigger = $([]);
3918          if (input.hasClass(this.markerClassName)) {
3919              return;
3920          }
3921          this._attachments(input, inst);
3922          input.addClass(this.markerClassName).keydown(this._doKeyDown).
3923              keypress(this._doKeyPress).keyup(this._doKeyUp);
3924          this._autoSize(inst);
3925          $.data(target, "datepicker", inst);
3926          //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
3927          if( inst.settings.disabled ) {
3928              this._disableDatepicker( target );
3929          }
3930      },
3931  
3932      /* Make attachments based on settings. */
3933      _attachments: function(input, inst) {
3934          var showOn, buttonText, buttonImage,
3935              appendText = this._get(inst, "appendText"),
3936              isRTL = this._get(inst, "isRTL");
3937  
3938          if (inst.append) {
3939              inst.append.remove();
3940          }
3941          if (appendText) {
3942              inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
3943              input[isRTL ? "before" : "after"](inst.append);
3944          }
3945  
3946          input.unbind("focus", this._showDatepicker);
3947  
3948          if (inst.trigger) {
3949              inst.trigger.remove();
3950          }
3951  
3952          showOn = this._get(inst, "showOn");
3953          if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
3954              input.focus(this._showDatepicker);
3955          }
3956          if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
3957              buttonText = this._get(inst, "buttonText");
3958              buttonImage = this._get(inst, "buttonImage");
3959              inst.trigger = $(this._get(inst, "buttonImageOnly") ?
3960                  $("<img/>").addClass(this._triggerClass).
3961                      attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
3962                  $("<button type='button'></button>").addClass(this._triggerClass).
3963                      html(!buttonImage ? buttonText : $("<img/>").attr(
3964                      { src:buttonImage, alt:buttonText, title:buttonText })));
3965              input[isRTL ? "before" : "after"](inst.trigger);
3966              inst.trigger.click(function() {
3967                  if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
3968                      $.datepicker._hideDatepicker();
3969                  } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
3970                      $.datepicker._hideDatepicker();
3971                      $.datepicker._showDatepicker(input[0]);
3972                  } else {
3973                      $.datepicker._showDatepicker(input[0]);
3974                  }
3975                  return false;
3976              });
3977          }
3978      },
3979  
3980      /* Apply the maximum length for the date format. */
3981      _autoSize: function(inst) {
3982          if (this._get(inst, "autoSize") && !inst.inline) {
3983              var findMax, max, maxI, i,
3984                  date = new Date(2009, 12 - 1, 20), // Ensure double digits
3985                  dateFormat = this._get(inst, "dateFormat");
3986  
3987              if (dateFormat.match(/[DM]/)) {
3988                  findMax = function(names) {
3989                      max = 0;
3990                      maxI = 0;
3991                      for (i = 0; i < names.length; i++) {
3992                          if (names[i].length > max) {
3993                              max = names[i].length;
3994                              maxI = i;
3995                          }
3996                      }
3997                      return maxI;
3998                  };
3999                  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
4000                      "monthNames" : "monthNamesShort"))));
4001                  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
4002                      "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
4003              }
4004              inst.input.attr("size", this._formatDate(inst, date).length);
4005          }
4006      },
4007  
4008      /* Attach an inline date picker to a div. */
4009      _inlineDatepicker: function(target, inst) {
4010          var divSpan = $(target);
4011          if (divSpan.hasClass(this.markerClassName)) {
4012              return;
4013          }
4014          divSpan.addClass(this.markerClassName).append(inst.dpDiv);
4015          $.data(target, "datepicker", inst);
4016          this._setDate(inst, this._getDefaultDate(inst), true);
4017          this._updateDatepicker(inst);
4018          this._updateAlternate(inst);
4019          //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
4020          if( inst.settings.disabled ) {
4021              this._disableDatepicker( target );
4022          }
4023          // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
4024          // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
4025          inst.dpDiv.css( "display", "block" );
4026      },
4027  
4028      /* Pop-up the date picker in a "dialog" box.
4029       * @param  input element - ignored
4030       * @param  date    string or Date - the initial date to display
4031       * @param  onSelect  function - the function to call when a date is selected
4032       * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
4033       * @param  pos int[2] - coordinates for the dialog's position within the screen or
4034       *                    event - with x/y coordinates or
4035       *                    leave empty for default (screen centre)
4036       * @return the manager object
4037       */
4038      _dialogDatepicker: function(input, date, onSelect, settings, pos) {
4039          var id, browserWidth, browserHeight, scrollX, scrollY,
4040              inst = this._dialogInst; // internal instance
4041  
4042          if (!inst) {
4043              this.uuid += 1;
4044              id = "dp" + this.uuid;
4045              this._dialogInput = $("<input type='text' id='" + id +
4046                  "' style='position: absolute; top: -100px; width: 0px;'/>");
4047              this._dialogInput.keydown(this._doKeyDown);
4048              $("body").append(this._dialogInput);
4049              inst = this._dialogInst = this._newInst(this._dialogInput, false);
4050              inst.settings = {};
4051              $.data(this._dialogInput[0], "datepicker", inst);
4052          }
4053          datepicker_extendRemove(inst.settings, settings || {});
4054          date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
4055          this._dialogInput.val(date);
4056  
4057          this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
4058          if (!this._pos) {
4059              browserWidth = document.documentElement.clientWidth;
4060              browserHeight = document.documentElement.clientHeight;
4061              scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
4062              scrollY = document.documentElement.scrollTop || document.body.scrollTop;
4063              this._pos = // should use actual width/height below
4064                  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
4065          }
4066  
4067          // move input on screen for focus, but hidden behind dialog
4068          this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
4069          inst.settings.onSelect = onSelect;
4070          this._inDialog = true;
4071          this.dpDiv.addClass(this._dialogClass);
4072          this._showDatepicker(this._dialogInput[0]);
4073          if ($.blockUI) {
4074              $.blockUI(this.dpDiv);
4075          }
4076          $.data(this._dialogInput[0], "datepicker", inst);
4077          return this;
4078      },
4079  
4080      /* Detach a datepicker from its control.
4081       * @param  target    element - the target input field or division or span
4082       */
4083      _destroyDatepicker: function(target) {
4084          var nodeName,
4085              $target = $(target),
4086              inst = $.data(target, "datepicker");
4087  
4088          if (!$target.hasClass(this.markerClassName)) {
4089              return;
4090          }
4091  
4092          nodeName = target.nodeName.toLowerCase();
4093          $.removeData(target, "datepicker");
4094          if (nodeName === "input") {
4095              inst.append.remove();
4096              inst.trigger.remove();
4097              $target.removeClass(this.markerClassName).
4098                  unbind("focus", this._showDatepicker).
4099                  unbind("keydown", this._doKeyDown).
4100                  unbind("keypress", this._doKeyPress).
4101                  unbind("keyup", this._doKeyUp);
4102          } else if (nodeName === "div" || nodeName === "span") {
4103              $target.removeClass(this.markerClassName).empty();
4104          }
4105      },
4106  
4107      /* Enable the date picker to a jQuery selection.
4108       * @param  target    element - the target input field or division or span
4109       */
4110      _enableDatepicker: function(target) {
4111          var nodeName, inline,
4112              $target = $(target),
4113              inst = $.data(target, "datepicker");
4114  
4115          if (!$target.hasClass(this.markerClassName)) {
4116              return;
4117          }
4118  
4119          nodeName = target.nodeName.toLowerCase();
4120          if (nodeName === "input") {
4121              target.disabled = false;
4122              inst.trigger.filter("button").
4123                  each(function() { this.disabled = false; }).end().
4124                  filter("img").css({opacity: "1.0", cursor: ""});
4125          } else if (nodeName === "div" || nodeName === "span") {
4126              inline = $target.children("." + this._inlineClass);
4127              inline.children().removeClass("ui-state-disabled");
4128              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4129                  prop("disabled", false);
4130          }
4131          this._disabledInputs = $.map(this._disabledInputs,
4132              function(value) { return (value === target ? null : value); }); // delete entry
4133      },
4134  
4135      /* Disable the date picker to a jQuery selection.
4136       * @param  target    element - the target input field or division or span
4137       */
4138      _disableDatepicker: function(target) {
4139          var nodeName, inline,
4140              $target = $(target),
4141              inst = $.data(target, "datepicker");
4142  
4143          if (!$target.hasClass(this.markerClassName)) {
4144              return;
4145          }
4146  
4147          nodeName = target.nodeName.toLowerCase();
4148          if (nodeName === "input") {
4149              target.disabled = true;
4150              inst.trigger.filter("button").
4151                  each(function() { this.disabled = true; }).end().
4152                  filter("img").css({opacity: "0.5", cursor: "default"});
4153          } else if (nodeName === "div" || nodeName === "span") {
4154              inline = $target.children("." + this._inlineClass);
4155              inline.children().addClass("ui-state-disabled");
4156              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
4157                  prop("disabled", true);
4158          }
4159          this._disabledInputs = $.map(this._disabledInputs,
4160              function(value) { return (value === target ? null : value); }); // delete entry
4161          this._disabledInputs[this._disabledInputs.length] = target;
4162      },
4163  
4164      /* Is the first field in a jQuery collection disabled as a datepicker?
4165       * @param  target    element - the target input field or division or span
4166       * @return boolean - true if disabled, false if enabled
4167       */
4168      _isDisabledDatepicker: function(target) {
4169          if (!target) {
4170              return false;
4171          }
4172          for (var i = 0; i < this._disabledInputs.length; i++) {
4173              if (this._disabledInputs[i] === target) {
4174                  return true;
4175              }
4176          }
4177          return false;
4178      },
4179  
4180      /* Retrieve the instance data for the target control.
4181       * @param  target  element - the target input field or division or span
4182       * @return  object - the associated instance data
4183       * @throws  error if a jQuery problem getting data
4184       */
4185      _getInst: function(target) {
4186          try {
4187              return $.data(target, "datepicker");
4188          }
4189          catch (err) {
4190              throw "Missing instance data for this datepicker";
4191          }
4192      },
4193  
4194      /* Update or retrieve the settings for a date picker attached to an input field or division.
4195       * @param  target  element - the target input field or division or span
4196       * @param  name    object - the new settings to update or
4197       *                string - the name of the setting to change or retrieve,
4198       *                when retrieving also "all" for all instance settings or
4199       *                "defaults" for all global defaults
4200       * @param  value   any - the new value for the setting
4201       *                (omit if above is an object or to retrieve a value)
4202       */
4203      _optionDatepicker: function(target, name, value) {
4204          var settings, date, minDate, maxDate,
4205              inst = this._getInst(target);
4206  
4207          if (arguments.length === 2 && typeof name === "string") {
4208              return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
4209                  (inst ? (name === "all" ? $.extend({}, inst.settings) :
4210                  this._get(inst, name)) : null));
4211          }
4212  
4213          settings = name || {};
4214          if (typeof name === "string") {
4215              settings = {};
4216              settings[name] = value;
4217          }
4218  
4219          if (inst) {
4220              if (this._curInst === inst) {
4221                  this._hideDatepicker();
4222              }
4223  
4224              date = this._getDateDatepicker(target, true);
4225              minDate = this._getMinMaxDate(inst, "min");
4226              maxDate = this._getMinMaxDate(inst, "max");
4227              datepicker_extendRemove(inst.settings, settings);
4228              // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
4229              if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
4230                  inst.settings.minDate = this._formatDate(inst, minDate);
4231              }
4232              if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
4233                  inst.settings.maxDate = this._formatDate(inst, maxDate);
4234              }
4235              if ( "disabled" in settings ) {
4236                  if ( settings.disabled ) {
4237                      this._disableDatepicker(target);
4238                  } else {
4239                      this._enableDatepicker(target);
4240                  }
4241              }
4242              this._attachments($(target), inst);
4243              this._autoSize(inst);
4244              this._setDate(inst, date);
4245              this._updateAlternate(inst);
4246              this._updateDatepicker(inst);
4247          }
4248      },
4249  
4250      // change method deprecated
4251      _changeDatepicker: function(target, name, value) {
4252          this._optionDatepicker(target, name, value);
4253      },
4254  
4255      /* Redraw the date picker attached to an input field or division.
4256       * @param  target  element - the target input field or division or span
4257       */
4258      _refreshDatepicker: function(target) {
4259          var inst = this._getInst(target);
4260          if (inst) {
4261              this._updateDatepicker(inst);
4262          }
4263      },
4264  
4265      /* Set the dates for a jQuery selection.
4266       * @param  target element - the target input field or division or span
4267       * @param  date    Date - the new date
4268       */
4269      _setDateDatepicker: function(target, date) {
4270          var inst = this._getInst(target);
4271          if (inst) {
4272              this._setDate(inst, date);
4273              this._updateDatepicker(inst);
4274              this._updateAlternate(inst);
4275          }
4276      },
4277  
4278      /* Get the date(s) for the first entry in a jQuery selection.
4279       * @param  target element - the target input field or division or span
4280       * @param  noDefault boolean - true if no default date is to be used
4281       * @return Date - the current date
4282       */
4283      _getDateDatepicker: function(target, noDefault) {
4284          var inst = this._getInst(target);
4285          if (inst && !inst.inline) {
4286              this._setDateFromField(inst, noDefault);
4287          }
4288          return (inst ? this._getDate(inst) : null);
4289      },
4290  
4291      /* Handle keystrokes. */
4292      _doKeyDown: function(event) {
4293          var onSelect, dateStr, sel,
4294              inst = $.datepicker._getInst(event.target),
4295              handled = true,
4296              isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
4297  
4298          inst._keyEvent = true;
4299          if ($.datepicker._datepickerShowing) {
4300              switch (event.keyCode) {
4301                  case 9: $.datepicker._hideDatepicker();
4302                          handled = false;
4303                          break; // hide on tab out
4304                  case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
4305                                      $.datepicker._currentClass + ")", inst.dpDiv);
4306                          if (sel[0]) {
4307                              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
4308                          }
4309  
4310                          onSelect = $.datepicker._get(inst, "onSelect");
4311                          if (onSelect) {
4312                              dateStr = $.datepicker._formatDate(inst);
4313  
4314                              // trigger custom callback
4315                              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
4316                          } else {
4317                              $.datepicker._hideDatepicker();
4318                          }
4319  
4320                          return false; // don't submit the form
4321                  case 27: $.datepicker._hideDatepicker();
4322                          break; // hide on escape
4323                  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4324                              -$.datepicker._get(inst, "stepBigMonths") :
4325                              -$.datepicker._get(inst, "stepMonths")), "M");
4326                          break; // previous month/year on page up/+ ctrl
4327                  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4328                              +$.datepicker._get(inst, "stepBigMonths") :
4329                              +$.datepicker._get(inst, "stepMonths")), "M");
4330                          break; // next month/year on page down/+ ctrl
4331                  case 35: if (event.ctrlKey || event.metaKey) {
4332                              $.datepicker._clearDate(event.target);
4333                          }
4334                          handled = event.ctrlKey || event.metaKey;
4335                          break; // clear on ctrl or command +end
4336                  case 36: if (event.ctrlKey || event.metaKey) {
4337                              $.datepicker._gotoToday(event.target);
4338                          }
4339                          handled = event.ctrlKey || event.metaKey;
4340                          break; // current on ctrl or command +home
4341                  case 37: if (event.ctrlKey || event.metaKey) {
4342                              $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
4343                          }
4344                          handled = event.ctrlKey || event.metaKey;
4345                          // -1 day on ctrl or command +left
4346                          if (event.originalEvent.altKey) {
4347                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4348                                  -$.datepicker._get(inst, "stepBigMonths") :
4349                                  -$.datepicker._get(inst, "stepMonths")), "M");
4350                          }
4351                          // next month/year on alt +left on Mac
4352                          break;
4353                  case 38: if (event.ctrlKey || event.metaKey) {
4354                              $.datepicker._adjustDate(event.target, -7, "D");
4355                          }
4356                          handled = event.ctrlKey || event.metaKey;
4357                          break; // -1 week on ctrl or command +up
4358                  case 39: if (event.ctrlKey || event.metaKey) {
4359                              $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
4360                          }
4361                          handled = event.ctrlKey || event.metaKey;
4362                          // +1 day on ctrl or command +right
4363                          if (event.originalEvent.altKey) {
4364                              $.datepicker._adjustDate(event.target, (event.ctrlKey ?
4365                                  +$.datepicker._get(inst, "stepBigMonths") :
4366                                  +$.datepicker._get(inst, "stepMonths")), "M");
4367                          }
4368                          // next month/year on alt +right
4369                          break;
4370                  case 40: if (event.ctrlKey || event.metaKey) {
4371                              $.datepicker._adjustDate(event.target, +7, "D");
4372                          }
4373                          handled = event.ctrlKey || event.metaKey;
4374                          break; // +1 week on ctrl or command +down
4375                  default: handled = false;
4376              }
4377          } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
4378              $.datepicker._showDatepicker(this);
4379          } else {
4380              handled = false;
4381          }
4382  
4383          if (handled) {
4384              event.preventDefault();
4385              event.stopPropagation();
4386          }
4387      },
4388  
4389      /* Filter entered characters - based on date format. */
4390      _doKeyPress: function(event) {
4391          var chars, chr,
4392              inst = $.datepicker._getInst(event.target);
4393  
4394          if ($.datepicker._get(inst, "constrainInput")) {
4395              chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
4396              chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
4397              return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
4398          }
4399      },
4400  
4401      /* Synchronise manual entry and field/alternate field. */
4402      _doKeyUp: function(event) {
4403          var date,
4404              inst = $.datepicker._getInst(event.target);
4405  
4406          if (inst.input.val() !== inst.lastVal) {
4407              try {
4408                  date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
4409                      (inst.input ? inst.input.val() : null),
4410                      $.datepicker._getFormatConfig(inst));
4411  
4412                  if (date) { // only if valid
4413                      $.datepicker._setDateFromField(inst);
4414                      $.datepicker._updateAlternate(inst);
4415                      $.datepicker._updateDatepicker(inst);
4416                  }
4417              }
4418              catch (err) {
4419              }
4420          }
4421          return true;
4422      },
4423  
4424      /* Pop-up the date picker for a given input field.
4425       * If false returned from beforeShow event handler do not show.
4426       * @param  input  element - the input field attached to the date picker or
4427       *                    event - if triggered by focus
4428       */
4429      _showDatepicker: function(input) {
4430          input = input.target || input;
4431          if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
4432              input = $("input", input.parentNode)[0];
4433          }
4434  
4435          if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
4436              return;
4437          }
4438  
4439          var inst, beforeShow, beforeShowSettings, isFixed,
4440              offset, showAnim, duration;
4441  
4442          inst = $.datepicker._getInst(input);
4443          if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
4444              $.datepicker._curInst.dpDiv.stop(true, true);
4445              if ( inst && $.datepicker._datepickerShowing ) {
4446                  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
4447              }
4448          }
4449  
4450          beforeShow = $.datepicker._get(inst, "beforeShow");
4451          beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
4452          if(beforeShowSettings === false){
4453              return;
4454          }
4455          datepicker_extendRemove(inst.settings, beforeShowSettings);
4456  
4457          inst.lastVal = null;
4458          $.datepicker._lastInput = input;
4459          $.datepicker._setDateFromField(inst);
4460  
4461          if ($.datepicker._inDialog) { // hide cursor
4462              input.value = "";
4463          }
4464          if (!$.datepicker._pos) { // position below input
4465              $.datepicker._pos = $.datepicker._findPos(input);
4466              $.datepicker._pos[1] += input.offsetHeight; // add the height
4467          }
4468  
4469          isFixed = false;
4470          $(input).parents().each(function() {
4471              isFixed |= $(this).css("position") === "fixed";
4472              return !isFixed;
4473          });
4474  
4475          offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
4476          $.datepicker._pos = null;
4477          //to avoid flashes on Firefox
4478          inst.dpDiv.empty();
4479          // determine sizing offscreen
4480          inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
4481          $.datepicker._updateDatepicker(inst);
4482          // fix width for dynamic number of date pickers
4483          // and adjust position before showing
4484          offset = $.datepicker._checkOffset(inst, offset, isFixed);
4485          inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
4486              "static" : (isFixed ? "fixed" : "absolute")), display: "none",
4487              left: offset.left + "px", top: offset.top + "px"});
4488  
4489          if (!inst.inline) {
4490              showAnim = $.datepicker._get(inst, "showAnim");
4491              duration = $.datepicker._get(inst, "duration");
4492              inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
4493              $.datepicker._datepickerShowing = true;
4494  
4495              if ( $.effects && $.effects.effect[ showAnim ] ) {
4496                  inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
4497              } else {
4498                  inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
4499              }
4500  
4501              if ( $.datepicker._shouldFocusInput( inst ) ) {
4502                  inst.input.focus();
4503              }
4504  
4505              $.datepicker._curInst = inst;
4506          }
4507      },
4508  
4509      /* Generate the date picker content. */
4510      _updateDatepicker: function(inst) {
4511          this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
4512          datepicker_instActive = inst; // for delegate hover events
4513          inst.dpDiv.empty().append(this._generateHTML(inst));
4514          this._attachHandlers(inst);
4515  
4516          var origyearshtml,
4517              numMonths = this._getNumberOfMonths(inst),
4518              cols = numMonths[1],
4519              width = 17,
4520              activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
4521  
4522          if ( activeCell.length > 0 ) {
4523              datepicker_handleMouseover.apply( activeCell.get( 0 ) );
4524          }
4525  
4526          inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
4527          if (cols > 1) {
4528              inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
4529          }
4530          inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
4531              "Class"]("ui-datepicker-multi");
4532          inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
4533              "Class"]("ui-datepicker-rtl");
4534  
4535          if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
4536              inst.input.focus();
4537          }
4538  
4539          // deffered render of the years select (to avoid flashes on Firefox)
4540          if( inst.yearshtml ){
4541              origyearshtml = inst.yearshtml;
4542              setTimeout(function(){
4543                  //assure that inst.yearshtml didn't change.
4544                  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
4545                      inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
4546                  }
4547                  origyearshtml = inst.yearshtml = null;
4548              }, 0);
4549          }
4550      },
4551  
4552      // #6694 - don't focus the input if it's already focused
4553      // this breaks the change event in IE
4554      // Support: IE and jQuery <1.9
4555      _shouldFocusInput: function( inst ) {
4556          return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
4557      },
4558  
4559      /* Check positioning to remain on screen. */
4560      _checkOffset: function(inst, offset, isFixed) {
4561          var dpWidth = inst.dpDiv.outerWidth(),
4562              dpHeight = inst.dpDiv.outerHeight(),
4563              inputWidth = inst.input ? inst.input.outerWidth() : 0,
4564              inputHeight = inst.input ? inst.input.outerHeight() : 0,
4565              viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
4566              viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
4567  
4568          offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
4569          offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
4570          offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
4571  
4572          // now check if datepicker is showing outside window viewport - move to a better place if so.
4573          offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
4574              Math.abs(offset.left + dpWidth - viewWidth) : 0);
4575          offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
4576              Math.abs(dpHeight + inputHeight) : 0);
4577  
4578          return offset;
4579      },
4580  
4581      /* Find an object's position on the screen. */
4582      _findPos: function(obj) {
4583          var position,
4584              inst = this._getInst(obj),
4585              isRTL = this._get(inst, "isRTL");
4586  
4587          while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
4588              obj = obj[isRTL ? "previousSibling" : "nextSibling"];
4589          }
4590  
4591          position = $(obj).offset();
4592          return [position.left, position.top];
4593      },
4594  
4595      /* Hide the date picker from view.
4596       * @param  input  element - the input field attached to the date picker
4597       */
4598      _hideDatepicker: function(input) {
4599          var showAnim, duration, postProcess, onClose,
4600              inst = this._curInst;
4601  
4602          if (!inst || (input && inst !== $.data(input, "datepicker"))) {
4603              return;
4604          }
4605  
4606          if (this._datepickerShowing) {
4607              showAnim = this._get(inst, "showAnim");
4608              duration = this._get(inst, "duration");
4609              postProcess = function() {
4610                  $.datepicker._tidyDialog(inst);
4611              };
4612  
4613              // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
4614              if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
4615                  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
4616              } else {
4617                  inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
4618                      (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
4619              }
4620  
4621              if (!showAnim) {
4622                  postProcess();
4623              }
4624              this._datepickerShowing = false;
4625  
4626              onClose = this._get(inst, "onClose");
4627              if (onClose) {
4628                  onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
4629              }
4630  
4631              this._lastInput = null;
4632              if (this._inDialog) {
4633                  this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
4634                  if ($.blockUI) {
4635                      $.unblockUI();
4636                      $("body").append(this.dpDiv);
4637                  }
4638              }
4639              this._inDialog = false;
4640          }
4641      },
4642  
4643      /* Tidy up after a dialog display. */
4644      _tidyDialog: function(inst) {
4645          inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
4646      },
4647  
4648      /* Close date picker if clicked elsewhere. */
4649      _checkExternalClick: function(event) {
4650          if (!$.datepicker._curInst) {
4651              return;
4652          }
4653  
4654          var $target = $(event.target),
4655              inst = $.datepicker._getInst($target[0]);
4656  
4657          if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
4658                  $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
4659                  !$target.hasClass($.datepicker.markerClassName) &&
4660                  !$target.closest("." + $.datepicker._triggerClass).length &&
4661                  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
4662              ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
4663                  $.datepicker._hideDatepicker();
4664          }
4665      },
4666  
4667      /* Adjust one of the date sub-fields. */
4668      _adjustDate: function(id, offset, period) {
4669          var target = $(id),
4670              inst = this._getInst(target[0]);
4671  
4672          if (this._isDisabledDatepicker(target[0])) {
4673              return;
4674          }
4675          this._adjustInstDate(inst, offset +
4676              (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
4677              period);
4678          this._updateDatepicker(inst);
4679      },
4680  
4681      /* Action for current link. */
4682      _gotoToday: function(id) {
4683          var date,
4684              target = $(id),
4685              inst = this._getInst(target[0]);
4686  
4687          if (this._get(inst, "gotoCurrent") && inst.currentDay) {
4688              inst.selectedDay = inst.currentDay;
4689              inst.drawMonth = inst.selectedMonth = inst.currentMonth;
4690              inst.drawYear = inst.selectedYear = inst.currentYear;
4691          } else {
4692              date = new Date();
4693              inst.selectedDay = date.getDate();
4694              inst.drawMonth = inst.selectedMonth = date.getMonth();
4695              inst.drawYear = inst.selectedYear = date.getFullYear();
4696          }
4697          this._notifyChange(inst);
4698          this._adjustDate(target);
4699      },
4700  
4701      /* Action for selecting a new month/year. */
4702      _selectMonthYear: function(id, select, period) {
4703          var target = $(id),
4704              inst = this._getInst(target[0]);
4705  
4706          inst["selected" + (period === "M" ? "Month" : "Year")] =
4707          inst["draw" + (period === "M" ? "Month" : "Year")] =
4708              parseInt(select.options[select.selectedIndex].value,10);
4709  
4710          this._notifyChange(inst);
4711          this._adjustDate(target);
4712      },
4713  
4714      /* Action for selecting a day. */
4715      _selectDay: function(id, month, year, td) {
4716          var inst,
4717              target = $(id);
4718  
4719          if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
4720              return;
4721          }
4722  
4723          inst = this._getInst(target[0]);
4724          inst.selectedDay = inst.currentDay = $("a", td).html();
4725          inst.selectedMonth = inst.currentMonth = month;
4726          inst.selectedYear = inst.currentYear = year;
4727          this._selectDate(id, this._formatDate(inst,
4728              inst.currentDay, inst.currentMonth, inst.currentYear));
4729      },
4730  
4731      /* Erase the input field and hide the date picker. */
4732      _clearDate: function(id) {
4733          var target = $(id);
4734          this._selectDate(target, "");
4735      },
4736  
4737      /* Update the input field with the selected date. */
4738      _selectDate: function(id, dateStr) {
4739          var onSelect,
4740              target = $(id),
4741              inst = this._getInst(target[0]);
4742  
4743          dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
4744          if (inst.input) {
4745              inst.input.val(dateStr);
4746          }
4747          this._updateAlternate(inst);
4748  
4749          onSelect = this._get(inst, "onSelect");
4750          if (onSelect) {
4751              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
4752          } else if (inst.input) {
4753              inst.input.trigger("change"); // fire the change event
4754          }
4755  
4756          if (inst.inline){
4757              this._updateDatepicker(inst);
4758          } else {
4759              this._hideDatepicker();
4760              this._lastInput = inst.input[0];
4761              if (typeof(inst.input[0]) !== "object") {
4762                  inst.input.focus(); // restore focus
4763              }
4764              this._lastInput = null;
4765          }
4766      },
4767  
4768      /* Update any alternate field to synchronise with the main field. */
4769      _updateAlternate: function(inst) {
4770          var altFormat, date, dateStr,
4771              altField = this._get(inst, "altField");
4772  
4773          if (altField) { // update alternate field too
4774              altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
4775              date = this._getDate(inst);
4776              dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
4777              $(altField).each(function() { $(this).val(dateStr); });
4778          }
4779      },
4780  
4781      /* Set as beforeShowDay function to prevent selection of weekends.
4782       * @param  date  Date - the date to customise
4783       * @return [boolean, string] - is this date selectable?, what is its CSS class?
4784       */
4785      noWeekends: function(date) {
4786          var day = date.getDay();
4787          return [(day > 0 && day < 6), ""];
4788      },
4789  
4790      /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
4791       * @param  date  Date - the date to get the week for
4792       * @return  number - the number of the week within the year that contains this date
4793       */
4794      iso8601Week: function(date) {
4795          var time,
4796              checkDate = new Date(date.getTime());
4797  
4798          // Find Thursday of this week starting on Monday
4799          checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
4800  
4801          time = checkDate.getTime();
4802          checkDate.setMonth(0); // Compare with Jan 1
4803          checkDate.setDate(1);
4804          return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
4805      },
4806  
4807      /* Parse a string value into a date object.
4808       * See formatDate below for the possible formats.
4809       *
4810       * @param  format string - the expected format of the date
4811       * @param  value string - the date in the above format
4812       * @param  settings Object - attributes include:
4813       *                    shortYearCutoff  number - the cutoff year for determining the century (optional)
4814       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
4815       *                    dayNames        string[7] - names of the days from Sunday (optional)
4816       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
4817       *                    monthNames        string[12] - names of the months (optional)
4818       * @return  Date - the extracted date value or null if value is blank
4819       */
4820      parseDate: function (format, value, settings) {
4821          if (format == null || value == null) {
4822              throw "Invalid arguments";
4823          }
4824  
4825          value = (typeof value === "object" ? value.toString() : value + "");
4826          if (value === "") {
4827              return null;
4828          }
4829  
4830          var iFormat, dim, extra,
4831              iValue = 0,
4832              shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
4833              shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
4834                  new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
4835              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
4836              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
4837              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
4838              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
4839              year = -1,
4840              month = -1,
4841              day = -1,
4842              doy = -1,
4843              literal = false,
4844              date,
4845              // Check whether a format character is doubled
4846              lookAhead = function(match) {
4847                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
4848                  if (matches) {
4849                      iFormat++;
4850                  }
4851                  return matches;
4852              },
4853              // Extract a number from the string value
4854              getNumber = function(match) {
4855                  var isDoubled = lookAhead(match),
4856                      size = (match === "@" ? 14 : (match === "!" ? 20 :
4857                      (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
4858                      minSize = (match === "y" ? size : 1),
4859                      digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
4860                      num = value.substring(iValue).match(digits);
4861                  if (!num) {
4862                      throw "Missing number at position " + iValue;
4863                  }
4864                  iValue += num[0].length;
4865                  return parseInt(num[0], 10);
4866              },
4867              // Extract a name from the string value and convert to an index
4868              getName = function(match, shortNames, longNames) {
4869                  var index = -1,
4870                      names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
4871                          return [ [k, v] ];
4872                      }).sort(function (a, b) {
4873                          return -(a[1].length - b[1].length);
4874                      });
4875  
4876                  $.each(names, function (i, pair) {
4877                      var name = pair[1];
4878                      if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
4879                          index = pair[0];
4880                          iValue += name.length;
4881                          return false;
4882                      }
4883                  });
4884                  if (index !== -1) {
4885                      return index + 1;
4886                  } else {
4887                      throw "Unknown name at position " + iValue;
4888                  }
4889              },
4890              // Confirm that a literal character matches the string value
4891              checkLiteral = function() {
4892                  if (value.charAt(iValue) !== format.charAt(iFormat)) {
4893                      throw "Unexpected literal at position " + iValue;
4894                  }
4895                  iValue++;
4896              };
4897  
4898          for (iFormat = 0; iFormat < format.length; iFormat++) {
4899              if (literal) {
4900                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
4901                      literal = false;
4902                  } else {
4903                      checkLiteral();
4904                  }
4905              } else {
4906                  switch (format.charAt(iFormat)) {
4907                      case "d":
4908                          day = getNumber("d");
4909                          break;
4910                      case "D":
4911                          getName("D", dayNamesShort, dayNames);
4912                          break;
4913                      case "o":
4914                          doy = getNumber("o");
4915                          break;
4916                      case "m":
4917                          month = getNumber("m");
4918                          break;
4919                      case "M":
4920                          month = getName("M", monthNamesShort, monthNames);
4921                          break;
4922                      case "y":
4923                          year = getNumber("y");
4924                          break;
4925                      case "@":
4926                          date = new Date(getNumber("@"));
4927                          year = date.getFullYear();
4928                          month = date.getMonth() + 1;
4929                          day = date.getDate();
4930                          break;
4931                      case "!":
4932                          date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
4933                          year = date.getFullYear();
4934                          month = date.getMonth() + 1;
4935                          day = date.getDate();
4936                          break;
4937                      case "'":
4938                          if (lookAhead("'")){
4939                              checkLiteral();
4940                          } else {
4941                              literal = true;
4942                          }
4943                          break;
4944                      default:
4945                          checkLiteral();
4946                  }
4947              }
4948          }
4949  
4950          if (iValue < value.length){
4951              extra = value.substr(iValue);
4952              if (!/^\s+/.test(extra)) {
4953                  throw "Extra/unparsed characters found in date: " + extra;
4954              }
4955          }
4956  
4957          if (year === -1) {
4958              year = new Date().getFullYear();
4959          } else if (year < 100) {
4960              year += new Date().getFullYear() - new Date().getFullYear() % 100 +
4961                  (year <= shortYearCutoff ? 0 : -100);
4962          }
4963  
4964          if (doy > -1) {
4965              month = 1;
4966              day = doy;
4967              do {
4968                  dim = this._getDaysInMonth(year, month - 1);
4969                  if (day <= dim) {
4970                      break;
4971                  }
4972                  month++;
4973                  day -= dim;
4974              } while (true);
4975          }
4976  
4977          date = this._daylightSavingAdjust(new Date(year, month - 1, day));
4978          if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
4979              throw "Invalid date"; // E.g. 31/02/00
4980          }
4981          return date;
4982      },
4983  
4984      /* Standard date formats. */
4985      ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
4986      COOKIE: "D, dd M yy",
4987      ISO_8601: "yy-mm-dd",
4988      RFC_822: "D, d M y",
4989      RFC_850: "DD, dd-M-y",
4990      RFC_1036: "D, d M y",
4991      RFC_1123: "D, d M yy",
4992      RFC_2822: "D, d M yy",
4993      RSS: "D, d M y", // RFC 822
4994      TICKS: "!",
4995      TIMESTAMP: "@",
4996      W3C: "yy-mm-dd", // ISO 8601
4997  
4998      _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
4999          Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
5000  
5001      /* Format a date object into a string value.
5002       * The format can be combinations of the following:
5003       * d  - day of month (no leading zero)
5004       * dd - day of month (two digit)
5005       * o  - day of year (no leading zeros)
5006       * oo - day of year (three digit)
5007       * D  - day name short
5008       * DD - day name long
5009       * m  - month of year (no leading zero)
5010       * mm - month of year (two digit)
5011       * M  - month name short
5012       * MM - month name long
5013       * y  - year (two digit)
5014       * yy - year (four digit)
5015       * @ - Unix timestamp (ms since 01/01/1970)
5016       * ! - Windows ticks (100ns since 01/01/0001)
5017       * "..." - literal text
5018       * '' - single quote
5019       *
5020       * @param  format string - the desired format of the date
5021       * @param  date Date - the date value to format
5022       * @param  settings Object - attributes include:
5023       *                    dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
5024       *                    dayNames        string[7] - names of the days from Sunday (optional)
5025       *                    monthNamesShort string[12] - abbreviated names of the months (optional)
5026       *                    monthNames        string[12] - names of the months (optional)
5027       * @return  string - the date in the above format
5028       */
5029      formatDate: function (format, date, settings) {
5030          if (!date) {
5031              return "";
5032          }
5033  
5034          var iFormat,
5035              dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
5036              dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
5037              monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
5038              monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
5039              // Check whether a format character is doubled
5040              lookAhead = function(match) {
5041                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5042                  if (matches) {
5043                      iFormat++;
5044                  }
5045                  return matches;
5046              },
5047              // Format a number, with leading zero if necessary
5048              formatNumber = function(match, value, len) {
5049                  var num = "" + value;
5050                  if (lookAhead(match)) {
5051                      while (num.length < len) {
5052                          num = "0" + num;
5053                      }
5054                  }
5055                  return num;
5056              },
5057              // Format a name, short or long as requested
5058              formatName = function(match, value, shortNames, longNames) {
5059                  return (lookAhead(match) ? longNames[value] : shortNames[value]);
5060              },
5061              output = "",
5062              literal = false;
5063  
5064          if (date) {
5065              for (iFormat = 0; iFormat < format.length; iFormat++) {
5066                  if (literal) {
5067                      if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5068                          literal = false;
5069                      } else {
5070                          output += format.charAt(iFormat);
5071                      }
5072                  } else {
5073                      switch (format.charAt(iFormat)) {
5074                          case "d":
5075                              output += formatNumber("d", date.getDate(), 2);
5076                              break;
5077                          case "D":
5078                              output += formatName("D", date.getDay(), dayNamesShort, dayNames);
5079                              break;
5080                          case "o":
5081                              output += formatNumber("o",
5082                                  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
5083                              break;
5084                          case "m":
5085                              output += formatNumber("m", date.getMonth() + 1, 2);
5086                              break;
5087                          case "M":
5088                              output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
5089                              break;
5090                          case "y":
5091                              output += (lookAhead("y") ? date.getFullYear() :
5092                                  (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
5093                              break;
5094                          case "@":
5095                              output += date.getTime();
5096                              break;
5097                          case "!":
5098                              output += date.getTime() * 10000 + this._ticksTo1970;
5099                              break;
5100                          case "'":
5101                              if (lookAhead("'")) {
5102                                  output += "'";
5103                              } else {
5104                                  literal = true;
5105                              }
5106                              break;
5107                          default:
5108                              output += format.charAt(iFormat);
5109                      }
5110                  }
5111              }
5112          }
5113          return output;
5114      },
5115  
5116      /* Extract all possible characters from the date format. */
5117      _possibleChars: function (format) {
5118          var iFormat,
5119              chars = "",
5120              literal = false,
5121              // Check whether a format character is doubled
5122              lookAhead = function(match) {
5123                  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
5124                  if (matches) {
5125                      iFormat++;
5126                  }
5127                  return matches;
5128              };
5129  
5130          for (iFormat = 0; iFormat < format.length; iFormat++) {
5131              if (literal) {
5132                  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
5133                      literal = false;
5134                  } else {
5135                      chars += format.charAt(iFormat);
5136                  }
5137              } else {
5138                  switch (format.charAt(iFormat)) {
5139                      case "d": case "m": case "y": case "@":
5140                          chars += "0123456789";
5141                          break;
5142                      case "D": case "M":
5143                          return null; // Accept anything
5144                      case "'":
5145                          if (lookAhead("'")) {
5146                              chars += "'";
5147                          } else {
5148                              literal = true;
5149                          }
5150                          break;
5151                      default:
5152                          chars += format.charAt(iFormat);
5153                  }
5154              }
5155          }
5156          return chars;
5157      },
5158  
5159      /* Get a setting value, defaulting if necessary. */
5160      _get: function(inst, name) {
5161          return inst.settings[name] !== undefined ?
5162              inst.settings[name] : this._defaults[name];
5163      },
5164  
5165      /* Parse existing date and initialise date picker. */
5166      _setDateFromField: function(inst, noDefault) {
5167          if (inst.input.val() === inst.lastVal) {
5168              return;
5169          }
5170  
5171          var dateFormat = this._get(inst, "dateFormat"),
5172              dates = inst.lastVal = inst.input ? inst.input.val() : null,
5173              defaultDate = this._getDefaultDate(inst),
5174              date = defaultDate,
5175              settings = this._getFormatConfig(inst);
5176  
5177          try {
5178              date = this.parseDate(dateFormat, dates, settings) || defaultDate;
5179          } catch (event) {
5180              dates = (noDefault ? "" : dates);
5181          }
5182          inst.selectedDay = date.getDate();
5183          inst.drawMonth = inst.selectedMonth = date.getMonth();
5184          inst.drawYear = inst.selectedYear = date.getFullYear();
5185          inst.currentDay = (dates ? date.getDate() : 0);
5186          inst.currentMonth = (dates ? date.getMonth() : 0);
5187          inst.currentYear = (dates ? date.getFullYear() : 0);
5188          this._adjustInstDate(inst);
5189      },
5190  
5191      /* Retrieve the default date shown on opening. */
5192      _getDefaultDate: function(inst) {
5193          return this._restrictMinMax(inst,
5194              this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
5195      },
5196  
5197      /* A date may be specified as an exact value or a relative one. */
5198      _determineDate: function(inst, date, defaultDate) {
5199          var offsetNumeric = function(offset) {
5200                  var date = new Date();
5201                  date.setDate(date.getDate() + offset);
5202                  return date;
5203              },
5204              offsetString = function(offset) {
5205                  try {
5206                      return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
5207                          offset, $.datepicker._getFormatConfig(inst));
5208                  }
5209                  catch (e) {
5210                      // Ignore
5211                  }
5212  
5213                  var date = (offset.toLowerCase().match(/^c/) ?
5214                      $.datepicker._getDate(inst) : null) || new Date(),
5215                      year = date.getFullYear(),
5216                      month = date.getMonth(),
5217                      day = date.getDate(),
5218                      pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
5219                      matches = pattern.exec(offset);
5220  
5221                  while (matches) {
5222                      switch (matches[2] || "d") {
5223                          case "d" : case "D" :
5224                              day += parseInt(matches[1],10); break;
5225                          case "w" : case "W" :
5226                              day += parseInt(matches[1],10) * 7; break;
5227                          case "m" : case "M" :
5228                              month += parseInt(matches[1],10);
5229                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5230                              break;
5231                          case "y": case "Y" :
5232                              year += parseInt(matches[1],10);
5233                              day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
5234                              break;
5235                      }
5236                      matches = pattern.exec(offset);
5237                  }
5238                  return new Date(year, month, day);
5239              },
5240              newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
5241                  (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
5242  
5243          newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
5244          if (newDate) {
5245              newDate.setHours(0);
5246              newDate.setMinutes(0);
5247              newDate.setSeconds(0);
5248              newDate.setMilliseconds(0);
5249          }
5250          return this._daylightSavingAdjust(newDate);
5251      },
5252  
5253      /* Handle switch to/from daylight saving.
5254       * Hours may be non-zero on daylight saving cut-over:
5255       * > 12 when midnight changeover, but then cannot generate
5256       * midnight datetime, so jump to 1AM, otherwise reset.
5257       * @param  date  (Date) the date to check
5258       * @return  (Date) the corrected date
5259       */
5260      _daylightSavingAdjust: function(date) {
5261          if (!date) {
5262              return null;
5263          }
5264          date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
5265          return date;
5266      },
5267  
5268      /* Set the date(s) directly. */
5269      _setDate: function(inst, date, noChange) {
5270          var clear = !date,
5271              origMonth = inst.selectedMonth,
5272              origYear = inst.selectedYear,
5273              newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
5274  
5275          inst.selectedDay = inst.currentDay = newDate.getDate();
5276          inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
5277          inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
5278          if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
5279              this._notifyChange(inst);
5280          }
5281          this._adjustInstDate(inst);
5282          if (inst.input) {
5283              inst.input.val(clear ? "" : this._formatDate(inst));
5284          }
5285      },
5286  
5287      /* Retrieve the date(s) directly. */
5288      _getDate: function(inst) {
5289          var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
5290              this._daylightSavingAdjust(new Date(
5291              inst.currentYear, inst.currentMonth, inst.currentDay)));
5292              return startDate;
5293      },
5294  
5295      /* Attach the onxxx handlers.  These are declared statically so
5296       * they work with static code transformers like Caja.
5297       */
5298      _attachHandlers: function(inst) {
5299          var stepMonths = this._get(inst, "stepMonths"),
5300              id = "#" + inst.id.replace( /\\\\/g, "\\" );
5301          inst.dpDiv.find("[data-handler]").map(function () {
5302              var handler = {
5303                  prev: function () {
5304                      $.datepicker._adjustDate(id, -stepMonths, "M");
5305                  },
5306                  next: function () {
5307                      $.datepicker._adjustDate(id, +stepMonths, "M");
5308                  },
5309                  hide: function () {
5310                      $.datepicker._hideDatepicker();
5311                  },
5312                  today: function () {
5313                      $.datepicker._gotoToday(id);
5314                  },
5315                  selectDay: function () {
5316                      $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
5317                      return false;
5318                  },
5319                  selectMonth: function () {
5320                      $.datepicker._selectMonthYear(id, this, "M");
5321                      return false;
5322                  },
5323                  selectYear: function () {
5324                      $.datepicker._selectMonthYear(id, this, "Y");
5325                      return false;
5326                  }
5327              };
5328              $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
5329          });
5330      },
5331  
5332      /* Generate the HTML for the current state of the date picker. */
5333      _generateHTML: function(inst) {
5334          var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
5335              controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
5336              monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
5337              selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
5338              cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
5339              printDate, dRow, tbody, daySettings, otherMonth, unselectable,
5340              tempDate = new Date(),
5341              today = this._daylightSavingAdjust(
5342                  new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
5343              isRTL = this._get(inst, "isRTL"),
5344              showButtonPanel = this._get(inst, "showButtonPanel"),
5345              hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
5346              navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
5347              numMonths = this._getNumberOfMonths(inst),
5348              showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
5349              stepMonths = this._get(inst, "stepMonths"),
5350              isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
5351              currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
5352                  new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
5353              minDate = this._getMinMaxDate(inst, "min"),
5354              maxDate = this._getMinMaxDate(inst, "max"),
5355              drawMonth = inst.drawMonth - showCurrentAtPos,
5356              drawYear = inst.drawYear;
5357  
5358          if (drawMonth < 0) {
5359              drawMonth += 12;
5360              drawYear--;
5361          }
5362          if (maxDate) {
5363              maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
5364                  maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
5365              maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
5366              while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
5367                  drawMonth--;
5368                  if (drawMonth < 0) {
5369                      drawMonth = 11;
5370                      drawYear--;
5371                  }
5372              }
5373          }
5374          inst.drawMonth = drawMonth;
5375          inst.drawYear = drawYear;
5376  
5377          prevText = this._get(inst, "prevText");
5378          prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
5379              this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
5380              this._getFormatConfig(inst)));
5381  
5382          prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
5383              "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
5384              " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
5385              (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>"));
5386  
5387          nextText = this._get(inst, "nextText");
5388          nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
5389              this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
5390              this._getFormatConfig(inst)));
5391  
5392          next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
5393              "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
5394              " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
5395              (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>"));
5396  
5397          currentText = this._get(inst, "currentText");
5398          gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
5399          currentText = (!navigationAsDateFormat ? currentText :
5400              this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
5401  
5402          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'>" +
5403              this._get(inst, "closeText") + "</button>" : "");
5404  
5405          buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
5406              (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'" +
5407              ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
5408  
5409          firstDay = parseInt(this._get(inst, "firstDay"),10);
5410          firstDay = (isNaN(firstDay) ? 0 : firstDay);
5411  
5412          showWeek = this._get(inst, "showWeek");
5413          dayNames = this._get(inst, "dayNames");
5414          dayNamesMin = this._get(inst, "dayNamesMin");
5415          monthNames = this._get(inst, "monthNames");
5416          monthNamesShort = this._get(inst, "monthNamesShort");
5417          beforeShowDay = this._get(inst, "beforeShowDay");
5418          showOtherMonths = this._get(inst, "showOtherMonths");
5419          selectOtherMonths = this._get(inst, "selectOtherMonths");
5420          defaultDate = this._getDefaultDate(inst);
5421          html = "";
5422          dow;
5423          for (row = 0; row < numMonths[0]; row++) {
5424              group = "";
5425              this.maxRows = 4;
5426              for (col = 0; col < numMonths[1]; col++) {
5427                  selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
5428                  cornerClass = " ui-corner-all";
5429                  calender = "";
5430                  if (isMultiMonth) {
5431                      calender += "<div class='ui-datepicker-group";
5432                      if (numMonths[1] > 1) {
5433                          switch (col) {
5434                              case 0: calender += " ui-datepicker-group-first";
5435                                  cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
5436                              case numMonths[1]-1: calender += " ui-datepicker-group-last";
5437                                  cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
5438                              default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
5439                          }
5440                      }
5441                      calender += "'>";
5442                  }
5443                  calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
5444                      (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
5445                      (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
5446                      this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
5447                      row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
5448                      "</div><table class='ui-datepicker-calendar'><thead>" +
5449                      "<tr>";
5450                  thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
5451                  for (dow = 0; dow < 7; dow++) { // days of the week
5452                      day = (dow + firstDay) % 7;
5453                      thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
5454                          "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
5455                  }
5456                  calender += thead + "</tr></thead><tbody>";
5457                  daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
5458                  if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
5459                      inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
5460                  }
5461                  leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
5462                  curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
5463                  numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
5464                  this.maxRows = numRows;
5465                  printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
5466                  for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
5467                      calender += "<tr>";
5468                      tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
5469                          this._get(inst, "calculateWeek")(printDate) + "</td>");
5470                      for (dow = 0; dow < 7; dow++) { // create date picker days
5471                          daySettings = (beforeShowDay ?
5472                              beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
5473                          otherMonth = (printDate.getMonth() !== drawMonth);
5474                          unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
5475                              (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
5476                          tbody += "<td class='" +
5477                              ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
5478                              (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
5479                              ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
5480                              (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
5481                              // or defaultDate is current printedDate and defaultDate is selectedDate
5482                              " " + this._dayOverClass : "") + // highlight selected day
5483                              (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
5484                              (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
5485                              (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
5486                              (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
5487                              ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
5488                              (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
5489                              (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
5490                              (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
5491                              (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
5492                              (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
5493                              (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
5494                              "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
5495                          printDate.setDate(printDate.getDate() + 1);
5496                          printDate = this._daylightSavingAdjust(printDate);
5497                      }
5498                      calender += tbody + "</tr>";
5499                  }
5500                  drawMonth++;
5501                  if (drawMonth > 11) {
5502                      drawMonth = 0;
5503                      drawYear++;
5504                  }
5505                  calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
5506                              ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
5507                  group += calender;
5508              }
5509              html += group;
5510          }
5511          html += buttonPanel;
5512          inst._keyEvent = false;
5513          return html;
5514      },
5515  
5516      /* Generate the month and year header. */
5517      _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
5518              secondary, monthNames, monthNamesShort) {
5519  
5520          var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
5521              changeMonth = this._get(inst, "changeMonth"),
5522              changeYear = this._get(inst, "changeYear"),
5523              showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
5524              html = "<div class='ui-datepicker-title'>",
5525              monthHtml = "";
5526  
5527          // month selection
5528          if (secondary || !changeMonth) {
5529              monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
5530          } else {
5531              inMinYear = (minDate && minDate.getFullYear() === drawYear);
5532              inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
5533              monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
5534              for ( month = 0; month < 12; month++) {
5535                  if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
5536                      monthHtml += "<option value='" + month + "'" +
5537                          (month === drawMonth ? " selected='selected'" : "") +
5538                          ">" + monthNamesShort[month] + "</option>";
5539                  }
5540              }
5541              monthHtml += "</select>";
5542          }
5543  
5544          if (!showMonthAfterYear) {
5545              html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
5546          }
5547  
5548          // year selection
5549          if ( !inst.yearshtml ) {
5550              inst.yearshtml = "";
5551              if (secondary || !changeYear) {
5552                  html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
5553              } else {
5554                  // determine range of years to display
5555                  years = this._get(inst, "yearRange").split(":");
5556                  thisYear = new Date().getFullYear();
5557                  determineYear = function(value) {
5558                      var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
5559                          (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
5560                          parseInt(value, 10)));
5561                      return (isNaN(year) ? thisYear : year);
5562                  };
5563                  year = determineYear(years[0]);
5564                  endYear = Math.max(year, determineYear(years[1] || ""));
5565                  year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
5566                  endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
5567                  inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
5568                  for (; year <= endYear; year++) {
5569                      inst.yearshtml += "<option value='" + year + "'" +
5570                          (year === drawYear ? " selected='selected'" : "") +
5571                          ">" + year + "</option>";
5572                  }
5573                  inst.yearshtml += "</select>";
5574  
5575                  html += inst.yearshtml;
5576                  inst.yearshtml = null;
5577              }
5578          }
5579  
5580          html += this._get(inst, "yearSuffix");
5581          if (showMonthAfterYear) {
5582              html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
5583          }
5584          html += "</div>"; // Close datepicker_header
5585          return html;
5586      },
5587  
5588      /* Adjust one of the date sub-fields. */
5589      _adjustInstDate: function(inst, offset, period) {
5590          var year = inst.drawYear + (period === "Y" ? offset : 0),
5591              month = inst.drawMonth + (period === "M" ? offset : 0),
5592              day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
5593              date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
5594  
5595          inst.selectedDay = date.getDate();
5596          inst.drawMonth = inst.selectedMonth = date.getMonth();
5597          inst.drawYear = inst.selectedYear = date.getFullYear();
5598          if (period === "M" || period === "Y") {
5599              this._notifyChange(inst);
5600          }
5601      },
5602  
5603      /* Ensure a date is within any min/max bounds. */
5604      _restrictMinMax: function(inst, date) {
5605          var minDate = this._getMinMaxDate(inst, "min"),
5606              maxDate = this._getMinMaxDate(inst, "max"),
5607              newDate = (minDate && date < minDate ? minDate : date);
5608          return (maxDate && newDate > maxDate ? maxDate : newDate);
5609      },
5610  
5611      /* Notify change of month/year. */
5612      _notifyChange: function(inst) {
5613          var onChange = this._get(inst, "onChangeMonthYear");
5614          if (onChange) {
5615              onChange.apply((inst.input ? inst.input[0] : null),
5616                  [inst.selectedYear, inst.selectedMonth + 1, inst]);
5617          }
5618      },
5619  
5620      /* Determine the number of months to show. */
5621      _getNumberOfMonths: function(inst) {
5622          var numMonths = this._get(inst, "numberOfMonths");
5623          return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
5624      },
5625  
5626      /* Determine the current maximum date - ensure no time components are set. */
5627      _getMinMaxDate: function(inst, minMax) {
5628          return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
5629      },
5630  
5631      /* Find the number of days in a given month. */
5632      _getDaysInMonth: function(year, month) {
5633          return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
5634      },
5635  
5636      /* Find the day of the week of the first of a month. */
5637      _getFirstDayOfMonth: function(year, month) {
5638          return new Date(year, month, 1).getDay();
5639      },
5640  
5641      /* Determines if we should allow a "next/prev" month display change. */
5642      _canAdjustMonth: function(inst, offset, curYear, curMonth) {
5643          var numMonths = this._getNumberOfMonths(inst),
5644              date = this._daylightSavingAdjust(new Date(curYear,
5645              curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
5646  
5647          if (offset < 0) {
5648              date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
5649          }
5650          return this._isInRange(inst, date);
5651      },
5652  
5653      /* Is the given date in the accepted range? */
5654      _isInRange: function(inst, date) {
5655          var yearSplit, currentYear,
5656              minDate = this._getMinMaxDate(inst, "min"),
5657              maxDate = this._getMinMaxDate(inst, "max"),
5658              minYear = null,
5659              maxYear = null,
5660              years = this._get(inst, "yearRange");
5661              if (years){
5662                  yearSplit = years.split(":");
5663                  currentYear = new Date().getFullYear();
5664                  minYear = parseInt(yearSplit[0], 10);
5665                  maxYear = parseInt(yearSplit[1], 10);
5666                  if ( yearSplit[0].match(/[+\-].*/) ) {
5667                      minYear += currentYear;
5668                  }
5669                  if ( yearSplit[1].match(/[+\-].*/) ) {
5670                      maxYear += currentYear;
5671                  }
5672              }
5673  
5674          return ((!minDate || date.getTime() >= minDate.getTime()) &&
5675              (!maxDate || date.getTime() <= maxDate.getTime()) &&
5676              (!minYear || date.getFullYear() >= minYear) &&
5677              (!maxYear || date.getFullYear() <= maxYear));
5678      },
5679  
5680      /* Provide the configuration settings for formatting/parsing. */
5681      _getFormatConfig: function(inst) {
5682          var shortYearCutoff = this._get(inst, "shortYearCutoff");
5683          shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
5684              new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
5685          return {shortYearCutoff: shortYearCutoff,
5686              dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
5687              monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
5688      },
5689  
5690      /* Format the given date for display. */
5691      _formatDate: function(inst, day, month, year) {
5692          if (!day) {
5693              inst.currentDay = inst.selectedDay;
5694              inst.currentMonth = inst.selectedMonth;
5695              inst.currentYear = inst.selectedYear;
5696          }
5697          var date = (day ? (typeof day === "object" ? day :
5698              this._daylightSavingAdjust(new Date(year, month, day))) :
5699              this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
5700          return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
5701      }
5702  });
5703  
5704  /*
5705   * Bind hover events for datepicker elements.
5706   * Done via delegate so the binding only occurs once in the lifetime of the parent div.
5707   * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
5708   */
5709  function datepicker_bindHover(dpDiv) {
5710      var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
5711      return dpDiv.delegate(selector, "mouseout", function() {
5712              $(this).removeClass("ui-state-hover");
5713              if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5714                  $(this).removeClass("ui-datepicker-prev-hover");
5715              }
5716              if (this.className.indexOf("ui-datepicker-next") !== -1) {
5717                  $(this).removeClass("ui-datepicker-next-hover");
5718              }
5719          })
5720          .delegate( selector, "mouseover", datepicker_handleMouseover );
5721  }
5722  
5723  function datepicker_handleMouseover() {
5724      if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
5725          $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
5726          $(this).addClass("ui-state-hover");
5727          if (this.className.indexOf("ui-datepicker-prev") !== -1) {
5728              $(this).addClass("ui-datepicker-prev-hover");
5729          }
5730          if (this.className.indexOf("ui-datepicker-next") !== -1) {
5731              $(this).addClass("ui-datepicker-next-hover");
5732          }
5733      }
5734  }
5735  
5736  /* jQuery extend now ignores nulls! */
5737  function datepicker_extendRemove(target, props) {
5738      $.extend(target, props);
5739      for (var name in props) {
5740          if (props[name] == null) {
5741              target[name] = props[name];
5742          }
5743      }
5744      return target;
5745  }
5746  
5747  /* Invoke the datepicker functionality.
5748     @param  options  string - a command, optionally followed by additional parameters or
5749                      Object - settings for attaching new datepicker functionality
5750     @return  jQuery object */
5751  $.fn.datepicker = function(options){
5752  
5753      /* Verify an empty collection wasn't passed - Fixes #6976 */
5754      if ( !this.length ) {
5755          return this;
5756      }
5757  
5758      /* Initialise the date picker. */
5759      if (!$.datepicker.initialized) {
5760          $(document).mousedown($.datepicker._checkExternalClick);
5761          $.datepicker.initialized = true;
5762      }
5763  
5764      /* Append datepicker main container to body if not exist. */
5765      if ($("#"+$.datepicker._mainDivId).length === 0) {
5766          $("body").append($.datepicker.dpDiv);
5767      }
5768  
5769      var otherArgs = Array.prototype.slice.call(arguments, 1);
5770      if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
5771          return $.datepicker["_" + options + "Datepicker"].
5772              apply($.datepicker, [this[0]].concat(otherArgs));
5773      }
5774      if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
5775          return $.datepicker["_" + options + "Datepicker"].
5776              apply($.datepicker, [this[0]].concat(otherArgs));
5777      }
5778      return this.each(function() {
5779          typeof options === "string" ?
5780              $.datepicker["_" + options + "Datepicker"].
5781                  apply($.datepicker, [this].concat(otherArgs)) :
5782              $.datepicker._attachDatepicker(this, options);
5783      });
5784  };
5785  
5786  $.datepicker = new Datepicker(); // singleton instance
5787  $.datepicker.initialized = false;
5788  $.datepicker.uuid = new Date().getTime();
5789  $.datepicker.version = "1.11.1";
5790  
5791  var datepicker = $.datepicker;
5792  
5793  
5794  /*!
5795   * jQuery UI Draggable 1.11.1
5796   * http://jqueryui.com
5797   *
5798   * Copyright 2014 jQuery Foundation and other contributors
5799   * Released under the MIT license.
5800   * http://jquery.org/license
5801   *
5802   * http://api.jqueryui.com/draggable/
5803   */
5804  
5805  
5806  $.widget("ui.draggable", $.ui.mouse, {
5807      version: "1.11.1",
5808      widgetEventPrefix: "drag",
5809      options: {
5810          addClasses: true,
5811          appendTo: "parent",
5812          axis: false,
5813          connectToSortable: false,
5814          containment: false,
5815          cursor: "auto",
5816          cursorAt: false,
5817          grid: false,
5818          handle: false,
5819          helper: "original",
5820          iframeFix: false,
5821          opacity: false,
5822          refreshPositions: false,
5823          revert: false,
5824          revertDuration: 500,
5825          scope: "default",
5826          scroll: true,
5827          scrollSensitivity: 20,
5828          scrollSpeed: 20,
5829          snap: false,
5830          snapMode: "both",
5831          snapTolerance: 20,
5832          stack: false,
5833          zIndex: false,
5834  
5835          // callbacks
5836          drag: null,
5837          start: null,
5838          stop: null
5839      },
5840      _create: function() {
5841  
5842          if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
5843              this.element[0].style.position = "relative";
5844          }
5845          if (this.options.addClasses){
5846              this.element.addClass("ui-draggable");
5847          }
5848          if (this.options.disabled){
5849              this.element.addClass("ui-draggable-disabled");
5850          }
5851          this._setHandleClassName();
5852  
5853          this._mouseInit();
5854      },
5855  
5856      _setOption: function( key, value ) {
5857          this._super( key, value );
5858          if ( key === "handle" ) {
5859              this._removeHandleClassName();
5860              this._setHandleClassName();
5861          }
5862      },
5863  
5864      _destroy: function() {
5865          if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
5866              this.destroyOnClear = true;
5867              return;
5868          }
5869          this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
5870          this._removeHandleClassName();
5871          this._mouseDestroy();
5872      },
5873  
5874      _mouseCapture: function(event) {
5875  
5876          var document = this.document[ 0 ],
5877              o = this.options;
5878  
5879          // support: IE9
5880          // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
5881          try {
5882              // Support: IE9+
5883              // If the <body> is blurred, IE will switch windows, see #9520
5884              if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
5885                  // Blur any element that currently has focus, see #4261
5886                  $( document.activeElement ).blur();
5887              }
5888          } catch ( error ) {}
5889  
5890          // among others, prevent a drag on a resizable-handle
5891          if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
5892              return false;
5893          }
5894  
5895          //Quit if we're not on a valid handle
5896          this.handle = this._getHandle(event);
5897          if (!this.handle) {
5898              return false;
5899          }
5900  
5901          $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
5902              $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
5903              .css({
5904                  width: this.offsetWidth + "px", height: this.offsetHeight + "px",
5905                  position: "absolute", opacity: "0.001", zIndex: 1000
5906              })
5907              .css($(this).offset())
5908              .appendTo("body");
5909          });
5910  
5911          return true;
5912  
5913      },
5914  
5915      _mouseStart: function(event) {
5916  
5917          var o = this.options;
5918  
5919          //Create and append the visible helper
5920          this.helper = this._createHelper(event);
5921  
5922          this.helper.addClass("ui-draggable-dragging");
5923  
5924          //Cache the helper size
5925          this._cacheHelperProportions();
5926  
5927          //If ddmanager is used for droppables, set the global draggable
5928          if ($.ui.ddmanager) {
5929              $.ui.ddmanager.current = this;
5930          }
5931  
5932          /*
5933           * - Position generation -
5934           * This block generates everything position related - it's the core of draggables.
5935           */
5936  
5937          //Cache the margins of the original element
5938          this._cacheMargins();
5939  
5940          //Store the helper's css position
5941          this.cssPosition = this.helper.css( "position" );
5942          this.scrollParent = this.helper.scrollParent( true );
5943          this.offsetParent = this.helper.offsetParent();
5944          this.offsetParentCssPosition = this.offsetParent.css( "position" );
5945  
5946          //The element's absolute position on the page minus margins
5947          this.offset = this.positionAbs = this.element.offset();
5948          this.offset = {
5949              top: this.offset.top - this.margins.top,
5950              left: this.offset.left - this.margins.left
5951          };
5952  
5953          //Reset scroll cache
5954          this.offset.scroll = false;
5955  
5956          $.extend(this.offset, {
5957              click: { //Where the click happened, relative to the element
5958                  left: event.pageX - this.offset.left,
5959                  top: event.pageY - this.offset.top
5960              },
5961              parent: this._getParentOffset(),
5962              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
5963          });
5964  
5965          //Generate the original position
5966          this.originalPosition = this.position = this._generatePosition( event, false );
5967          this.originalPageX = event.pageX;
5968          this.originalPageY = event.pageY;
5969  
5970          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
5971          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
5972  
5973          //Set a containment if given in the options
5974          this._setContainment();
5975  
5976          //Trigger event + callbacks
5977          if (this._trigger("start", event) === false) {
5978              this._clear();
5979              return false;
5980          }
5981  
5982          //Recache the helper size
5983          this._cacheHelperProportions();
5984  
5985          //Prepare the droppable offsets
5986          if ($.ui.ddmanager && !o.dropBehaviour) {
5987              $.ui.ddmanager.prepareOffsets(this, event);
5988          }
5989  
5990          this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
5991  
5992          //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
5993          if ( $.ui.ddmanager ) {
5994              $.ui.ddmanager.dragStart(this, event);
5995          }
5996  
5997          return true;
5998      },
5999  
6000      _mouseDrag: function(event, noPropagation) {
6001          // reset any necessary cached properties (see #5009)
6002          if ( this.offsetParentCssPosition === "fixed" ) {
6003              this.offset.parent = this._getParentOffset();
6004          }
6005  
6006          //Compute the helpers position
6007          this.position = this._generatePosition( event, true );
6008          this.positionAbs = this._convertPositionTo("absolute");
6009  
6010          //Call plugins and callbacks and use the resulting position if something is returned
6011          if (!noPropagation) {
6012              var ui = this._uiHash();
6013              if (this._trigger("drag", event, ui) === false) {
6014                  this._mouseUp({});
6015                  return false;
6016              }
6017              this.position = ui.position;
6018          }
6019  
6020          this.helper[ 0 ].style.left = this.position.left + "px";
6021          this.helper[ 0 ].style.top = this.position.top + "px";
6022  
6023          if ($.ui.ddmanager) {
6024              $.ui.ddmanager.drag(this, event);
6025          }
6026  
6027          return false;
6028      },
6029  
6030      _mouseStop: function(event) {
6031  
6032          //If we are using droppables, inform the manager about the drop
6033          var that = this,
6034              dropped = false;
6035          if ($.ui.ddmanager && !this.options.dropBehaviour) {
6036              dropped = $.ui.ddmanager.drop(this, event);
6037          }
6038  
6039          //if a drop comes from outside (a sortable)
6040          if (this.dropped) {
6041              dropped = this.dropped;
6042              this.dropped = false;
6043          }
6044  
6045          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))) {
6046              $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
6047                  if (that._trigger("stop", event) !== false) {
6048                      that._clear();
6049                  }
6050              });
6051          } else {
6052              if (this._trigger("stop", event) !== false) {
6053                  this._clear();
6054              }
6055          }
6056  
6057          return false;
6058      },
6059  
6060      _mouseUp: function(event) {
6061          //Remove frame helpers
6062          $("div.ui-draggable-iframeFix").each(function() {
6063              this.parentNode.removeChild(this);
6064          });
6065  
6066          //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
6067          if ( $.ui.ddmanager ) {
6068              $.ui.ddmanager.dragStop(this, event);
6069          }
6070  
6071          // The interaction is over; whether or not the click resulted in a drag, focus the element
6072          this.element.focus();
6073  
6074          return $.ui.mouse.prototype._mouseUp.call(this, event);
6075      },
6076  
6077      cancel: function() {
6078  
6079          if (this.helper.is(".ui-draggable-dragging")) {
6080              this._mouseUp({});
6081          } else {
6082              this._clear();
6083          }
6084  
6085          return this;
6086  
6087      },
6088  
6089      _getHandle: function(event) {
6090          return this.options.handle ?
6091              !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
6092              true;
6093      },
6094  
6095      _setHandleClassName: function() {
6096          this.handleElement = this.options.handle ?
6097              this.element.find( this.options.handle ) : this.element;
6098          this.handleElement.addClass( "ui-draggable-handle" );
6099      },
6100  
6101      _removeHandleClassName: function() {
6102          this.handleElement.removeClass( "ui-draggable-handle" );
6103      },
6104  
6105      _createHelper: function(event) {
6106  
6107          var o = this.options,
6108              helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[ 0 ], [ event ])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
6109  
6110          if (!helper.parents("body").length) {
6111              helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
6112          }
6113  
6114          if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
6115              helper.css("position", "absolute");
6116          }
6117  
6118          return helper;
6119  
6120      },
6121  
6122      _adjustOffsetFromHelper: function(obj) {
6123          if (typeof obj === "string") {
6124              obj = obj.split(" ");
6125          }
6126          if ($.isArray(obj)) {
6127              obj = { left: +obj[0], top: +obj[1] || 0 };
6128          }
6129          if ("left" in obj) {
6130              this.offset.click.left = obj.left + this.margins.left;
6131          }
6132          if ("right" in obj) {
6133              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
6134          }
6135          if ("top" in obj) {
6136              this.offset.click.top = obj.top + this.margins.top;
6137          }
6138          if ("bottom" in obj) {
6139              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
6140          }
6141      },
6142  
6143      _isRootNode: function( element ) {
6144          return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
6145      },
6146  
6147      _getParentOffset: function() {
6148  
6149          //Get the offsetParent and cache its position
6150          var po = this.offsetParent.offset(),
6151              document = this.document[ 0 ];
6152  
6153          // This is a special case where we need to modify a offset calculated on start, since the following happened:
6154          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
6155          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
6156          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
6157          if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
6158              po.left += this.scrollParent.scrollLeft();
6159              po.top += this.scrollParent.scrollTop();
6160          }
6161  
6162          if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
6163              po = { top: 0, left: 0 };
6164          }
6165  
6166          return {
6167              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
6168              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
6169          };
6170  
6171      },
6172  
6173      _getRelativeOffset: function() {
6174          if ( this.cssPosition !== "relative" ) {
6175              return { top: 0, left: 0 };
6176          }
6177  
6178          var p = this.element.position(),
6179              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6180  
6181          return {
6182              top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
6183              left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
6184          };
6185  
6186      },
6187  
6188      _cacheMargins: function() {
6189          this.margins = {
6190              left: (parseInt(this.element.css("marginLeft"), 10) || 0),
6191              top: (parseInt(this.element.css("marginTop"), 10) || 0),
6192              right: (parseInt(this.element.css("marginRight"), 10) || 0),
6193              bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
6194          };
6195      },
6196  
6197      _cacheHelperProportions: function() {
6198          this.helperProportions = {
6199              width: this.helper.outerWidth(),
6200              height: this.helper.outerHeight()
6201          };
6202      },
6203  
6204      _setContainment: function() {
6205  
6206          var over, c, ce,
6207              o = this.options,
6208              document = this.document[ 0 ];
6209  
6210          this.relativeContainer = null;
6211  
6212          if ( !o.containment ) {
6213              this.containment = null;
6214              return;
6215          }
6216  
6217          if ( o.containment === "window" ) {
6218              this.containment = [
6219                  $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
6220                  $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
6221                  $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
6222                  $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6223              ];
6224              return;
6225          }
6226  
6227          if ( o.containment === "document") {
6228              this.containment = [
6229                  0,
6230                  0,
6231                  $( document ).width() - this.helperProportions.width - this.margins.left,
6232                  ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
6233              ];
6234              return;
6235          }
6236  
6237          if ( o.containment.constructor === Array ) {
6238              this.containment = o.containment;
6239              return;
6240          }
6241  
6242          if ( o.containment === "parent" ) {
6243              o.containment = this.helper[ 0 ].parentNode;
6244          }
6245  
6246          c = $( o.containment );
6247          ce = c[ 0 ];
6248  
6249          if ( !ce ) {
6250              return;
6251          }
6252  
6253          over = c.css( "overflow" ) !== "hidden";
6254  
6255          this.containment = [
6256              ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
6257              ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
6258              ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
6259              ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top  - this.margins.bottom
6260          ];
6261          this.relativeContainer = c;
6262      },
6263  
6264      _convertPositionTo: function(d, pos) {
6265  
6266          if (!pos) {
6267              pos = this.position;
6268          }
6269  
6270          var mod = d === "absolute" ? 1 : -1,
6271              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
6272  
6273          return {
6274              top: (
6275                  pos.top    +                                                                // The absolute mouse position
6276                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
6277                  this.offset.parent.top * mod -                                        // The offsetParent's offset without borders (offset + border)
6278                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
6279              ),
6280              left: (
6281                  pos.left +                                                                // The absolute mouse position
6282                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
6283                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
6284                  ( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
6285              )
6286          };
6287  
6288      },
6289  
6290      _generatePosition: function( event, constrainPosition ) {
6291  
6292          var containment, co, top, left,
6293              o = this.options,
6294              scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
6295              pageX = event.pageX,
6296              pageY = event.pageY;
6297  
6298          // Cache the scroll
6299          if ( !scrollIsRootNode || !this.offset.scroll ) {
6300              this.offset.scroll = {
6301                  top: this.scrollParent.scrollTop(),
6302                  left: this.scrollParent.scrollLeft()
6303              };
6304          }
6305  
6306          /*
6307           * - Position constraining -
6308           * Constrain the position to a mix of grid, containment.
6309           */
6310  
6311          // If we are not dragging yet, we won't check for options
6312          if ( constrainPosition ) {
6313              if ( this.containment ) {
6314                  if ( this.relativeContainer ){
6315                      co = this.relativeContainer.offset();
6316                      containment = [
6317                          this.containment[ 0 ] + co.left,
6318                          this.containment[ 1 ] + co.top,
6319                          this.containment[ 2 ] + co.left,
6320                          this.containment[ 3 ] + co.top
6321                      ];
6322                  } else {
6323                      containment = this.containment;
6324                  }
6325  
6326                  if (event.pageX - this.offset.click.left < containment[0]) {
6327                      pageX = containment[0] + this.offset.click.left;
6328                  }
6329                  if (event.pageY - this.offset.click.top < containment[1]) {
6330                      pageY = containment[1] + this.offset.click.top;
6331                  }
6332                  if (event.pageX - this.offset.click.left > containment[2]) {
6333                      pageX = containment[2] + this.offset.click.left;
6334                  }
6335                  if (event.pageY - this.offset.click.top > containment[3]) {
6336                      pageY = containment[3] + this.offset.click.top;
6337                  }
6338              }
6339  
6340              if (o.grid) {
6341                  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
6342                  top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
6343                  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;
6344  
6345                  left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
6346                  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;
6347              }
6348  
6349              if ( o.axis === "y" ) {
6350                  pageX = this.originalPageX;
6351              }
6352  
6353              if ( o.axis === "x" ) {
6354                  pageY = this.originalPageY;
6355              }
6356          }
6357  
6358          return {
6359              top: (
6360                  pageY -                                                                    // The absolute mouse position
6361                  this.offset.click.top    -                                                // Click offset (relative to the element)
6362                  this.offset.relative.top -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6363                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
6364                  ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
6365              ),
6366              left: (
6367                  pageX -                                                                    // The absolute mouse position
6368                  this.offset.click.left -                                                // Click offset (relative to the element)
6369                  this.offset.relative.left -                                                // Only for relative positioned nodes: Relative offset from element to offset parent
6370                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
6371                  ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
6372              )
6373          };
6374  
6375      },
6376  
6377      _clear: function() {
6378          this.helper.removeClass("ui-draggable-dragging");
6379          if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
6380              this.helper.remove();
6381          }
6382          this.helper = null;
6383          this.cancelHelperRemoval = false;
6384          if ( this.destroyOnClear ) {
6385              this.destroy();
6386          }
6387      },
6388  
6389      // From now on bulk stuff - mainly helpers
6390  
6391      _trigger: function(type, event, ui) {
6392          ui = ui || this._uiHash();
6393          $.ui.plugin.call( this, type, [ event, ui, this ], true );
6394          //The absolute position has to be recalculated after plugins
6395          if (type === "drag") {
6396              this.positionAbs = this._convertPositionTo("absolute");
6397          }
6398          return $.Widget.prototype._trigger.call(this, type, event, ui);
6399      },
6400  
6401      plugins: {},
6402  
6403      _uiHash: function() {
6404          return {
6405              helper: this.helper,
6406              position: this.position,
6407              originalPosition: this.originalPosition,
6408              offset: this.positionAbs
6409          };
6410      }
6411  
6412  });
6413  
6414  $.ui.plugin.add("draggable", "connectToSortable", {
6415      start: function( event, ui, inst ) {
6416  
6417          var o = inst.options,
6418              uiSortable = $.extend({}, ui, { item: inst.element });
6419          inst.sortables = [];
6420          $(o.connectToSortable).each(function() {
6421              var sortable = $( this ).sortable( "instance" );
6422              if (sortable && !sortable.options.disabled) {
6423                  inst.sortables.push({
6424                      instance: sortable,
6425                      shouldRevert: sortable.options.revert
6426                  });
6427                  sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
6428                  sortable._trigger("activate", event, uiSortable);
6429              }
6430          });
6431  
6432      },
6433      stop: function( event, ui, inst ) {
6434  
6435          //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
6436          var uiSortable = $.extend( {}, ui, {
6437              item: inst.element
6438          });
6439  
6440          $.each(inst.sortables, function() {
6441              if (this.instance.isOver) {
6442  
6443                  this.instance.isOver = 0;
6444  
6445                  inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
6446                  this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
6447  
6448                  //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
6449                  if (this.shouldRevert) {
6450                      this.instance.options.revert = this.shouldRevert;
6451                  }
6452  
6453                  //Trigger the stop of the sortable
6454                  this.instance._mouseStop(event);
6455  
6456                  this.instance.options.helper = this.instance.options._helper;
6457  
6458                  //If the helper has been the original item, restore properties in the sortable
6459                  if (inst.options.helper === "original") {
6460                      this.instance.currentItem.css({ top: "auto", left: "auto" });
6461                  }
6462  
6463              } else {
6464                  this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
6465                  this.instance._trigger("deactivate", event, uiSortable);
6466              }
6467  
6468          });
6469  
6470      },
6471      drag: function( event, ui, inst ) {
6472  
6473          var that = this;
6474  
6475          $.each(inst.sortables, function() {
6476  
6477              var innermostIntersecting = false,
6478                  thisSortable = this;
6479  
6480              //Copy over some variables to allow calling the sortable's native _intersectsWith
6481              this.instance.positionAbs = inst.positionAbs;
6482              this.instance.helperProportions = inst.helperProportions;
6483              this.instance.offset.click = inst.offset.click;
6484  
6485              if (this.instance._intersectsWith(this.instance.containerCache)) {
6486                  innermostIntersecting = true;
6487                  $.each(inst.sortables, function() {
6488                      this.instance.positionAbs = inst.positionAbs;
6489                      this.instance.helperProportions = inst.helperProportions;
6490                      this.instance.offset.click = inst.offset.click;
6491                      if (this !== thisSortable &&
6492                          this.instance._intersectsWith(this.instance.containerCache) &&
6493                          $.contains(thisSortable.instance.element[0], this.instance.element[0])
6494                      ) {
6495                          innermostIntersecting = false;
6496                      }
6497                      return innermostIntersecting;
6498                  });
6499              }
6500  
6501              if (innermostIntersecting) {
6502                  //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
6503                  if (!this.instance.isOver) {
6504  
6505                      this.instance.isOver = 1;
6506                      //Now we fake the start of dragging for the sortable instance,
6507                      //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
6508                      //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
6509                      this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
6510                      this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
6511                      this.instance.options.helper = function() { return ui.helper[0]; };
6512  
6513                      event.target = this.instance.currentItem[0];
6514                      this.instance._mouseCapture(event, true);
6515                      this.instance._mouseStart(event, true, true);
6516  
6517                      //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
6518                      this.instance.offset.click.top = inst.offset.click.top;
6519                      this.instance.offset.click.left = inst.offset.click.left;
6520                      this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
6521                      this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
6522  
6523                      inst._trigger("toSortable", event);
6524                      inst.dropped = this.instance.element; //draggable revert needs that
6525                      //hack so receive/update callbacks work (mostly)
6526                      inst.currentItem = inst.element;
6527                      this.instance.fromOutside = inst;
6528  
6529                  }
6530  
6531                  //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
6532                  if (this.instance.currentItem) {
6533                      this.instance._mouseDrag(event);
6534                  }
6535  
6536              } else {
6537  
6538                  //If it doesn't intersect with the sortable, and it intersected before,
6539                  //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
6540                  if (this.instance.isOver) {
6541  
6542                      this.instance.isOver = 0;
6543                      this.instance.cancelHelperRemoval = true;
6544  
6545                      //Prevent reverting on this forced stop
6546                      this.instance.options.revert = false;
6547  
6548                      // The out event needs to be triggered independently
6549                      this.instance._trigger("out", event, this.instance._uiHash(this.instance));
6550  
6551                      this.instance._mouseStop(event, true);
6552                      this.instance.options.helper = this.instance.options._helper;
6553  
6554                      //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
6555                      this.instance.currentItem.remove();
6556                      if (this.instance.placeholder) {
6557                          this.instance.placeholder.remove();
6558                      }
6559  
6560                      inst._trigger("fromSortable", event);
6561                      inst.dropped = false; //draggable revert needs that
6562                  }
6563  
6564              }
6565  
6566          });
6567  
6568      }
6569  });
6570  
6571  $.ui.plugin.add("draggable", "cursor", {
6572      start: function( event, ui, instance ) {
6573          var t = $( "body" ),
6574              o = instance.options;
6575  
6576          if (t.css("cursor")) {
6577              o._cursor = t.css("cursor");
6578          }
6579          t.css("cursor", o.cursor);
6580      },
6581      stop: function( event, ui, instance ) {
6582          var o = instance.options;
6583          if (o._cursor) {
6584              $("body").css("cursor", o._cursor);
6585          }
6586      }
6587  });
6588  
6589  $.ui.plugin.add("draggable", "opacity", {
6590      start: function( event, ui, instance ) {
6591          var t = $( ui.helper ),
6592              o = instance.options;
6593          if (t.css("opacity")) {
6594              o._opacity = t.css("opacity");
6595          }
6596          t.css("opacity", o.opacity);
6597      },
6598      stop: function( event, ui, instance ) {
6599          var o = instance.options;
6600          if (o._opacity) {
6601              $(ui.helper).css("opacity", o._opacity);
6602          }
6603      }
6604  });
6605  
6606  $.ui.plugin.add("draggable", "scroll", {
6607      start: function( event, ui, i ) {
6608          if ( !i.scrollParentNotHidden ) {
6609              i.scrollParentNotHidden = i.helper.scrollParent( false );
6610          }
6611  
6612          if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
6613              i.overflowOffset = i.scrollParentNotHidden.offset();
6614          }
6615      },
6616      drag: function( event, ui, i  ) {
6617  
6618          var o = i.options,
6619              scrolled = false,
6620              scrollParent = i.scrollParentNotHidden[ 0 ],
6621              document = i.document[ 0 ];
6622  
6623          if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
6624              if ( !o.axis || o.axis !== "x" ) {
6625                  if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
6626                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
6627                  } else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
6628                      scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
6629                  }
6630              }
6631  
6632              if ( !o.axis || o.axis !== "y" ) {
6633                  if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
6634                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
6635                  } else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
6636                      scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
6637                  }
6638              }
6639  
6640          } else {
6641  
6642              if (!o.axis || o.axis !== "x") {
6643                  if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
6644                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
6645                  } else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
6646                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
6647                  }
6648              }
6649  
6650              if (!o.axis || o.axis !== "y") {
6651                  if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
6652                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
6653                  } else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
6654                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
6655                  }
6656              }
6657  
6658          }
6659  
6660          if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
6661              $.ui.ddmanager.prepareOffsets(i, event);
6662          }
6663  
6664      }
6665  });
6666  
6667  $.ui.plugin.add("draggable", "snap", {
6668      start: function( event, ui, i ) {
6669  
6670          var o = i.options;
6671  
6672          i.snapElements = [];
6673  
6674          $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
6675              var $t = $(this),
6676                  $o = $t.offset();
6677              if (this !== i.element[0]) {
6678                  i.snapElements.push({
6679                      item: this,
6680                      width: $t.outerWidth(), height: $t.outerHeight(),
6681                      top: $o.top, left: $o.left
6682                  });
6683              }
6684          });
6685  
6686      },
6687      drag: function( event, ui, inst ) {
6688  
6689          var ts, bs, ls, rs, l, r, t, b, i, first,
6690              o = inst.options,
6691              d = o.snapTolerance,
6692              x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
6693              y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
6694  
6695          for (i = inst.snapElements.length - 1; i >= 0; i--){
6696  
6697              l = inst.snapElements[i].left;
6698              r = l + inst.snapElements[i].width;
6699              t = inst.snapElements[i].top;
6700              b = t + inst.snapElements[i].height;
6701  
6702              if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
6703                  if (inst.snapElements[i].snapping) {
6704                      (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6705                  }
6706                  inst.snapElements[i].snapping = false;
6707                  continue;
6708              }
6709  
6710              if (o.snapMode !== "inner") {
6711                  ts = Math.abs(t - y2) <= d;
6712                  bs = Math.abs(b - y1) <= d;
6713                  ls = Math.abs(l - x2) <= d;
6714                  rs = Math.abs(r - x1) <= d;
6715                  if (ts) {
6716                      ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
6717                  }
6718                  if (bs) {
6719                      ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
6720                  }
6721                  if (ls) {
6722                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
6723                  }
6724                  if (rs) {
6725                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
6726                  }
6727              }
6728  
6729              first = (ts || bs || ls || rs);
6730  
6731              if (o.snapMode !== "outer") {
6732                  ts = Math.abs(t - y1) <= d;
6733                  bs = Math.abs(b - y2) <= d;
6734                  ls = Math.abs(l - x1) <= d;
6735                  rs = Math.abs(r - x2) <= d;
6736                  if (ts) {
6737                      ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
6738                  }
6739                  if (bs) {
6740                      ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
6741                  }
6742                  if (ls) {
6743                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
6744                  }
6745                  if (rs) {
6746                      ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
6747                  }
6748              }
6749  
6750              if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
6751                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
6752              }
6753              inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
6754  
6755          }
6756  
6757      }
6758  });
6759  
6760  $.ui.plugin.add("draggable", "stack", {
6761      start: function( event, ui, instance ) {
6762          var min,
6763              o = instance.options,
6764              group = $.makeArray($(o.stack)).sort(function(a, b) {
6765                  return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
6766              });
6767  
6768          if (!group.length) { return; }
6769  
6770          min = parseInt($(group[0]).css("zIndex"), 10) || 0;
6771          $(group).each(function(i) {
6772              $(this).css("zIndex", min + i);
6773          });
6774          this.css("zIndex", (min + group.length));
6775      }
6776  });
6777  
6778  $.ui.plugin.add("draggable", "zIndex", {
6779      start: function( event, ui, instance ) {
6780          var t = $( ui.helper ),
6781              o = instance.options;
6782  
6783          if (t.css("zIndex")) {
6784              o._zIndex = t.css("zIndex");
6785          }
6786          t.css("zIndex", o.zIndex);
6787      },
6788      stop: function( event, ui, instance ) {
6789          var o = instance.options;
6790  
6791          if (o._zIndex) {
6792              $(ui.helper).css("zIndex", o._zIndex);
6793          }
6794      }
6795  });
6796  
6797  var draggable = $.ui.draggable;
6798  
6799  
6800  /*!
6801   * jQuery UI Resizable 1.11.1
6802   * http://jqueryui.com
6803   *
6804   * Copyright 2014 jQuery Foundation and other contributors
6805   * Released under the MIT license.
6806   * http://jquery.org/license
6807   *
6808   * http://api.jqueryui.com/resizable/
6809   */
6810  
6811  
6812  $.widget("ui.resizable", $.ui.mouse, {
6813      version: "1.11.1",
6814      widgetEventPrefix: "resize",
6815      options: {
6816          alsoResize: false,
6817          animate: false,
6818          animateDuration: "slow",
6819          animateEasing: "swing",
6820          aspectRatio: false,
6821          autoHide: false,
6822          containment: false,
6823          ghost: false,
6824          grid: false,
6825          handles: "e,s,se",
6826          helper: false,
6827          maxHeight: null,
6828          maxWidth: null,
6829          minHeight: 10,
6830          minWidth: 10,
6831          // See #7960
6832          zIndex: 90,
6833  
6834          // callbacks
6835          resize: null,
6836          start: null,
6837          stop: null
6838      },
6839  
6840      _num: function( value ) {
6841          return parseInt( value, 10 ) || 0;
6842      },
6843  
6844      _isNumber: function( value ) {
6845          return !isNaN( parseInt( value, 10 ) );
6846      },
6847  
6848      _hasScroll: function( el, a ) {
6849  
6850          if ( $( el ).css( "overflow" ) === "hidden") {
6851              return false;
6852          }
6853  
6854          var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
6855              has = false;
6856  
6857          if ( el[ scroll ] > 0 ) {
6858              return true;
6859          }
6860  
6861          // TODO: determine which cases actually cause this to happen
6862          // if the element doesn't have the scroll set, see if it's possible to
6863          // set the scroll
6864          el[ scroll ] = 1;
6865          has = ( el[ scroll ] > 0 );
6866          el[ scroll ] = 0;
6867          return has;
6868      },
6869  
6870      _create: function() {
6871  
6872          var n, i, handle, axis, hname,
6873              that = this,
6874              o = this.options;
6875          this.element.addClass("ui-resizable");
6876  
6877          $.extend(this, {
6878              _aspectRatio: !!(o.aspectRatio),
6879              aspectRatio: o.aspectRatio,
6880              originalElement: this.element,
6881              _proportionallyResizeElements: [],
6882              _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
6883          });
6884  
6885          // Wrap the element if it cannot hold child nodes
6886          if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
6887  
6888              this.element.wrap(
6889                  $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
6890                      position: this.element.css("position"),
6891                      width: this.element.outerWidth(),
6892                      height: this.element.outerHeight(),
6893                      top: this.element.css("top"),
6894                      left: this.element.css("left")
6895                  })
6896              );
6897  
6898              this.element = this.element.parent().data(
6899                  "ui-resizable", this.element.resizable( "instance" )
6900              );
6901  
6902              this.elementIsWrapper = true;
6903  
6904              this.element.css({
6905                  marginLeft: this.originalElement.css("marginLeft"),
6906                  marginTop: this.originalElement.css("marginTop"),
6907                  marginRight: this.originalElement.css("marginRight"),
6908                  marginBottom: this.originalElement.css("marginBottom")
6909              });
6910              this.originalElement.css({
6911                  marginLeft: 0,
6912                  marginTop: 0,
6913                  marginRight: 0,
6914                  marginBottom: 0
6915              });
6916              // support: Safari
6917              // Prevent Safari textarea resize
6918              this.originalResizeStyle = this.originalElement.css("resize");
6919              this.originalElement.css("resize", "none");
6920  
6921              this._proportionallyResizeElements.push( this.originalElement.css({
6922                  position: "static",
6923                  zoom: 1,
6924                  display: "block"
6925              }) );
6926  
6927              // support: IE9
6928              // avoid IE jump (hard set the margin)
6929              this.originalElement.css({ margin: this.originalElement.css("margin") });
6930  
6931              this._proportionallyResize();
6932          }
6933  
6934          this.handles = o.handles ||
6935              ( !$(".ui-resizable-handle", this.element).length ?
6936                  "e,s,se" : {
6937                      n: ".ui-resizable-n",
6938                      e: ".ui-resizable-e",
6939                      s: ".ui-resizable-s",
6940                      w: ".ui-resizable-w",
6941                      se: ".ui-resizable-se",
6942                      sw: ".ui-resizable-sw",
6943                      ne: ".ui-resizable-ne",
6944                      nw: ".ui-resizable-nw"
6945                  } );
6946  
6947          if (this.handles.constructor === String) {
6948  
6949              if ( this.handles === "all") {
6950                  this.handles = "n,e,s,w,se,sw,ne,nw";
6951              }
6952  
6953              n = this.handles.split(",");
6954              this.handles = {};
6955  
6956              for (i = 0; i < n.length; i++) {
6957  
6958                  handle = $.trim(n[i]);
6959                  hname = "ui-resizable-" + handle;
6960                  axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
6961  
6962                  axis.css({ zIndex: o.zIndex });
6963  
6964                  // TODO : What's going on here?
6965                  if ("se" === handle) {
6966                      axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
6967                  }
6968  
6969                  this.handles[handle] = ".ui-resizable-" + handle;
6970                  this.element.append(axis);
6971              }
6972  
6973          }
6974  
6975          this._renderAxis = function(target) {
6976  
6977              var i, axis, padPos, padWrapper;
6978  
6979              target = target || this.element;
6980  
6981              for (i in this.handles) {
6982  
6983                  if (this.handles[i].constructor === String) {
6984                      this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
6985                  }
6986  
6987                  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
6988  
6989                      axis = $(this.handles[i], this.element);
6990  
6991                      padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
6992  
6993                      padPos = [ "padding",
6994                          /ne|nw|n/.test(i) ? "Top" :
6995                          /se|sw|s/.test(i) ? "Bottom" :
6996                          /^e$/.test(i) ? "Right" : "Left" ].join("");
6997  
6998                      target.css(padPos, padWrapper);
6999  
7000                      this._proportionallyResize();
7001  
7002                  }
7003  
7004                  // TODO: What's that good for? There's not anything to be executed left
7005                  if (!$(this.handles[i]).length) {
7006                      continue;
7007                  }
7008              }
7009          };
7010  
7011          // TODO: make renderAxis a prototype function
7012          this._renderAxis(this.element);
7013  
7014          this._handles = $(".ui-resizable-handle", this.element)
7015              .disableSelection();
7016  
7017          this._handles.mouseover(function() {
7018              if (!that.resizing) {
7019                  if (this.className) {
7020                      axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
7021                  }
7022                  that.axis = axis && axis[1] ? axis[1] : "se";
7023              }
7024          });
7025  
7026          if (o.autoHide) {
7027              this._handles.hide();
7028              $(this.element)
7029                  .addClass("ui-resizable-autohide")
7030                  .mouseenter(function() {
7031                      if (o.disabled) {
7032                          return;
7033                      }
7034                      $(this).removeClass("ui-resizable-autohide");
7035                      that._handles.show();
7036                  })
7037                  .mouseleave(function() {
7038                      if (o.disabled) {
7039                          return;
7040                      }
7041                      if (!that.resizing) {
7042                          $(this).addClass("ui-resizable-autohide");
7043                          that._handles.hide();
7044                      }
7045                  });
7046          }
7047  
7048          this._mouseInit();
7049  
7050      },
7051  
7052      _destroy: function() {
7053  
7054          this._mouseDestroy();
7055  
7056          var wrapper,
7057              _destroy = function(exp) {
7058                  $(exp)
7059                      .removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
7060                      .removeData("resizable")
7061                      .removeData("ui-resizable")
7062                      .unbind(".resizable")
7063                      .find(".ui-resizable-handle")
7064                          .remove();
7065              };
7066  
7067          // TODO: Unwrap at same DOM position
7068          if (this.elementIsWrapper) {
7069              _destroy(this.element);
7070              wrapper = this.element;
7071              this.originalElement.css({
7072                  position: wrapper.css("position"),
7073                  width: wrapper.outerWidth(),
7074                  height: wrapper.outerHeight(),
7075                  top: wrapper.css("top"),
7076                  left: wrapper.css("left")
7077              }).insertAfter( wrapper );
7078              wrapper.remove();
7079          }
7080  
7081          this.originalElement.css("resize", this.originalResizeStyle);
7082          _destroy(this.originalElement);
7083  
7084          return this;
7085      },
7086  
7087      _mouseCapture: function(event) {
7088          var i, handle,
7089              capture = false;
7090  
7091          for (i in this.handles) {
7092              handle = $(this.handles[i])[0];
7093              if (handle === event.target || $.contains(handle, event.target)) {
7094                  capture = true;
7095              }
7096          }
7097  
7098          return !this.options.disabled && capture;
7099      },
7100  
7101      _mouseStart: function(event) {
7102  
7103          var curleft, curtop, cursor,
7104              o = this.options,
7105              el = this.element;
7106  
7107          this.resizing = true;
7108  
7109          this._renderProxy();
7110  
7111          curleft = this._num(this.helper.css("left"));
7112          curtop = this._num(this.helper.css("top"));
7113  
7114          if (o.containment) {
7115              curleft += $(o.containment).scrollLeft() || 0;
7116              curtop += $(o.containment).scrollTop() || 0;
7117          }
7118  
7119          this.offset = this.helper.offset();
7120          this.position = { left: curleft, top: curtop };
7121  
7122          this.size = this._helper ? {
7123                  width: this.helper.width(),
7124                  height: this.helper.height()
7125              } : {
7126                  width: el.width(),
7127                  height: el.height()
7128              };
7129  
7130          this.originalSize = this._helper ? {
7131                  width: el.outerWidth(),
7132                  height: el.outerHeight()
7133              } : {
7134                  width: el.width(),
7135                  height: el.height()
7136              };
7137  
7138          this.sizeDiff = {
7139              width: el.outerWidth() - el.width(),
7140              height: el.outerHeight() - el.height()
7141          };
7142  
7143          this.originalPosition = { left: curleft, top: curtop };
7144          this.originalMousePosition = { left: event.pageX, top: event.pageY };
7145  
7146          this.aspectRatio = (typeof o.aspectRatio === "number") ?
7147              o.aspectRatio :
7148              ((this.originalSize.width / this.originalSize.height) || 1);
7149  
7150          cursor = $(".ui-resizable-" + this.axis).css("cursor");
7151          $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
7152  
7153          el.addClass("ui-resizable-resizing");
7154          this._propagate("start", event);
7155          return true;
7156      },
7157  
7158      _mouseDrag: function(event) {
7159  
7160          var data, props,
7161              smp = this.originalMousePosition,
7162              a = this.axis,
7163              dx = (event.pageX - smp.left) || 0,
7164              dy = (event.pageY - smp.top) || 0,
7165              trigger = this._change[a];
7166  
7167          this._updatePrevProperties();
7168  
7169          if (!trigger) {
7170              return false;
7171          }
7172  
7173          data = trigger.apply(this, [ event, dx, dy ]);
7174  
7175          this._updateVirtualBoundaries(event.shiftKey);
7176          if (this._aspectRatio || event.shiftKey) {
7177              data = this._updateRatio(data, event);
7178          }
7179  
7180          data = this._respectSize(data, event);
7181  
7182          this._updateCache(data);
7183  
7184          this._propagate("resize", event);
7185  
7186          props = this._applyChanges();
7187  
7188          if ( !this._helper && this._proportionallyResizeElements.length ) {
7189              this._proportionallyResize();
7190          }
7191  
7192          if ( !$.isEmptyObject( props ) ) {
7193              this._updatePrevProperties();
7194              this._trigger( "resize", event, this.ui() );
7195              this._applyChanges();
7196          }
7197  
7198          return false;
7199      },
7200  
7201      _mouseStop: function(event) {
7202  
7203          this.resizing = false;
7204          var pr, ista, soffseth, soffsetw, s, left, top,
7205              o = this.options, that = this;
7206  
7207          if (this._helper) {
7208  
7209              pr = this._proportionallyResizeElements;
7210              ista = pr.length && (/textarea/i).test(pr[0].nodeName);
7211              soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
7212              soffsetw = ista ? 0 : that.sizeDiff.width;
7213  
7214              s = {
7215                  width: (that.helper.width()  - soffsetw),
7216                  height: (that.helper.height() - soffseth)
7217              };
7218              left = (parseInt(that.element.css("left"), 10) +
7219                  (that.position.left - that.originalPosition.left)) || null;
7220              top = (parseInt(that.element.css("top"), 10) +
7221                  (that.position.top - that.originalPosition.top)) || null;
7222  
7223              if (!o.animate) {
7224                  this.element.css($.extend(s, { top: top, left: left }));
7225              }
7226  
7227              that.helper.height(that.size.height);
7228              that.helper.width(that.size.width);
7229  
7230              if (this._helper && !o.animate) {
7231                  this._proportionallyResize();
7232              }
7233          }
7234  
7235          $("body").css("cursor", "auto");
7236  
7237          this.element.removeClass("ui-resizable-resizing");
7238  
7239          this._propagate("stop", event);
7240  
7241          if (this._helper) {
7242              this.helper.remove();
7243          }
7244  
7245          return false;
7246  
7247      },
7248  
7249      _updatePrevProperties: function() {
7250          this.prevPosition = {
7251              top: this.position.top,
7252              left: this.position.left
7253          };
7254          this.prevSize = {
7255              width: this.size.width,
7256              height: this.size.height
7257          };
7258      },
7259  
7260      _applyChanges: function() {
7261          var props = {};
7262  
7263          if ( this.position.top !== this.prevPosition.top ) {
7264              props.top = this.position.top + "px";
7265          }
7266          if ( this.position.left !== this.prevPosition.left ) {
7267              props.left = this.position.left + "px";
7268          }
7269          if ( this.size.width !== this.prevSize.width ) {
7270              props.width = this.size.width + "px";
7271          }
7272          if ( this.size.height !== this.prevSize.height ) {
7273              props.height = this.size.height + "px";
7274          }
7275  
7276          this.helper.css( props );
7277  
7278          return props;
7279      },
7280  
7281      _updateVirtualBoundaries: function(forceAspectRatio) {
7282          var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
7283              o = this.options;
7284  
7285          b = {
7286              minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
7287              maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
7288              minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
7289              maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
7290          };
7291  
7292          if (this._aspectRatio || forceAspectRatio) {
7293              pMinWidth = b.minHeight * this.aspectRatio;
7294              pMinHeight = b.minWidth / this.aspectRatio;
7295              pMaxWidth = b.maxHeight * this.aspectRatio;
7296              pMaxHeight = b.maxWidth / this.aspectRatio;
7297  
7298              if (pMinWidth > b.minWidth) {
7299                  b.minWidth = pMinWidth;
7300              }
7301              if (pMinHeight > b.minHeight) {
7302                  b.minHeight = pMinHeight;
7303              }
7304              if (pMaxWidth < b.maxWidth) {
7305                  b.maxWidth = pMaxWidth;
7306              }
7307              if (pMaxHeight < b.maxHeight) {
7308                  b.maxHeight = pMaxHeight;
7309              }
7310          }
7311          this._vBoundaries = b;
7312      },
7313  
7314      _updateCache: function(data) {
7315          this.offset = this.helper.offset();
7316          if (this._isNumber(data.left)) {
7317              this.position.left = data.left;
7318          }
7319          if (this._isNumber(data.top)) {
7320              this.position.top = data.top;
7321          }
7322          if (this._isNumber(data.height)) {
7323              this.size.height = data.height;
7324          }
7325          if (this._isNumber(data.width)) {
7326              this.size.width = data.width;
7327          }
7328      },
7329  
7330      _updateRatio: function( data ) {
7331  
7332          var cpos = this.position,
7333              csize = this.size,
7334              a = this.axis;
7335  
7336          if (this._isNumber(data.height)) {
7337              data.width = (data.height * this.aspectRatio);
7338          } else if (this._isNumber(data.width)) {
7339              data.height = (data.width / this.aspectRatio);
7340          }
7341  
7342          if (a === "sw") {
7343              data.left = cpos.left + (csize.width - data.width);
7344              data.top = null;
7345          }
7346          if (a === "nw") {
7347              data.top = cpos.top + (csize.height - data.height);
7348              data.left = cpos.left + (csize.width - data.width);
7349          }
7350  
7351          return data;
7352      },
7353  
7354      _respectSize: function( data ) {
7355  
7356          var o = this._vBoundaries,
7357              a = this.axis,
7358              ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
7359              ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
7360              isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
7361              isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
7362              dw = this.originalPosition.left + this.originalSize.width,
7363              dh = this.position.top + this.size.height,
7364              cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
7365          if (isminw) {
7366              data.width = o.minWidth;
7367          }
7368          if (isminh) {
7369              data.height = o.minHeight;
7370          }
7371          if (ismaxw) {
7372              data.width = o.maxWidth;
7373          }
7374          if (ismaxh) {
7375              data.height = o.maxHeight;
7376          }
7377  
7378          if (isminw && cw) {
7379              data.left = dw - o.minWidth;
7380          }
7381          if (ismaxw && cw) {
7382              data.left = dw - o.maxWidth;
7383          }
7384          if (isminh && ch) {
7385              data.top = dh - o.minHeight;
7386          }
7387          if (ismaxh && ch) {
7388              data.top = dh - o.maxHeight;
7389          }
7390  
7391          // Fixing jump error on top/left - bug #2330
7392          if (!data.width && !data.height && !data.left && data.top) {
7393              data.top = null;
7394          } else if (!data.width && !data.height && !data.top && data.left) {
7395              data.left = null;
7396          }
7397  
7398          return data;
7399      },
7400  
7401      _getPaddingPlusBorderDimensions: function( element ) {
7402          var i = 0,
7403              widths = [],
7404              borders = [
7405                  element.css( "borderTopWidth" ),
7406                  element.css( "borderRightWidth" ),
7407                  element.css( "borderBottomWidth" ),
7408                  element.css( "borderLeftWidth" )
7409              ],
7410              paddings = [
7411                  element.css( "paddingTop" ),
7412                  element.css( "paddingRight" ),
7413                  element.css( "paddingBottom" ),
7414                  element.css( "paddingLeft" )
7415              ];
7416  
7417          for ( ; i < 4; i++ ) {
7418              widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
7419              widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
7420          }
7421  
7422          return {
7423              height: widths[ 0 ] + widths[ 2 ],
7424              width: widths[ 1 ] + widths[ 3 ]
7425          };
7426      },
7427  
7428      _proportionallyResize: function() {
7429  
7430          if (!this._proportionallyResizeElements.length) {
7431              return;
7432          }
7433  
7434          var prel,
7435              i = 0,
7436              element = this.helper || this.element;
7437  
7438          for ( ; i < this._proportionallyResizeElements.length; i++) {
7439  
7440              prel = this._proportionallyResizeElements[i];
7441  
7442              // TODO: Seems like a bug to cache this.outerDimensions
7443              // considering that we are in a loop.
7444              if (!this.outerDimensions) {
7445                  this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
7446              }
7447  
7448              prel.css({
7449                  height: (element.height() - this.outerDimensions.height) || 0,
7450                  width: (element.width() - this.outerDimensions.width) || 0
7451              });
7452  
7453          }
7454  
7455      },
7456  
7457      _renderProxy: function() {
7458  
7459          var el = this.element, o = this.options;
7460          this.elementOffset = el.offset();
7461  
7462          if (this._helper) {
7463  
7464              this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
7465  
7466              this.helper.addClass(this._helper).css({
7467                  width: this.element.outerWidth() - 1,
7468                  height: this.element.outerHeight() - 1,
7469                  position: "absolute",
7470                  left: this.elementOffset.left + "px",
7471                  top: this.elementOffset.top + "px",
7472                  zIndex: ++o.zIndex //TODO: Don't modify option
7473              });
7474  
7475              this.helper
7476                  .appendTo("body")
7477                  .disableSelection();
7478  
7479          } else {
7480              this.helper = this.element;
7481          }
7482  
7483      },
7484  
7485      _change: {
7486          e: function(event, dx) {
7487              return { width: this.originalSize.width + dx };
7488          },
7489          w: function(event, dx) {
7490              var cs = this.originalSize, sp = this.originalPosition;
7491              return { left: sp.left + dx, width: cs.width - dx };
7492          },
7493          n: function(event, dx, dy) {
7494              var cs = this.originalSize, sp = this.originalPosition;
7495              return { top: sp.top + dy, height: cs.height - dy };
7496          },
7497          s: function(event, dx, dy) {
7498              return { height: this.originalSize.height + dy };
7499          },
7500          se: function(event, dx, dy) {
7501              return $.extend(this._change.s.apply(this, arguments),
7502                  this._change.e.apply(this, [ event, dx, dy ]));
7503          },
7504          sw: function(event, dx, dy) {
7505              return $.extend(this._change.s.apply(this, arguments),
7506                  this._change.w.apply(this, [ event, dx, dy ]));
7507          },
7508          ne: function(event, dx, dy) {
7509              return $.extend(this._change.n.apply(this, arguments),
7510                  this._change.e.apply(this, [ event, dx, dy ]));
7511          },
7512          nw: function(event, dx, dy) {
7513              return $.extend(this._change.n.apply(this, arguments),
7514                  this._change.w.apply(this, [ event, dx, dy ]));
7515          }
7516      },
7517  
7518      _propagate: function(n, event) {
7519          $.ui.plugin.call(this, n, [ event, this.ui() ]);
7520          (n !== "resize" && this._trigger(n, event, this.ui()));
7521      },
7522  
7523      plugins: {},
7524  
7525      ui: function() {
7526          return {
7527              originalElement: this.originalElement,
7528              element: this.element,
7529              helper: this.helper,
7530              position: this.position,
7531              size: this.size,
7532              originalSize: this.originalSize,
7533              originalPosition: this.originalPosition
7534          };
7535      }
7536  
7537  });
7538  
7539  /*
7540   * Resizable Extensions
7541   */
7542  
7543  $.ui.plugin.add("resizable", "animate", {
7544  
7545      stop: function( event ) {
7546          var that = $(this).resizable( "instance" ),
7547              o = that.options,
7548              pr = that._proportionallyResizeElements,
7549              ista = pr.length && (/textarea/i).test(pr[0].nodeName),
7550              soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
7551              soffsetw = ista ? 0 : that.sizeDiff.width,
7552              style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
7553              left = (parseInt(that.element.css("left"), 10) +
7554                  (that.position.left - that.originalPosition.left)) || null,
7555              top = (parseInt(that.element.css("top"), 10) +
7556                  (that.position.top - that.originalPosition.top)) || null;
7557  
7558          that.element.animate(
7559              $.extend(style, top && left ? { top: top, left: left } : {}), {
7560                  duration: o.animateDuration,
7561                  easing: o.animateEasing,
7562                  step: function() {
7563  
7564                      var data = {
7565                          width: parseInt(that.element.css("width"), 10),
7566                          height: parseInt(that.element.css("height"), 10),
7567                          top: parseInt(that.element.css("top"), 10),
7568                          left: parseInt(that.element.css("left"), 10)
7569                      };
7570  
7571                      if (pr && pr.length) {
7572                          $(pr[0]).css({ width: data.width, height: data.height });
7573                      }
7574  
7575                      // propagating resize, and updating values for each animation step
7576                      that._updateCache(data);
7577                      that._propagate("resize", event);
7578  
7579                  }
7580              }
7581          );
7582      }
7583  
7584  });
7585  
7586  $.ui.plugin.add( "resizable", "containment", {
7587  
7588      start: function() {
7589          var element, p, co, ch, cw, width, height,
7590              that = $( this ).resizable( "instance" ),
7591              o = that.options,
7592              el = that.element,
7593              oc = o.containment,
7594              ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
7595  
7596          if ( !ce ) {
7597              return;
7598          }
7599  
7600          that.containerElement = $( ce );
7601  
7602          if ( /document/.test( oc ) || oc === document ) {
7603              that.containerOffset = {
7604                  left: 0,
7605                  top: 0
7606              };
7607              that.containerPosition = {
7608                  left: 0,
7609                  top: 0
7610              };
7611  
7612              that.parentData = {
7613                  element: $( document ),
7614                  left: 0,
7615                  top: 0,
7616                  width: $( document ).width(),
7617                  height: $( document ).height() || document.body.parentNode.scrollHeight
7618              };
7619          } else {
7620              element = $( ce );
7621              p = [];
7622              $([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
7623                  p[ i ] = that._num( element.css( "padding" + name ) );
7624              });
7625  
7626              that.containerOffset = element.offset();
7627              that.containerPosition = element.position();
7628              that.containerSize = {
7629                  height: ( element.innerHeight() - p[ 3 ] ),
7630                  width: ( element.innerWidth() - p[ 1 ] )
7631              };
7632  
7633              co = that.containerOffset;
7634              ch = that.containerSize.height;
7635              cw = that.containerSize.width;
7636              width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
7637              height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
7638  
7639              that.parentData = {
7640                  element: ce,
7641                  left: co.left,
7642                  top: co.top,
7643                  width: width,
7644                  height: height
7645              };
7646          }
7647      },
7648  
7649      resize: function( event ) {
7650          var woset, hoset, isParent, isOffsetRelative,
7651              that = $( this ).resizable( "instance" ),
7652              o = that.options,
7653              co = that.containerOffset,
7654              cp = that.position,
7655              pRatio = that._aspectRatio || event.shiftKey,
7656              cop = {
7657                  top: 0,
7658                  left: 0
7659              },
7660              ce = that.containerElement,
7661              continueResize = true;
7662  
7663          if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
7664              cop = co;
7665          }
7666  
7667          if ( cp.left < ( that._helper ? co.left : 0 ) ) {
7668              that.size.width = that.size.width +
7669                  ( that._helper ?
7670                      ( that.position.left - co.left ) :
7671                      ( that.position.left - cop.left ) );
7672  
7673              if ( pRatio ) {
7674                  that.size.height = that.size.width / that.aspectRatio;
7675                  continueResize = false;
7676              }
7677              that.position.left = o.helper ? co.left : 0;
7678          }
7679  
7680          if ( cp.top < ( that._helper ? co.top : 0 ) ) {
7681              that.size.height = that.size.height +
7682                  ( that._helper ?
7683                      ( that.position.top - co.top ) :
7684                      that.position.top );
7685  
7686              if ( pRatio ) {
7687                  that.size.width = that.size.height * that.aspectRatio;
7688                  continueResize = false;
7689              }
7690              that.position.top = that._helper ? co.top : 0;
7691          }
7692  
7693          isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
7694          isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
7695  
7696          if ( isParent && isOffsetRelative ) {
7697              that.offset.left = that.parentData.left + that.position.left;
7698              that.offset.top = that.parentData.top + that.position.top;
7699          } else {
7700              that.offset.left = that.element.offset().left;
7701              that.offset.top = that.element.offset().top;
7702          }
7703  
7704          woset = Math.abs( that.sizeDiff.width +
7705              (that._helper ?
7706                  that.offset.left - cop.left :
7707                  (that.offset.left - co.left)) );
7708  
7709          hoset = Math.abs( that.sizeDiff.height +
7710              (that._helper ?
7711                  that.offset.top - cop.top :
7712                  (that.offset.top - co.top)) );
7713  
7714          if ( woset + that.size.width >= that.parentData.width ) {
7715              that.size.width = that.parentData.width - woset;
7716              if ( pRatio ) {
7717                  that.size.height = that.size.width / that.aspectRatio;
7718                  continueResize = false;
7719              }
7720          }
7721  
7722          if ( hoset + that.size.height >= that.parentData.height ) {
7723              that.size.height = that.parentData.height - hoset;
7724              if ( pRatio ) {
7725                  that.size.width = that.size.height * that.aspectRatio;
7726                  continueResize = false;
7727              }
7728          }
7729  
7730          if ( !continueResize ){
7731              that.position.left = that.prevPosition.left;
7732              that.position.top = that.prevPosition.top;
7733              that.size.width = that.prevSize.width;
7734              that.size.height = that.prevSize.height;
7735          }
7736      },
7737  
7738      stop: function() {
7739          var that = $( this ).resizable( "instance" ),
7740              o = that.options,
7741              co = that.containerOffset,
7742              cop = that.containerPosition,
7743              ce = that.containerElement,
7744              helper = $( that.helper ),
7745              ho = helper.offset(),
7746              w = helper.outerWidth() - that.sizeDiff.width,
7747              h = helper.outerHeight() - that.sizeDiff.height;
7748  
7749          if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
7750              $( this ).css({
7751                  left: ho.left - cop.left - co.left,
7752                  width: w,
7753                  height: h
7754              });
7755          }
7756  
7757          if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
7758              $( this ).css({
7759                  left: ho.left - cop.left - co.left,
7760                  width: w,
7761                  height: h
7762              });
7763          }
7764      }
7765  });
7766  
7767  $.ui.plugin.add("resizable", "alsoResize", {
7768  
7769      start: function() {
7770          var that = $(this).resizable( "instance" ),
7771              o = that.options,
7772              _store = function(exp) {
7773                  $(exp).each(function() {
7774                      var el = $(this);
7775                      el.data("ui-resizable-alsoresize", {
7776                          width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
7777                          left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
7778                      });
7779                  });
7780              };
7781  
7782          if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
7783              if (o.alsoResize.length) {
7784                  o.alsoResize = o.alsoResize[0];
7785                  _store(o.alsoResize);
7786              } else {
7787                  $.each(o.alsoResize, function(exp) {
7788                      _store(exp);
7789                  });
7790              }
7791          } else {
7792              _store(o.alsoResize);
7793          }
7794      },
7795  
7796      resize: function(event, ui) {
7797          var that = $(this).resizable( "instance" ),
7798              o = that.options,
7799              os = that.originalSize,
7800              op = that.originalPosition,
7801              delta = {
7802                  height: (that.size.height - os.height) || 0,
7803                  width: (that.size.width - os.width) || 0,
7804                  top: (that.position.top - op.top) || 0,
7805                  left: (that.position.left - op.left) || 0
7806              },
7807  
7808              _alsoResize = function(exp, c) {
7809                  $(exp).each(function() {
7810                      var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
7811                          css = c && c.length ?
7812                              c :
7813                              el.parents(ui.originalElement[0]).length ?
7814                                  [ "width", "height" ] :
7815                                  [ "width", "height", "top", "left" ];
7816  
7817                      $.each(css, function(i, prop) {
7818                          var sum = (start[prop] || 0) + (delta[prop] || 0);
7819                          if (sum && sum >= 0) {
7820                              style[prop] = sum || null;
7821                          }
7822                      });
7823  
7824                      el.css(style);
7825                  });
7826              };
7827  
7828          if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
7829              $.each(o.alsoResize, function(exp, c) {
7830                  _alsoResize(exp, c);
7831              });
7832          } else {
7833              _alsoResize(o.alsoResize);
7834          }
7835      },
7836  
7837      stop: function() {
7838          $(this).removeData("resizable-alsoresize");
7839      }
7840  });
7841  
7842  $.ui.plugin.add("resizable", "ghost", {
7843  
7844      start: function() {
7845  
7846          var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
7847  
7848          that.ghost = that.originalElement.clone();
7849          that.ghost
7850              .css({
7851                  opacity: 0.25,
7852                  display: "block",
7853                  position: "relative",
7854                  height: cs.height,
7855                  width: cs.width,
7856                  margin: 0,
7857                  left: 0,
7858                  top: 0
7859              })
7860              .addClass("ui-resizable-ghost")
7861              .addClass(typeof o.ghost === "string" ? o.ghost : "");
7862  
7863          that.ghost.appendTo(that.helper);
7864  
7865      },
7866  
7867      resize: function() {
7868          var that = $(this).resizable( "instance" );
7869          if (that.ghost) {
7870              that.ghost.css({
7871                  position: "relative",
7872                  height: that.size.height,
7873                  width: that.size.width
7874              });
7875          }
7876      },
7877  
7878      stop: function() {
7879          var that = $(this).resizable( "instance" );
7880          if (that.ghost && that.helper) {
7881              that.helper.get(0).removeChild(that.ghost.get(0));
7882          }
7883      }
7884  
7885  });
7886  
7887  $.ui.plugin.add("resizable", "grid", {
7888  
7889      resize: function() {
7890          var outerDimensions,
7891              that = $(this).resizable( "instance" ),
7892              o = that.options,
7893              cs = that.size,
7894              os = that.originalSize,
7895              op = that.originalPosition,
7896              a = that.axis,
7897              grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
7898              gridX = (grid[0] || 1),
7899              gridY = (grid[1] || 1),
7900              ox = Math.round((cs.width - os.width) / gridX) * gridX,
7901              oy = Math.round((cs.height - os.height) / gridY) * gridY,
7902              newWidth = os.width + ox,
7903              newHeight = os.height + oy,
7904              isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
7905              isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
7906              isMinWidth = o.minWidth && (o.minWidth > newWidth),
7907              isMinHeight = o.minHeight && (o.minHeight > newHeight);
7908  
7909          o.grid = grid;
7910  
7911          if (isMinWidth) {
7912              newWidth += gridX;
7913          }
7914          if (isMinHeight) {
7915              newHeight += gridY;
7916          }
7917          if (isMaxWidth) {
7918              newWidth -= gridX;
7919          }
7920          if (isMaxHeight) {
7921              newHeight -= gridY;
7922          }
7923  
7924          if (/^(se|s|e)$/.test(a)) {
7925              that.size.width = newWidth;
7926              that.size.height = newHeight;
7927          } else if (/^(ne)$/.test(a)) {
7928              that.size.width = newWidth;
7929              that.size.height = newHeight;
7930              that.position.top = op.top - oy;
7931          } else if (/^(sw)$/.test(a)) {
7932              that.size.width = newWidth;
7933              that.size.height = newHeight;
7934              that.position.left = op.left - ox;
7935          } else {
7936              if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
7937                  outerDimensions = that._getPaddingPlusBorderDimensions( this );
7938              }
7939  
7940              if ( newHeight - gridY > 0 ) {
7941                  that.size.height = newHeight;
7942                  that.position.top = op.top - oy;
7943              } else {
7944                  newHeight = gridY - outerDimensions.height;
7945                  that.size.height = newHeight;
7946                  that.position.top = op.top + os.height - newHeight;
7947              }
7948              if ( newWidth - gridX > 0 ) {
7949                  that.size.width = newWidth;
7950                  that.position.left = op.left - ox;
7951              } else {
7952                  newWidth = gridY - outerDimensions.height;
7953                  that.size.width = newWidth;
7954                  that.position.left = op.left + os.width - newWidth;
7955              }
7956          }
7957      }
7958  
7959  });
7960  
7961  var resizable = $.ui.resizable;
7962  
7963  
7964  /*!
7965   * jQuery UI Dialog 1.11.1
7966   * http://jqueryui.com
7967   *
7968   * Copyright 2014 jQuery Foundation and other contributors
7969   * Released under the MIT license.
7970   * http://jquery.org/license
7971   *
7972   * http://api.jqueryui.com/dialog/
7973   */
7974  
7975  
7976  var dialog = $.widget( "ui.dialog", {
7977      version: "1.11.1",
7978      options: {
7979          appendTo: "body",
7980          autoOpen: true,
7981          buttons: [],
7982          closeOnEscape: true,
7983          closeText: "Close",
7984          dialogClass: "",
7985          draggable: true,
7986          hide: null,
7987          height: "auto",
7988          maxHeight: null,
7989          maxWidth: null,
7990          minHeight: 150,
7991          minWidth: 150,
7992          modal: false,
7993          position: {
7994              my: "center",
7995              at: "center",
7996              of: window,
7997              collision: "fit",
7998              // Ensure the titlebar is always visible
7999              using: function( pos ) {
8000                  var topOffset = $( this ).css( pos ).offset().top;
8001                  if ( topOffset < 0 ) {
8002                      $( this ).css( "top", pos.top - topOffset );
8003                  }
8004              }
8005          },
8006          resizable: true,
8007          show: null,
8008          title: null,
8009          width: 300,
8010  
8011          // callbacks
8012          beforeClose: null,
8013          close: null,
8014          drag: null,
8015          dragStart: null,
8016          dragStop: null,
8017          focus: null,
8018          open: null,
8019          resize: null,
8020          resizeStart: null,
8021          resizeStop: null
8022      },
8023  
8024      sizeRelatedOptions: {
8025          buttons: true,
8026          height: true,
8027          maxHeight: true,
8028          maxWidth: true,
8029          minHeight: true,
8030          minWidth: true,
8031          width: true
8032      },
8033  
8034      resizableRelatedOptions: {
8035          maxHeight: true,
8036          maxWidth: true,
8037          minHeight: true,
8038          minWidth: true
8039      },
8040  
8041      _create: function() {
8042          this.originalCss = {
8043              display: this.element[ 0 ].style.display,
8044              width: this.element[ 0 ].style.width,
8045              minHeight: this.element[ 0 ].style.minHeight,
8046              maxHeight: this.element[ 0 ].style.maxHeight,
8047              height: this.element[ 0 ].style.height
8048          };
8049          this.originalPosition = {
8050              parent: this.element.parent(),
8051              index: this.element.parent().children().index( this.element )
8052          };
8053          this.originalTitle = this.element.attr( "title" );
8054          this.options.title = this.options.title || this.originalTitle;
8055  
8056          this._createWrapper();
8057  
8058          this.element
8059              .show()
8060              .removeAttr( "title" )
8061              .addClass( "ui-dialog-content ui-widget-content" )
8062              .appendTo( this.uiDialog );
8063  
8064          this._createTitlebar();
8065          this._createButtonPane();
8066  
8067          if ( this.options.draggable && $.fn.draggable ) {
8068              this._makeDraggable();
8069          }
8070          if ( this.options.resizable && $.fn.resizable ) {
8071              this._makeResizable();
8072          }
8073  
8074          this._isOpen = false;
8075  
8076          this._trackFocus();
8077      },
8078  
8079      _init: function() {
8080          if ( this.options.autoOpen ) {
8081              this.open();
8082          }
8083      },
8084  
8085      _appendTo: function() {
8086          var element = this.options.appendTo;
8087          if ( element && (element.jquery || element.nodeType) ) {
8088              return $( element );
8089          }
8090          return this.document.find( element || "body" ).eq( 0 );
8091      },
8092  
8093      _destroy: function() {
8094          var next,
8095              originalPosition = this.originalPosition;
8096  
8097          this._destroyOverlay();
8098  
8099          this.element
8100              .removeUniqueId()
8101              .removeClass( "ui-dialog-content ui-widget-content" )
8102              .css( this.originalCss )
8103              // Without detaching first, the following becomes really slow
8104              .detach();
8105  
8106          this.uiDialog.stop( true, true ).remove();
8107  
8108          if ( this.originalTitle ) {
8109              this.element.attr( "title", this.originalTitle );
8110          }
8111  
8112          next = originalPosition.parent.children().eq( originalPosition.index );
8113          // Don't try to place the dialog next to itself (#8613)
8114          if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
8115              next.before( this.element );
8116          } else {
8117              originalPosition.parent.append( this.element );
8118          }
8119      },
8120  
8121      widget: function() {
8122          return this.uiDialog;
8123      },
8124  
8125      disable: $.noop,
8126      enable: $.noop,
8127  
8128      close: function( event ) {
8129          var activeElement,
8130              that = this;
8131  
8132          if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8133              return;
8134          }
8135  
8136          this._isOpen = false;
8137          this._focusedElement = null;
8138          this._destroyOverlay();
8139          this._untrackInstance();
8140  
8141          if ( !this.opener.filter( ":focusable" ).focus().length ) {
8142  
8143              // support: IE9
8144              // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
8145              try {
8146                  activeElement = this.document[ 0 ].activeElement;
8147  
8148                  // Support: IE9, IE10
8149                  // If the <body> is blurred, IE will switch windows, see #4520
8150                  if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
8151  
8152                      // Hiding a focused element doesn't trigger blur in WebKit
8153                      // so in case we have nothing to focus on, explicitly blur the active element
8154                      // https://bugs.webkit.org/show_bug.cgi?id=47182
8155                      $( activeElement ).blur();
8156                  }
8157              } catch ( error ) {}
8158          }
8159  
8160          this._hide( this.uiDialog, this.options.hide, function() {
8161              that._trigger( "close", event );
8162          });
8163      },
8164  
8165      isOpen: function() {
8166          return this._isOpen;
8167      },
8168  
8169      moveToTop: function() {
8170          this._moveToTop();
8171      },
8172  
8173      _moveToTop: function( event, silent ) {
8174          var moved = false,
8175              zIndicies = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
8176                  return +$( this ).css( "z-index" );
8177              }).get(),
8178              zIndexMax = Math.max.apply( null, zIndicies );
8179  
8180          if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
8181              this.uiDialog.css( "z-index", zIndexMax + 1 );
8182              moved = true;
8183          }
8184  
8185          if ( moved && !silent ) {
8186              this._trigger( "focus", event );
8187          }
8188          return moved;
8189      },
8190  
8191      open: function() {
8192          var that = this;
8193          if ( this._isOpen ) {
8194              if ( this._moveToTop() ) {
8195                  this._focusTabbable();
8196              }
8197              return;
8198          }
8199  
8200          this._isOpen = true;
8201          this.opener = $( this.document[ 0 ].activeElement );
8202  
8203          this._size();
8204          this._position();
8205          this._createOverlay();
8206          this._moveToTop( null, true );
8207  
8208          // Ensure the overlay is moved to the top with the dialog, but only when
8209          // opening. The overlay shouldn't move after the dialog is open so that
8210          // modeless dialogs opened after the modal dialog stack properly.
8211          if ( this.overlay ) {
8212              this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
8213          }
8214  
8215          this._show( this.uiDialog, this.options.show, function() {
8216              that._focusTabbable();
8217              that._trigger( "focus" );
8218          });
8219  
8220          // Track the dialog immediately upon openening in case a focus event
8221          // somehow occurs outside of the dialog before an element inside the
8222          // dialog is focused (#10152)
8223          this._makeFocusTarget();
8224  
8225          this._trigger( "open" );
8226      },
8227  
8228      _focusTabbable: function() {
8229          // Set focus to the first match:
8230          // 1. An element that was focused previously
8231          // 2. First element inside the dialog matching [autofocus]
8232          // 3. Tabbable element inside the content element
8233          // 4. Tabbable element inside the buttonpane
8234          // 5. The close button
8235          // 6. The dialog itself
8236          var hasFocus = this._focusedElement;
8237          if ( !hasFocus ) {
8238              hasFocus = this.element.find( "[autofocus]" );
8239          }
8240          if ( !hasFocus.length ) {
8241              hasFocus = this.element.find( ":tabbable" );
8242          }
8243          if ( !hasFocus.length ) {
8244              hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
8245          }
8246          if ( !hasFocus.length ) {
8247              hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
8248          }
8249          if ( !hasFocus.length ) {
8250              hasFocus = this.uiDialog;
8251          }
8252          hasFocus.eq( 0 ).focus();
8253      },
8254  
8255      _keepFocus: function( event ) {
8256  		function checkFocus() {
8257              var activeElement = this.document[0].activeElement,
8258                  isActive = this.uiDialog[0] === activeElement ||
8259                      $.contains( this.uiDialog[0], activeElement );
8260              if ( !isActive ) {
8261                  this._focusTabbable();
8262              }
8263          }
8264          event.preventDefault();
8265          checkFocus.call( this );
8266          // support: IE
8267          // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
8268          // so we check again later
8269          this._delay( checkFocus );
8270      },
8271  
8272      _createWrapper: function() {
8273          this.uiDialog = $("<div>")
8274              .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
8275                  this.options.dialogClass )
8276              .hide()
8277              .attr({
8278                  // Setting tabIndex makes the div focusable
8279                  tabIndex: -1,
8280                  role: "dialog"
8281              })
8282              .appendTo( this._appendTo() );
8283  
8284          this._on( this.uiDialog, {
8285              keydown: function( event ) {
8286                  if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
8287                          event.keyCode === $.ui.keyCode.ESCAPE ) {
8288                      event.preventDefault();
8289                      this.close( event );
8290                      return;
8291                  }
8292  
8293                  // prevent tabbing out of dialogs
8294                  if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
8295                      return;
8296                  }
8297                  var tabbables = this.uiDialog.find( ":tabbable" ),
8298                      first = tabbables.filter( ":first" ),
8299                      last = tabbables.filter( ":last" );
8300  
8301                  if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
8302                      this._delay(function() {
8303                          first.focus();
8304                      });
8305                      event.preventDefault();
8306                  } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
8307                      this._delay(function() {
8308                          last.focus();
8309                      });
8310                      event.preventDefault();
8311                  }
8312              },
8313              mousedown: function( event ) {
8314                  if ( this._moveToTop( event ) ) {
8315                      this._focusTabbable();
8316                  }
8317              }
8318          });
8319  
8320          // We assume that any existing aria-describedby attribute means
8321          // that the dialog content is marked up properly
8322          // otherwise we brute force the content as the description
8323          if ( !this.element.find( "[aria-describedby]" ).length ) {
8324              this.uiDialog.attr({
8325                  "aria-describedby": this.element.uniqueId().attr( "id" )
8326              });
8327          }
8328      },
8329  
8330      _createTitlebar: function() {
8331          var uiDialogTitle;
8332  
8333          this.uiDialogTitlebar = $( "<div>" )
8334              .addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
8335              .prependTo( this.uiDialog );
8336          this._on( this.uiDialogTitlebar, {
8337              mousedown: function( event ) {
8338                  // Don't prevent click on close button (#8838)
8339                  // Focusing a dialog that is partially scrolled out of view
8340                  // causes the browser to scroll it into view, preventing the click event
8341                  if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
8342                      // Dialog isn't getting focus when dragging (#8063)
8343                      this.uiDialog.focus();
8344                  }
8345              }
8346          });
8347  
8348          // support: IE
8349          // Use type="button" to prevent enter keypresses in textboxes from closing the
8350          // dialog in IE (#9312)
8351          this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
8352              .button({
8353                  label: this.options.closeText,
8354                  icons: {
8355                      primary: "ui-icon-closethick"
8356                  },
8357                  text: false
8358              })
8359              .addClass( "ui-dialog-titlebar-close" )
8360              .appendTo( this.uiDialogTitlebar );
8361          this._on( this.uiDialogTitlebarClose, {
8362              click: function( event ) {
8363                  event.preventDefault();
8364                  this.close( event );
8365              }
8366          });
8367  
8368          uiDialogTitle = $( "<span>" )
8369              .uniqueId()
8370              .addClass( "ui-dialog-title" )
8371              .prependTo( this.uiDialogTitlebar );
8372          this._title( uiDialogTitle );
8373  
8374          this.uiDialog.attr({
8375              "aria-labelledby": uiDialogTitle.attr( "id" )
8376          });
8377      },
8378  
8379      _title: function( title ) {
8380          if ( !this.options.title ) {
8381              title.html( "&#160;" );
8382          }
8383          title.text( this.options.title );
8384      },
8385  
8386      _createButtonPane: function() {
8387          this.uiDialogButtonPane = $( "<div>" )
8388              .addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
8389  
8390          this.uiButtonSet = $( "<div>" )
8391              .addClass( "ui-dialog-buttonset" )
8392              .appendTo( this.uiDialogButtonPane );
8393  
8394          this._createButtons();
8395      },
8396  
8397      _createButtons: function() {
8398          var that = this,
8399              buttons = this.options.buttons;
8400  
8401          // if we already have a button pane, remove it
8402          this.uiDialogButtonPane.remove();
8403          this.uiButtonSet.empty();
8404  
8405          if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
8406              this.uiDialog.removeClass( "ui-dialog-buttons" );
8407              return;
8408          }
8409  
8410          $.each( buttons, function( name, props ) {
8411              var click, buttonOptions;
8412              props = $.isFunction( props ) ?
8413                  { click: props, text: name } :
8414                  props;
8415              // Default to a non-submitting button
8416              props = $.extend( { type: "button" }, props );
8417              // Change the context for the click callback to be the main element
8418              click = props.click;
8419              props.click = function() {
8420                  click.apply( that.element[ 0 ], arguments );
8421              };
8422              buttonOptions = {
8423                  icons: props.icons,
8424                  text: props.showText
8425              };
8426              delete props.icons;
8427              delete props.showText;
8428              $( "<button></button>", props )
8429                  .button( buttonOptions )
8430                  .appendTo( that.uiButtonSet );
8431          });
8432          this.uiDialog.addClass( "ui-dialog-buttons" );
8433          this.uiDialogButtonPane.appendTo( this.uiDialog );
8434      },
8435  
8436      _makeDraggable: function() {
8437          var that = this,
8438              options = this.options;
8439  
8440  		function filteredUi( ui ) {
8441              return {
8442                  position: ui.position,
8443                  offset: ui.offset
8444              };
8445          }
8446  
8447          this.uiDialog.draggable({
8448              cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
8449              handle: ".ui-dialog-titlebar",
8450              containment: "document",
8451              start: function( event, ui ) {
8452                  $( this ).addClass( "ui-dialog-dragging" );
8453                  that._blockFrames();
8454                  that._trigger( "dragStart", event, filteredUi( ui ) );
8455              },
8456              drag: function( event, ui ) {
8457                  that._trigger( "drag", event, filteredUi( ui ) );
8458              },
8459              stop: function( event, ui ) {
8460                  var left = ui.offset.left - that.document.scrollLeft(),
8461                      top = ui.offset.top - that.document.scrollTop();
8462  
8463                  options.position = {
8464                      my: "left top",
8465                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
8466                          "top" + (top >= 0 ? "+" : "") + top,
8467                      of: that.window
8468                  };
8469                  $( this ).removeClass( "ui-dialog-dragging" );
8470                  that._unblockFrames();
8471                  that._trigger( "dragStop", event, filteredUi( ui ) );
8472              }
8473          });
8474      },
8475  
8476      _makeResizable: function() {
8477          var that = this,
8478              options = this.options,
8479              handles = options.resizable,
8480              // .ui-resizable has position: relative defined in the stylesheet
8481              // but dialogs have to use absolute or fixed positioning
8482              position = this.uiDialog.css("position"),
8483              resizeHandles = typeof handles === "string" ?
8484                  handles    :
8485                  "n,e,s,w,se,sw,ne,nw";
8486  
8487  		function filteredUi( ui ) {
8488              return {
8489                  originalPosition: ui.originalPosition,
8490                  originalSize: ui.originalSize,
8491                  position: ui.position,
8492                  size: ui.size
8493              };
8494          }
8495  
8496          this.uiDialog.resizable({
8497              cancel: ".ui-dialog-content",
8498              containment: "document",
8499              alsoResize: this.element,
8500              maxWidth: options.maxWidth,
8501              maxHeight: options.maxHeight,
8502              minWidth: options.minWidth,
8503              minHeight: this._minHeight(),
8504              handles: resizeHandles,
8505              start: function( event, ui ) {
8506                  $( this ).addClass( "ui-dialog-resizing" );
8507                  that._blockFrames();
8508                  that._trigger( "resizeStart", event, filteredUi( ui ) );
8509              },
8510              resize: function( event, ui ) {
8511                  that._trigger( "resize", event, filteredUi( ui ) );
8512              },
8513              stop: function( event, ui ) {
8514                  var offset = that.uiDialog.offset(),
8515                      left = offset.left - that.document.scrollLeft(),
8516                      top = offset.top - that.document.scrollTop();
8517  
8518                  options.height = that.uiDialog.height();
8519                  options.width = that.uiDialog.width();
8520                  options.position = {
8521                      my: "left top",
8522                      at: "left" + (left >= 0 ? "+" : "") + left + " " +
8523                          "top" + (top >= 0 ? "+" : "") + top,
8524                      of: that.window
8525                  };
8526                  $( this ).removeClass( "ui-dialog-resizing" );
8527                  that._unblockFrames();
8528                  that._trigger( "resizeStop", event, filteredUi( ui ) );
8529              }
8530          })
8531          .css( "position", position );
8532      },
8533  
8534      _trackFocus: function() {
8535          this._on( this.widget(), {
8536              focusin: function( event ) {
8537                  this._makeFocusTarget();
8538                  this._focusedElement = $( event.target );
8539              }
8540          });
8541      },
8542  
8543      _makeFocusTarget: function() {
8544          this._untrackInstance();
8545          this._trackingInstances().unshift( this );
8546      },
8547  
8548      _untrackInstance: function() {
8549          var instances = this._trackingInstances(),
8550              exists = $.inArray( this, instances );
8551          if ( exists !== -1 ) {
8552              instances.splice( exists, 1 );
8553          }
8554      },
8555  
8556      _trackingInstances: function() {
8557          var instances = this.document.data( "ui-dialog-instances" );
8558          if ( !instances ) {
8559              instances = [];
8560              this.document.data( "ui-dialog-instances", instances );
8561          }
8562          return instances;
8563      },
8564  
8565      _minHeight: function() {
8566          var options = this.options;
8567  
8568          return options.height === "auto" ?
8569              options.minHeight :
8570              Math.min( options.minHeight, options.height );
8571      },
8572  
8573      _position: function() {
8574          // Need to show the dialog to get the actual offset in the position plugin
8575          var isVisible = this.uiDialog.is( ":visible" );
8576          if ( !isVisible ) {
8577              this.uiDialog.show();
8578          }
8579          this.uiDialog.position( this.options.position );
8580          if ( !isVisible ) {
8581              this.uiDialog.hide();
8582          }
8583      },
8584  
8585      _setOptions: function( options ) {
8586          var that = this,
8587              resize = false,
8588              resizableOptions = {};
8589  
8590          $.each( options, function( key, value ) {
8591              that._setOption( key, value );
8592  
8593              if ( key in that.sizeRelatedOptions ) {
8594                  resize = true;
8595              }
8596              if ( key in that.resizableRelatedOptions ) {
8597                  resizableOptions[ key ] = value;
8598              }
8599          });
8600  
8601          if ( resize ) {
8602              this._size();
8603              this._position();
8604          }
8605          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8606              this.uiDialog.resizable( "option", resizableOptions );
8607          }
8608      },
8609  
8610      _setOption: function( key, value ) {
8611          var isDraggable, isResizable,
8612              uiDialog = this.uiDialog;
8613  
8614          if ( key === "dialogClass" ) {
8615              uiDialog
8616                  .removeClass( this.options.dialogClass )
8617                  .addClass( value );
8618          }
8619  
8620          if ( key === "disabled" ) {
8621              return;
8622          }
8623  
8624          this._super( key, value );
8625  
8626          if ( key === "appendTo" ) {
8627              this.uiDialog.appendTo( this._appendTo() );
8628          }
8629  
8630          if ( key === "buttons" ) {
8631              this._createButtons();
8632          }
8633  
8634          if ( key === "closeText" ) {
8635              this.uiDialogTitlebarClose.button({
8636                  // Ensure that we always pass a string
8637                  label: "" + value
8638              });
8639          }
8640  
8641          if ( key === "draggable" ) {
8642              isDraggable = uiDialog.is( ":data(ui-draggable)" );
8643              if ( isDraggable && !value ) {
8644                  uiDialog.draggable( "destroy" );
8645              }
8646  
8647              if ( !isDraggable && value ) {
8648                  this._makeDraggable();
8649              }
8650          }
8651  
8652          if ( key === "position" ) {
8653              this._position();
8654          }
8655  
8656          if ( key === "resizable" ) {
8657              // currently resizable, becoming non-resizable
8658              isResizable = uiDialog.is( ":data(ui-resizable)" );
8659              if ( isResizable && !value ) {
8660                  uiDialog.resizable( "destroy" );
8661              }
8662  
8663              // currently resizable, changing handles
8664              if ( isResizable && typeof value === "string" ) {
8665                  uiDialog.resizable( "option", "handles", value );
8666              }
8667  
8668              // currently non-resizable, becoming resizable
8669              if ( !isResizable && value !== false ) {
8670                  this._makeResizable();
8671              }
8672          }
8673  
8674          if ( key === "title" ) {
8675              this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
8676          }
8677      },
8678  
8679      _size: function() {
8680          // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
8681          // divs will both have width and height set, so we need to reset them
8682          var nonContentHeight, minContentHeight, maxContentHeight,
8683              options = this.options;
8684  
8685          // Reset content sizing
8686          this.element.show().css({
8687              width: "auto",
8688              minHeight: 0,
8689              maxHeight: "none",
8690              height: 0
8691          });
8692  
8693          if ( options.minWidth > options.width ) {
8694              options.width = options.minWidth;
8695          }
8696  
8697          // reset wrapper sizing
8698          // determine the height of all the non-content elements
8699          nonContentHeight = this.uiDialog.css({
8700                  height: "auto",
8701                  width: options.width
8702              })
8703              .outerHeight();
8704          minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
8705          maxContentHeight = typeof options.maxHeight === "number" ?
8706              Math.max( 0, options.maxHeight - nonContentHeight ) :
8707              "none";
8708  
8709          if ( options.height === "auto" ) {
8710              this.element.css({
8711                  minHeight: minContentHeight,
8712                  maxHeight: maxContentHeight,
8713                  height: "auto"
8714              });
8715          } else {
8716              this.element.height( Math.max( 0, options.height - nonContentHeight ) );
8717          }
8718  
8719          if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
8720              this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
8721          }
8722      },
8723  
8724      _blockFrames: function() {
8725          this.iframeBlocks = this.document.find( "iframe" ).map(function() {
8726              var iframe = $( this );
8727  
8728              return $( "<div>" )
8729                  .css({
8730                      position: "absolute",
8731                      width: iframe.outerWidth(),
8732                      height: iframe.outerHeight()
8733                  })
8734                  .appendTo( iframe.parent() )
8735                  .offset( iframe.offset() )[0];
8736          });
8737      },
8738  
8739      _unblockFrames: function() {
8740          if ( this.iframeBlocks ) {
8741              this.iframeBlocks.remove();
8742              delete this.iframeBlocks;
8743          }
8744      },
8745  
8746      _allowInteraction: function( event ) {
8747          if ( $( event.target ).closest( ".ui-dialog" ).length ) {
8748              return true;
8749          }
8750  
8751          // TODO: Remove hack when datepicker implements
8752          // the .ui-front logic (#8989)
8753          return !!$( event.target ).closest( ".ui-datepicker" ).length;
8754      },
8755  
8756      _createOverlay: function() {
8757          if ( !this.options.modal ) {
8758              return;
8759          }
8760  
8761          // We use a delay in case the overlay is created from an
8762          // event that we're going to be cancelling (#2804)
8763          var isOpening = true;
8764          this._delay(function() {
8765              isOpening = false;
8766          });
8767  
8768          if ( !this.document.data( "ui-dialog-overlays" ) ) {
8769  
8770              // Prevent use of anchors and inputs
8771              // Using _on() for an event handler shared across many instances is
8772              // safe because the dialogs stack and must be closed in reverse order
8773              this._on( this.document, {
8774                  focusin: function( event ) {
8775                      if ( isOpening ) {
8776                          return;
8777                      }
8778  
8779                      if ( !this._allowInteraction( event ) ) {
8780                          event.preventDefault();
8781                          this._trackingInstances()[ 0 ]._focusTabbable();
8782                      }
8783                  }
8784              });
8785          }
8786  
8787          this.overlay = $( "<div>" )
8788              .addClass( "ui-widget-overlay ui-front" )
8789              .appendTo( this._appendTo() );
8790          this._on( this.overlay, {
8791              mousedown: "_keepFocus"
8792          });
8793          this.document.data( "ui-dialog-overlays",
8794              (this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
8795      },
8796  
8797      _destroyOverlay: function() {
8798          if ( !this.options.modal ) {
8799              return;
8800          }
8801  
8802          if ( this.overlay ) {
8803              var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
8804  
8805              if ( !overlays ) {
8806                  this.document
8807                      .unbind( "focusin" )
8808                      .removeData( "ui-dialog-overlays" );
8809              } else {
8810                  this.document.data( "ui-dialog-overlays", overlays );
8811              }
8812  
8813              this.overlay.remove();
8814              this.overlay = null;
8815          }
8816      }
8817  });
8818  
8819  
8820  /*!
8821   * jQuery UI Droppable 1.11.1
8822   * http://jqueryui.com
8823   *
8824   * Copyright 2014 jQuery Foundation and other contributors
8825   * Released under the MIT license.
8826   * http://jquery.org/license
8827   *
8828   * http://api.jqueryui.com/droppable/
8829   */
8830  
8831  
8832  $.widget( "ui.droppable", {
8833      version: "1.11.1",
8834      widgetEventPrefix: "drop",
8835      options: {
8836          accept: "*",
8837          activeClass: false,
8838          addClasses: true,
8839          greedy: false,
8840          hoverClass: false,
8841          scope: "default",
8842          tolerance: "intersect",
8843  
8844          // callbacks
8845          activate: null,
8846          deactivate: null,
8847          drop: null,
8848          out: null,
8849          over: null
8850      },
8851      _create: function() {
8852  
8853          var proportions,
8854              o = this.options,
8855              accept = o.accept;
8856  
8857          this.isover = false;
8858          this.isout = true;
8859  
8860          this.accept = $.isFunction( accept ) ? accept : function( d ) {
8861              return d.is( accept );
8862          };
8863  
8864          this.proportions = function( /* valueToWrite */ ) {
8865              if ( arguments.length ) {
8866                  // Store the droppable's proportions
8867                  proportions = arguments[ 0 ];
8868              } else {
8869                  // Retrieve or derive the droppable's proportions
8870                  return proportions ?
8871                      proportions :
8872                      proportions = {
8873                          width: this.element[ 0 ].offsetWidth,
8874                          height: this.element[ 0 ].offsetHeight
8875                      };
8876              }
8877          };
8878  
8879          this._addToManager( o.scope );
8880  
8881          o.addClasses && this.element.addClass( "ui-droppable" );
8882  
8883      },
8884  
8885      _addToManager: function( scope ) {
8886          // Add the reference and positions to the manager
8887          $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
8888          $.ui.ddmanager.droppables[ scope ].push( this );
8889      },
8890  
8891      _splice: function( drop ) {
8892          var i = 0;
8893          for ( ; i < drop.length; i++ ) {
8894              if ( drop[ i ] === this ) {
8895                  drop.splice( i, 1 );
8896              }
8897          }
8898      },
8899  
8900      _destroy: function() {
8901          var drop = $.ui.ddmanager.droppables[ this.options.scope ];
8902  
8903          this._splice( drop );
8904  
8905          this.element.removeClass( "ui-droppable ui-droppable-disabled" );
8906      },
8907  
8908      _setOption: function( key, value ) {
8909  
8910          if ( key === "accept" ) {
8911              this.accept = $.isFunction( value ) ? value : function( d ) {
8912                  return d.is( value );
8913              };
8914          } else if ( key === "scope" ) {
8915              var drop = $.ui.ddmanager.droppables[ this.options.scope ];
8916  
8917              this._splice( drop );
8918              this._addToManager( value );
8919          }
8920  
8921          this._super( key, value );
8922      },
8923  
8924      _activate: function( event ) {
8925          var draggable = $.ui.ddmanager.current;
8926          if ( this.options.activeClass ) {
8927              this.element.addClass( this.options.activeClass );
8928          }
8929          if ( draggable ){
8930              this._trigger( "activate", event, this.ui( draggable ) );
8931          }
8932      },
8933  
8934      _deactivate: function( event ) {
8935          var draggable = $.ui.ddmanager.current;
8936          if ( this.options.activeClass ) {
8937              this.element.removeClass( this.options.activeClass );
8938          }
8939          if ( draggable ){
8940              this._trigger( "deactivate", event, this.ui( draggable ) );
8941          }
8942      },
8943  
8944      _over: function( event ) {
8945  
8946          var draggable = $.ui.ddmanager.current;
8947  
8948          // Bail if draggable and droppable are same element
8949          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
8950              return;
8951          }
8952  
8953          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
8954              if ( this.options.hoverClass ) {
8955                  this.element.addClass( this.options.hoverClass );
8956              }
8957              this._trigger( "over", event, this.ui( draggable ) );
8958          }
8959  
8960      },
8961  
8962      _out: function( event ) {
8963  
8964          var draggable = $.ui.ddmanager.current;
8965  
8966          // Bail if draggable and droppable are same element
8967          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
8968              return;
8969          }
8970  
8971          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
8972              if ( this.options.hoverClass ) {
8973                  this.element.removeClass( this.options.hoverClass );
8974              }
8975              this._trigger( "out", event, this.ui( draggable ) );
8976          }
8977  
8978      },
8979  
8980      _drop: function( event, custom ) {
8981  
8982          var draggable = custom || $.ui.ddmanager.current,
8983              childrenIntersection = false;
8984  
8985          // Bail if draggable and droppable are same element
8986          if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
8987              return false;
8988          }
8989  
8990          this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
8991              var inst = $( this ).droppable( "instance" );
8992              if (
8993                  inst.options.greedy &&
8994                  !inst.options.disabled &&
8995                  inst.options.scope === draggable.options.scope &&
8996                  inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
8997                  $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
8998              ) { childrenIntersection = true; return false; }
8999          });
9000          if ( childrenIntersection ) {
9001              return false;
9002          }
9003  
9004          if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9005              if ( this.options.activeClass ) {
9006                  this.element.removeClass( this.options.activeClass );
9007              }
9008              if ( this.options.hoverClass ) {
9009                  this.element.removeClass( this.options.hoverClass );
9010              }
9011              this._trigger( "drop", event, this.ui( draggable ) );
9012              return this.element;
9013          }
9014  
9015          return false;
9016  
9017      },
9018  
9019      ui: function( c ) {
9020          return {
9021              draggable: ( c.currentItem || c.element ),
9022              helper: c.helper,
9023              position: c.position,
9024              offset: c.positionAbs
9025          };
9026      }
9027  
9028  });
9029  
9030  $.ui.intersect = (function() {
9031  	function isOverAxis( x, reference, size ) {
9032          return ( x >= reference ) && ( x < ( reference + size ) );
9033      }
9034  
9035      return function( draggable, droppable, toleranceMode, event ) {
9036  
9037          if ( !droppable.offset ) {
9038              return false;
9039          }
9040  
9041          var x1 = ( draggable.positionAbs || draggable.position.absolute ).left,
9042              y1 = ( draggable.positionAbs || draggable.position.absolute ).top,
9043              x2 = x1 + draggable.helperProportions.width,
9044              y2 = y1 + draggable.helperProportions.height,
9045              l = droppable.offset.left,
9046              t = droppable.offset.top,
9047              r = l + droppable.proportions().width,
9048              b = t + droppable.proportions().height;
9049  
9050          switch ( toleranceMode ) {
9051          case "fit":
9052              return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
9053          case "intersect":
9054              return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
9055                  x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
9056                  t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
9057                  y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
9058          case "pointer":
9059              return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
9060          case "touch":
9061              return (
9062                  ( y1 >= t && y1 <= b ) || // Top edge touching
9063                  ( y2 >= t && y2 <= b ) || // Bottom edge touching
9064                  ( y1 < t && y2 > b ) // Surrounded vertically
9065              ) && (
9066                  ( x1 >= l && x1 <= r ) || // Left edge touching
9067                  ( x2 >= l && x2 <= r ) || // Right edge touching
9068                  ( x1 < l && x2 > r ) // Surrounded horizontally
9069              );
9070          default:
9071              return false;
9072          }
9073      };
9074  })();
9075  
9076  /*
9077      This manager tracks offsets of draggables and droppables
9078  */
9079  $.ui.ddmanager = {
9080      current: null,
9081      droppables: { "default": [] },
9082      prepareOffsets: function( t, event ) {
9083  
9084          var i, j,
9085              m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
9086              type = event ? event.type : null, // workaround for #2317
9087              list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
9088  
9089          droppablesLoop: for ( i = 0; i < m.length; i++ ) {
9090  
9091              // No disabled and non-accepted
9092              if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
9093                  continue;
9094              }
9095  
9096              // Filter out elements in the current dragged item
9097              for ( j = 0; j < list.length; j++ ) {
9098                  if ( list[ j ] === m[ i ].element[ 0 ] ) {
9099                      m[ i ].proportions().height = 0;
9100                      continue droppablesLoop;
9101                  }
9102              }
9103  
9104              m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
9105              if ( !m[ i ].visible ) {
9106                  continue;
9107              }
9108  
9109              // Activate the droppable if used directly from draggables
9110              if ( type === "mousedown" ) {
9111                  m[ i ]._activate.call( m[ i ], event );
9112              }
9113  
9114              m[ i ].offset = m[ i ].element.offset();
9115              m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
9116  
9117          }
9118  
9119      },
9120      drop: function( draggable, event ) {
9121  
9122          var dropped = false;
9123          // Create a copy of the droppables in case the list changes during the drop (#9116)
9124          $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
9125  
9126              if ( !this.options ) {
9127                  return;
9128              }
9129              if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
9130                  dropped = this._drop.call( this, event ) || dropped;
9131              }
9132  
9133              if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
9134                  this.isout = true;
9135                  this.isover = false;
9136                  this._deactivate.call( this, event );
9137              }
9138  
9139          });
9140          return dropped;
9141  
9142      },
9143      dragStart: function( draggable, event ) {
9144          // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
9145          draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
9146              if ( !draggable.options.refreshPositions ) {
9147                  $.ui.ddmanager.prepareOffsets( draggable, event );
9148              }
9149          });
9150      },
9151      drag: function( draggable, event ) {
9152  
9153          // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
9154          if ( draggable.options.refreshPositions ) {
9155              $.ui.ddmanager.prepareOffsets( draggable, event );
9156          }
9157  
9158          // Run through all droppables and check their positions based on specific tolerance options
9159          $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
9160  
9161              if ( this.options.disabled || this.greedyChild || !this.visible ) {
9162                  return;
9163              }
9164  
9165              var parentInstance, scope, parent,
9166                  intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
9167                  c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
9168              if ( !c ) {
9169                  return;
9170              }
9171  
9172              if ( this.options.greedy ) {
9173                  // find droppable parents with same scope
9174                  scope = this.options.scope;
9175                  parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
9176                      return $( this ).droppable( "instance" ).options.scope === scope;
9177                  });
9178  
9179                  if ( parent.length ) {
9180                      parentInstance = $( parent[ 0 ] ).droppable( "instance" );
9181                      parentInstance.greedyChild = ( c === "isover" );
9182                  }
9183              }
9184  
9185              // we just moved into a greedy child
9186              if ( parentInstance && c === "isover" ) {
9187                  parentInstance.isover = false;
9188                  parentInstance.isout = true;
9189                  parentInstance._out.call( parentInstance, event );
9190              }
9191  
9192              this[ c ] = true;
9193              this[c === "isout" ? "isover" : "isout"] = false;
9194              this[c === "isover" ? "_over" : "_out"].call( this, event );
9195  
9196              // we just moved out of a greedy child
9197              if ( parentInstance && c === "isout" ) {
9198                  parentInstance.isout = false;
9199                  parentInstance.isover = true;
9200                  parentInstance._over.call( parentInstance, event );
9201              }
9202          });
9203  
9204      },
9205      dragStop: function( draggable, event ) {
9206          draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
9207          // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
9208          if ( !draggable.options.refreshPositions ) {
9209              $.ui.ddmanager.prepareOffsets( draggable, event );
9210          }
9211      }
9212  };
9213  
9214  var droppable = $.ui.droppable;
9215  
9216  
9217  /*!
9218   * jQuery UI Effects 1.11.1
9219   * http://jqueryui.com
9220   *
9221   * Copyright 2014 jQuery Foundation and other contributors
9222   * Released under the MIT license.
9223   * http://jquery.org/license
9224   *
9225   * http://api.jqueryui.com/category/effects-core/
9226   */
9227  
9228  
9229  var dataSpace = "ui-effects-",
9230  
9231      // Create a local jQuery because jQuery Color relies on it and the
9232      // global may not exist with AMD and a custom build (#10199)
9233      jQuery = $;
9234  
9235  $.effects = {
9236      effect: {}
9237  };
9238  
9239  /*!
9240   * jQuery Color Animations v2.1.2
9241   * https://github.com/jquery/jquery-color
9242   *
9243   * Copyright 2014 jQuery Foundation and other contributors
9244   * Released under the MIT license.
9245   * http://jquery.org/license
9246   *
9247   * Date: Wed Jan 16 08:47:09 2013 -0600
9248   */
9249  (function( jQuery, undefined ) {
9250  
9251      var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
9252  
9253      // plusequals test for += 100 -= 100
9254      rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
9255      // a set of RE's that can match strings and generate color tuples.
9256      stringParsers = [ {
9257              re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9258              parse: function( execResult ) {
9259                  return [
9260                      execResult[ 1 ],
9261                      execResult[ 2 ],
9262                      execResult[ 3 ],
9263                      execResult[ 4 ]
9264                  ];
9265              }
9266          }, {
9267              re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9268              parse: function( execResult ) {
9269                  return [
9270                      execResult[ 1 ] * 2.55,
9271                      execResult[ 2 ] * 2.55,
9272                      execResult[ 3 ] * 2.55,
9273                      execResult[ 4 ]
9274                  ];
9275              }
9276          }, {
9277              // this regex ignores A-F because it's compared against an already lowercased string
9278              re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
9279              parse: function( execResult ) {
9280                  return [
9281                      parseInt( execResult[ 1 ], 16 ),
9282                      parseInt( execResult[ 2 ], 16 ),
9283                      parseInt( execResult[ 3 ], 16 )
9284                  ];
9285              }
9286          }, {
9287              // this regex ignores A-F because it's compared against an already lowercased string
9288              re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
9289              parse: function( execResult ) {
9290                  return [
9291                      parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
9292                      parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
9293                      parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
9294                  ];
9295              }
9296          }, {
9297              re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
9298              space: "hsla",
9299              parse: function( execResult ) {
9300                  return [
9301                      execResult[ 1 ],
9302                      execResult[ 2 ] / 100,
9303                      execResult[ 3 ] / 100,
9304                      execResult[ 4 ]
9305                  ];
9306              }
9307          } ],
9308  
9309      // jQuery.Color( )
9310      color = jQuery.Color = function( color, green, blue, alpha ) {
9311          return new jQuery.Color.fn.parse( color, green, blue, alpha );
9312      },
9313      spaces = {
9314          rgba: {
9315              props: {
9316                  red: {
9317                      idx: 0,
9318                      type: "byte"
9319                  },
9320                  green: {
9321                      idx: 1,
9322                      type: "byte"
9323                  },
9324                  blue: {
9325                      idx: 2,
9326                      type: "byte"
9327                  }
9328              }
9329          },
9330  
9331          hsla: {
9332              props: {
9333                  hue: {
9334                      idx: 0,
9335                      type: "degrees"
9336                  },
9337                  saturation: {
9338                      idx: 1,
9339                      type: "percent"
9340                  },
9341                  lightness: {
9342                      idx: 2,
9343                      type: "percent"
9344                  }
9345              }
9346          }
9347      },
9348      propTypes = {
9349          "byte": {
9350              floor: true,
9351              max: 255
9352          },
9353          "percent": {
9354              max: 1
9355          },
9356          "degrees": {
9357              mod: 360,
9358              floor: true
9359          }
9360      },
9361      support = color.support = {},
9362  
9363      // element for support tests
9364      supportElem = jQuery( "<p>" )[ 0 ],
9365  
9366      // colors = jQuery.Color.names
9367      colors,
9368  
9369      // local aliases of functions called often
9370      each = jQuery.each;
9371  
9372  // determine rgba support immediately
9373  supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
9374  support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
9375  
9376  // define cache name and alpha properties
9377  // for rgba and hsla spaces
9378  each( spaces, function( spaceName, space ) {
9379      space.cache = "_" + spaceName;
9380      space.props.alpha = {
9381          idx: 3,
9382          type: "percent",
9383          def: 1
9384      };
9385  });
9386  
9387  function clamp( value, prop, allowEmpty ) {
9388      var type = propTypes[ prop.type ] || {};
9389  
9390      if ( value == null ) {
9391          return (allowEmpty || !prop.def) ? null : prop.def;
9392      }
9393  
9394      // ~~ is an short way of doing floor for positive numbers
9395      value = type.floor ? ~~value : parseFloat( value );
9396  
9397      // IE will pass in empty strings as value for alpha,
9398      // which will hit this case
9399      if ( isNaN( value ) ) {
9400          return prop.def;
9401      }
9402  
9403      if ( type.mod ) {
9404          // we add mod before modding to make sure that negatives values
9405          // get converted properly: -10 -> 350
9406          return (value + type.mod) % type.mod;
9407      }
9408  
9409      // for now all property types without mod have min and max
9410      return 0 > value ? 0 : type.max < value ? type.max : value;
9411  }
9412  
9413  function stringParse( string ) {
9414      var inst = color(),
9415          rgba = inst._rgba = [];
9416  
9417      string = string.toLowerCase();
9418  
9419      each( stringParsers, function( i, parser ) {
9420          var parsed,
9421              match = parser.re.exec( string ),
9422              values = match && parser.parse( match ),
9423              spaceName = parser.space || "rgba";
9424  
9425          if ( values ) {
9426              parsed = inst[ spaceName ]( values );
9427  
9428              // if this was an rgba parse the assignment might happen twice
9429              // oh well....
9430              inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
9431              rgba = inst._rgba = parsed._rgba;
9432  
9433              // exit each( stringParsers ) here because we matched
9434              return false;
9435          }
9436      });
9437  
9438      // Found a stringParser that handled it
9439      if ( rgba.length ) {
9440  
9441          // if this came from a parsed string, force "transparent" when alpha is 0
9442          // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
9443          if ( rgba.join() === "0,0,0,0" ) {
9444              jQuery.extend( rgba, colors.transparent );
9445          }
9446          return inst;
9447      }
9448  
9449      // named colors
9450      return colors[ string ];
9451  }
9452  
9453  color.fn = jQuery.extend( color.prototype, {
9454      parse: function( red, green, blue, alpha ) {
9455          if ( red === undefined ) {
9456              this._rgba = [ null, null, null, null ];
9457              return this;
9458          }
9459          if ( red.jquery || red.nodeType ) {
9460              red = jQuery( red ).css( green );
9461              green = undefined;
9462          }
9463  
9464          var inst = this,
9465              type = jQuery.type( red ),
9466              rgba = this._rgba = [];
9467  
9468          // more than 1 argument specified - assume ( red, green, blue, alpha )
9469          if ( green !== undefined ) {
9470              red = [ red, green, blue, alpha ];
9471              type = "array";
9472          }
9473  
9474          if ( type === "string" ) {
9475              return this.parse( stringParse( red ) || colors._default );
9476          }
9477  
9478          if ( type === "array" ) {
9479              each( spaces.rgba.props, function( key, prop ) {
9480                  rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
9481              });
9482              return this;
9483          }
9484  
9485          if ( type === "object" ) {
9486              if ( red instanceof color ) {
9487                  each( spaces, function( spaceName, space ) {
9488                      if ( red[ space.cache ] ) {
9489                          inst[ space.cache ] = red[ space.cache ].slice();
9490                      }
9491                  });
9492              } else {
9493                  each( spaces, function( spaceName, space ) {
9494                      var cache = space.cache;
9495                      each( space.props, function( key, prop ) {
9496  
9497                          // if the cache doesn't exist, and we know how to convert
9498                          if ( !inst[ cache ] && space.to ) {
9499  
9500                              // if the value was null, we don't need to copy it
9501                              // if the key was alpha, we don't need to copy it either
9502                              if ( key === "alpha" || red[ key ] == null ) {
9503                                  return;
9504                              }
9505                              inst[ cache ] = space.to( inst._rgba );
9506                          }
9507  
9508                          // this is the only case where we allow nulls for ALL properties.
9509                          // call clamp with alwaysAllowEmpty
9510                          inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
9511                      });
9512  
9513                      // everything defined but alpha?
9514                      if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
9515                          // use the default of 1
9516                          inst[ cache ][ 3 ] = 1;
9517                          if ( space.from ) {
9518                              inst._rgba = space.from( inst[ cache ] );
9519                          }
9520                      }
9521                  });
9522              }
9523              return this;
9524          }
9525      },
9526      is: function( compare ) {
9527          var is = color( compare ),
9528              same = true,
9529              inst = this;
9530  
9531          each( spaces, function( _, space ) {
9532              var localCache,
9533                  isCache = is[ space.cache ];
9534              if (isCache) {
9535                  localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
9536                  each( space.props, function( _, prop ) {
9537                      if ( isCache[ prop.idx ] != null ) {
9538                          same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
9539                          return same;
9540                      }
9541                  });
9542              }
9543              return same;
9544          });
9545          return same;
9546      },
9547      _space: function() {
9548          var used = [],
9549              inst = this;
9550          each( spaces, function( spaceName, space ) {
9551              if ( inst[ space.cache ] ) {
9552                  used.push( spaceName );
9553              }
9554          });
9555          return used.pop();
9556      },
9557      transition: function( other, distance ) {
9558          var end = color( other ),
9559              spaceName = end._space(),
9560              space = spaces[ spaceName ],
9561              startColor = this.alpha() === 0 ? color( "transparent" ) : this,
9562              start = startColor[ space.cache ] || space.to( startColor._rgba ),
9563              result = start.slice();
9564  
9565          end = end[ space.cache ];
9566          each( space.props, function( key, prop ) {
9567              var index = prop.idx,
9568                  startValue = start[ index ],
9569                  endValue = end[ index ],
9570                  type = propTypes[ prop.type ] || {};
9571  
9572              // if null, don't override start value
9573              if ( endValue === null ) {
9574                  return;
9575              }
9576              // if null - use end
9577              if ( startValue === null ) {
9578                  result[ index ] = endValue;
9579              } else {
9580                  if ( type.mod ) {
9581                      if ( endValue - startValue > type.mod / 2 ) {
9582                          startValue += type.mod;
9583                      } else if ( startValue - endValue > type.mod / 2 ) {
9584                          startValue -= type.mod;
9585                      }
9586                  }
9587                  result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
9588              }
9589          });
9590          return this[ spaceName ]( result );
9591      },
9592      blend: function( opaque ) {
9593          // if we are already opaque - return ourself
9594          if ( this._rgba[ 3 ] === 1 ) {
9595              return this;
9596          }
9597  
9598          var rgb = this._rgba.slice(),
9599              a = rgb.pop(),
9600              blend = color( opaque )._rgba;
9601  
9602          return color( jQuery.map( rgb, function( v, i ) {
9603              return ( 1 - a ) * blend[ i ] + a * v;
9604          }));
9605      },
9606      toRgbaString: function() {
9607          var prefix = "rgba(",
9608              rgba = jQuery.map( this._rgba, function( v, i ) {
9609                  return v == null ? ( i > 2 ? 1 : 0 ) : v;
9610              });
9611  
9612          if ( rgba[ 3 ] === 1 ) {
9613              rgba.pop();
9614              prefix = "rgb(";
9615          }
9616  
9617          return prefix + rgba.join() + ")";
9618      },
9619      toHslaString: function() {
9620          var prefix = "hsla(",
9621              hsla = jQuery.map( this.hsla(), function( v, i ) {
9622                  if ( v == null ) {
9623                      v = i > 2 ? 1 : 0;
9624                  }
9625  
9626                  // catch 1 and 2
9627                  if ( i && i < 3 ) {
9628                      v = Math.round( v * 100 ) + "%";
9629                  }
9630                  return v;
9631              });
9632  
9633          if ( hsla[ 3 ] === 1 ) {
9634              hsla.pop();
9635              prefix = "hsl(";
9636          }
9637          return prefix + hsla.join() + ")";
9638      },
9639      toHexString: function( includeAlpha ) {
9640          var rgba = this._rgba.slice(),
9641              alpha = rgba.pop();
9642  
9643          if ( includeAlpha ) {
9644              rgba.push( ~~( alpha * 255 ) );
9645          }
9646  
9647          return "#" + jQuery.map( rgba, function( v ) {
9648  
9649              // default to 0 when nulls exist
9650              v = ( v || 0 ).toString( 16 );
9651              return v.length === 1 ? "0" + v : v;
9652          }).join("");
9653      },
9654      toString: function() {
9655          return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
9656      }
9657  });
9658  color.fn.parse.prototype = color.fn;
9659  
9660  // hsla conversions adapted from:
9661  // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
9662  
9663  function hue2rgb( p, q, h ) {
9664      h = ( h + 1 ) % 1;
9665      if ( h * 6 < 1 ) {
9666          return p + ( q - p ) * h * 6;
9667      }
9668      if ( h * 2 < 1) {
9669          return q;
9670      }
9671      if ( h * 3 < 2 ) {
9672          return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
9673      }
9674      return p;
9675  }
9676  
9677  spaces.hsla.to = function( rgba ) {
9678      if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
9679          return [ null, null, null, rgba[ 3 ] ];
9680      }
9681      var r = rgba[ 0 ] / 255,
9682          g = rgba[ 1 ] / 255,
9683          b = rgba[ 2 ] / 255,
9684          a = rgba[ 3 ],
9685          max = Math.max( r, g, b ),
9686          min = Math.min( r, g, b ),
9687          diff = max - min,
9688          add = max + min,
9689          l = add * 0.5,
9690          h, s;
9691  
9692      if ( min === max ) {
9693          h = 0;
9694      } else if ( r === max ) {
9695          h = ( 60 * ( g - b ) / diff ) + 360;
9696      } else if ( g === max ) {
9697          h = ( 60 * ( b - r ) / diff ) + 120;
9698      } else {
9699          h = ( 60 * ( r - g ) / diff ) + 240;
9700      }
9701  
9702      // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
9703      // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
9704      if ( diff === 0 ) {
9705          s = 0;
9706      } else if ( l <= 0.5 ) {
9707          s = diff / add;
9708      } else {
9709          s = diff / ( 2 - add );
9710      }
9711      return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
9712  };
9713  
9714  spaces.hsla.from = function( hsla ) {
9715      if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
9716          return [ null, null, null, hsla[ 3 ] ];
9717      }
9718      var h = hsla[ 0 ] / 360,
9719          s = hsla[ 1 ],
9720          l = hsla[ 2 ],
9721          a = hsla[ 3 ],
9722          q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
9723          p = 2 * l - q;
9724  
9725      return [
9726          Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
9727          Math.round( hue2rgb( p, q, h ) * 255 ),
9728          Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
9729          a
9730      ];
9731  };
9732  
9733  each( spaces, function( spaceName, space ) {
9734      var props = space.props,
9735          cache = space.cache,
9736          to = space.to,
9737          from = space.from;
9738  
9739      // makes rgba() and hsla()
9740      color.fn[ spaceName ] = function( value ) {
9741  
9742          // generate a cache for this space if it doesn't exist
9743          if ( to && !this[ cache ] ) {
9744              this[ cache ] = to( this._rgba );
9745          }
9746          if ( value === undefined ) {
9747              return this[ cache ].slice();
9748          }
9749  
9750          var ret,
9751              type = jQuery.type( value ),
9752              arr = ( type === "array" || type === "object" ) ? value : arguments,
9753              local = this[ cache ].slice();
9754  
9755          each( props, function( key, prop ) {
9756              var val = arr[ type === "object" ? key : prop.idx ];
9757              if ( val == null ) {
9758                  val = local[ prop.idx ];
9759              }
9760              local[ prop.idx ] = clamp( val, prop );
9761          });
9762  
9763          if ( from ) {
9764              ret = color( from( local ) );
9765              ret[ cache ] = local;
9766              return ret;
9767          } else {
9768              return color( local );
9769          }
9770      };
9771  
9772      // makes red() green() blue() alpha() hue() saturation() lightness()
9773      each( props, function( key, prop ) {
9774          // alpha is included in more than one space
9775          if ( color.fn[ key ] ) {
9776              return;
9777          }
9778          color.fn[ key ] = function( value ) {
9779              var vtype = jQuery.type( value ),
9780                  fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
9781                  local = this[ fn ](),
9782                  cur = local[ prop.idx ],
9783                  match;
9784  
9785              if ( vtype === "undefined" ) {
9786                  return cur;
9787              }
9788  
9789              if ( vtype === "function" ) {
9790                  value = value.call( this, cur );
9791                  vtype = jQuery.type( value );
9792              }
9793              if ( value == null && prop.empty ) {
9794                  return this;
9795              }
9796              if ( vtype === "string" ) {
9797                  match = rplusequals.exec( value );
9798                  if ( match ) {
9799                      value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
9800                  }
9801              }
9802              local[ prop.idx ] = value;
9803              return this[ fn ]( local );
9804          };
9805      });
9806  });
9807  
9808  // add cssHook and .fx.step function for each named hook.
9809  // accept a space separated string of properties
9810  color.hook = function( hook ) {
9811      var hooks = hook.split( " " );
9812      each( hooks, function( i, hook ) {
9813          jQuery.cssHooks[ hook ] = {
9814              set: function( elem, value ) {
9815                  var parsed, curElem,
9816                      backgroundColor = "";
9817  
9818                  if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
9819                      value = color( parsed || value );
9820                      if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
9821                          curElem = hook === "backgroundColor" ? elem.parentNode : elem;
9822                          while (
9823                              (backgroundColor === "" || backgroundColor === "transparent") &&
9824                              curElem && curElem.style
9825                          ) {
9826                              try {
9827                                  backgroundColor = jQuery.css( curElem, "backgroundColor" );
9828                                  curElem = curElem.parentNode;
9829                              } catch ( e ) {
9830                              }
9831                          }
9832  
9833                          value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
9834                              backgroundColor :
9835                              "_default" );
9836                      }
9837  
9838                      value = value.toRgbaString();
9839                  }
9840                  try {
9841                      elem.style[ hook ] = value;
9842                  } catch( e ) {
9843                      // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
9844                  }
9845              }
9846          };
9847          jQuery.fx.step[ hook ] = function( fx ) {
9848              if ( !fx.colorInit ) {
9849                  fx.start = color( fx.elem, hook );
9850                  fx.end = color( fx.end );
9851                  fx.colorInit = true;
9852              }
9853              jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
9854          };
9855      });
9856  
9857  };
9858  
9859  color.hook( stepHooks );
9860  
9861  jQuery.cssHooks.borderColor = {
9862      expand: function( value ) {
9863          var expanded = {};
9864  
9865          each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
9866              expanded[ "border" + part + "Color" ] = value;
9867          });
9868          return expanded;
9869      }
9870  };
9871  
9872  // Basic color names only.
9873  // Usage of any of the other color names requires adding yourself or including
9874  // jquery.color.svg-names.js.
9875  colors = jQuery.Color.names = {
9876      // 4.1. Basic color keywords
9877      aqua: "#00ffff",
9878      black: "#000000",
9879      blue: "#0000ff",
9880      fuchsia: "#ff00ff",
9881      gray: "#808080",
9882      green: "#008000",
9883      lime: "#00ff00",
9884      maroon: "#800000",
9885      navy: "#000080",
9886      olive: "#808000",
9887      purple: "#800080",
9888      red: "#ff0000",
9889      silver: "#c0c0c0",
9890      teal: "#008080",
9891      white: "#ffffff",
9892      yellow: "#ffff00",
9893  
9894      // 4.2.3. "transparent" color keyword
9895      transparent: [ null, null, null, 0 ],
9896  
9897      _default: "#ffffff"
9898  };
9899  
9900  })( jQuery );
9901  
9902  /******************************************************************************/
9903  /****************************** CLASS ANIMATIONS ******************************/
9904  /******************************************************************************/
9905  (function() {
9906  
9907  var classAnimationActions = [ "add", "remove", "toggle" ],
9908      shorthandStyles = {
9909          border: 1,
9910          borderBottom: 1,
9911          borderColor: 1,
9912          borderLeft: 1,
9913          borderRight: 1,
9914          borderTop: 1,
9915          borderWidth: 1,
9916          margin: 1,
9917          padding: 1
9918      };
9919  
9920  $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
9921      $.fx.step[ prop ] = function( fx ) {
9922          if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
9923              jQuery.style( fx.elem, prop, fx.end );
9924              fx.setAttr = true;
9925          }
9926      };
9927  });
9928  
9929  function getElementStyles( elem ) {
9930      var key, len,
9931          style = elem.ownerDocument.defaultView ?
9932              elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
9933              elem.currentStyle,
9934          styles = {};
9935  
9936      if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
9937          len = style.length;
9938          while ( len-- ) {
9939              key = style[ len ];
9940              if ( typeof style[ key ] === "string" ) {
9941                  styles[ $.camelCase( key ) ] = style[ key ];
9942              }
9943          }
9944      // support: Opera, IE <9
9945      } else {
9946          for ( key in style ) {
9947              if ( typeof style[ key ] === "string" ) {
9948                  styles[ key ] = style[ key ];
9949              }
9950          }
9951      }
9952  
9953      return styles;
9954  }
9955  
9956  function styleDifference( oldStyle, newStyle ) {
9957      var diff = {},
9958          name, value;
9959  
9960      for ( name in newStyle ) {
9961          value = newStyle[ name ];
9962          if ( oldStyle[ name ] !== value ) {
9963              if ( !shorthandStyles[ name ] ) {
9964                  if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
9965                      diff[ name ] = value;
9966                  }
9967              }
9968          }
9969      }
9970  
9971      return diff;
9972  }
9973  
9974  // support: jQuery <1.8
9975  if ( !$.fn.addBack ) {
9976      $.fn.addBack = function( selector ) {
9977          return this.add( selector == null ?
9978              this.prevObject : this.prevObject.filter( selector )
9979          );
9980      };
9981  }
9982  
9983  $.effects.animateClass = function( value, duration, easing, callback ) {
9984      var o = $.speed( duration, easing, callback );
9985  
9986      return this.queue( function() {
9987          var animated = $( this ),
9988              baseClass = animated.attr( "class" ) || "",
9989              applyClassChange,
9990              allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
9991  
9992          // map the animated objects to store the original styles.
9993          allAnimations = allAnimations.map(function() {
9994              var el = $( this );
9995              return {
9996                  el: el,
9997                  start: getElementStyles( this )
9998              };
9999          });
10000  
10001          // apply class change
10002          applyClassChange = function() {
10003              $.each( classAnimationActions, function(i, action) {
10004                  if ( value[ action ] ) {
10005                      animated[ action + "Class" ]( value[ action ] );
10006                  }
10007              });
10008          };
10009          applyClassChange();
10010  
10011          // map all animated objects again - calculate new styles and diff
10012          allAnimations = allAnimations.map(function() {
10013              this.end = getElementStyles( this.el[ 0 ] );
10014              this.diff = styleDifference( this.start, this.end );
10015              return this;
10016          });
10017  
10018          // apply original class
10019          animated.attr( "class", baseClass );
10020  
10021          // map all animated objects again - this time collecting a promise
10022          allAnimations = allAnimations.map(function() {
10023              var styleInfo = this,
10024                  dfd = $.Deferred(),
10025                  opts = $.extend({}, o, {
10026                      queue: false,
10027                      complete: function() {
10028                          dfd.resolve( styleInfo );
10029                      }
10030                  });
10031  
10032              this.el.animate( this.diff, opts );
10033              return dfd.promise();
10034          });
10035  
10036          // once all animations have completed:
10037          $.when.apply( $, allAnimations.get() ).done(function() {
10038  
10039              // set the final class
10040              applyClassChange();
10041  
10042              // for each animated element,
10043              // clear all css properties that were animated
10044              $.each( arguments, function() {
10045                  var el = this.el;
10046                  $.each( this.diff, function(key) {
10047                      el.css( key, "" );
10048                  });
10049              });
10050  
10051              // this is guarnteed to be there if you use jQuery.speed()
10052              // it also handles dequeuing the next anim...
10053              o.complete.call( animated[ 0 ] );
10054          });
10055      });
10056  };
10057  
10058  $.fn.extend({
10059      addClass: (function( orig ) {
10060          return function( classNames, speed, easing, callback ) {
10061              return speed ?
10062                  $.effects.animateClass.call( this,
10063                      { add: classNames }, speed, easing, callback ) :
10064                  orig.apply( this, arguments );
10065          };
10066      })( $.fn.addClass ),
10067  
10068      removeClass: (function( orig ) {
10069          return function( classNames, speed, easing, callback ) {
10070              return arguments.length > 1 ?
10071                  $.effects.animateClass.call( this,
10072                      { remove: classNames }, speed, easing, callback ) :
10073                  orig.apply( this, arguments );
10074          };
10075      })( $.fn.removeClass ),
10076  
10077      toggleClass: (function( orig ) {
10078          return function( classNames, force, speed, easing, callback ) {
10079              if ( typeof force === "boolean" || force === undefined ) {
10080                  if ( !speed ) {
10081                      // without speed parameter
10082                      return orig.apply( this, arguments );
10083                  } else {
10084                      return $.effects.animateClass.call( this,
10085                          (force ? { add: classNames } : { remove: classNames }),
10086                          speed, easing, callback );
10087                  }
10088              } else {
10089                  // without force parameter
10090                  return $.effects.animateClass.call( this,
10091                      { toggle: classNames }, force, speed, easing );
10092              }
10093          };
10094      })( $.fn.toggleClass ),
10095  
10096      switchClass: function( remove, add, speed, easing, callback) {
10097          return $.effects.animateClass.call( this, {
10098              add: add,
10099              remove: remove
10100          }, speed, easing, callback );
10101      }
10102  });
10103  
10104  })();
10105  
10106  /******************************************************************************/
10107  /*********************************** EFFECTS **********************************/
10108  /******************************************************************************/
10109  
10110  (function() {
10111  
10112  $.extend( $.effects, {
10113      version: "1.11.1",
10114  
10115      // Saves a set of properties in a data storage
10116      save: function( element, set ) {
10117          for ( var i = 0; i < set.length; i++ ) {
10118              if ( set[ i ] !== null ) {
10119                  element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
10120              }
10121          }
10122      },
10123  
10124      // Restores a set of previously saved properties from a data storage
10125      restore: function( element, set ) {
10126          var val, i;
10127          for ( i = 0; i < set.length; i++ ) {
10128              if ( set[ i ] !== null ) {
10129                  val = element.data( dataSpace + set[ i ] );
10130                  // support: jQuery 1.6.2
10131                  // http://bugs.jquery.com/ticket/9917
10132                  // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
10133                  // We can't differentiate between "" and 0 here, so we just assume
10134                  // empty string since it's likely to be a more common value...
10135                  if ( val === undefined ) {
10136                      val = "";
10137                  }
10138                  element.css( set[ i ], val );
10139              }
10140          }
10141      },
10142  
10143      setMode: function( el, mode ) {
10144          if (mode === "toggle") {
10145              mode = el.is( ":hidden" ) ? "show" : "hide";
10146          }
10147          return mode;
10148      },
10149  
10150      // Translates a [top,left] array into a baseline value
10151      // this should be a little more flexible in the future to handle a string & hash
10152      getBaseline: function( origin, original ) {
10153          var y, x;
10154          switch ( origin[ 0 ] ) {
10155              case "top": y = 0; break;
10156              case "middle": y = 0.5; break;
10157              case "bottom": y = 1; break;
10158              default: y = origin[ 0 ] / original.height;
10159          }
10160          switch ( origin[ 1 ] ) {
10161              case "left": x = 0; break;
10162              case "center": x = 0.5; break;
10163              case "right": x = 1; break;
10164              default: x = origin[ 1 ] / original.width;
10165          }
10166          return {
10167              x: x,
10168              y: y
10169          };
10170      },
10171  
10172      // Wraps the element around a wrapper that copies position properties
10173      createWrapper: function( element ) {
10174  
10175          // if the element is already wrapped, return it
10176          if ( element.parent().is( ".ui-effects-wrapper" )) {
10177              return element.parent();
10178          }
10179  
10180          // wrap the element
10181          var props = {
10182                  width: element.outerWidth(true),
10183                  height: element.outerHeight(true),
10184                  "float": element.css( "float" )
10185              },
10186              wrapper = $( "<div></div>" )
10187                  .addClass( "ui-effects-wrapper" )
10188                  .css({
10189                      fontSize: "100%",
10190                      background: "transparent",
10191                      border: "none",
10192                      margin: 0,
10193                      padding: 0
10194                  }),
10195              // Store the size in case width/height are defined in % - Fixes #5245
10196              size = {
10197                  width: element.width(),
10198                  height: element.height()
10199              },
10200              active = document.activeElement;
10201  
10202          // support: Firefox
10203          // Firefox incorrectly exposes anonymous content
10204          // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10205          try {
10206              active.id;
10207          } catch( e ) {
10208              active = document.body;
10209          }
10210  
10211          element.wrap( wrapper );
10212  
10213          // Fixes #7595 - Elements lose focus when wrapped.
10214          if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10215              $( active ).focus();
10216          }
10217  
10218          wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
10219  
10220          // transfer positioning properties to the wrapper
10221          if ( element.css( "position" ) === "static" ) {
10222              wrapper.css({ position: "relative" });
10223              element.css({ position: "relative" });
10224          } else {
10225              $.extend( props, {
10226                  position: element.css( "position" ),
10227                  zIndex: element.css( "z-index" )
10228              });
10229              $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
10230                  props[ pos ] = element.css( pos );
10231                  if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
10232                      props[ pos ] = "auto";
10233                  }
10234              });
10235              element.css({
10236                  position: "relative",
10237                  top: 0,
10238                  left: 0,
10239                  right: "auto",
10240                  bottom: "auto"
10241              });
10242          }
10243          element.css(size);
10244  
10245          return wrapper.css( props ).show();
10246      },
10247  
10248      removeWrapper: function( element ) {
10249          var active = document.activeElement;
10250  
10251          if ( element.parent().is( ".ui-effects-wrapper" ) ) {
10252              element.parent().replaceWith( element );
10253  
10254              // Fixes #7595 - Elements lose focus when wrapped.
10255              if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
10256                  $( active ).focus();
10257              }
10258          }
10259  
10260          return element;
10261      },
10262  
10263      setTransition: function( element, list, factor, value ) {
10264          value = value || {};
10265          $.each( list, function( i, x ) {
10266              var unit = element.cssUnit( x );
10267              if ( unit[ 0 ] > 0 ) {
10268                  value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
10269              }
10270          });
10271          return value;
10272      }
10273  });
10274  
10275  // return an effect options object for the given parameters:
10276  function _normalizeArguments( effect, options, speed, callback ) {
10277  
10278      // allow passing all options as the first parameter
10279      if ( $.isPlainObject( effect ) ) {
10280          options = effect;
10281          effect = effect.effect;
10282      }
10283  
10284      // convert to an object
10285      effect = { effect: effect };
10286  
10287      // catch (effect, null, ...)
10288      if ( options == null ) {
10289          options = {};
10290      }
10291  
10292      // catch (effect, callback)
10293      if ( $.isFunction( options ) ) {
10294          callback = options;
10295          speed = null;
10296          options = {};
10297      }
10298  
10299      // catch (effect, speed, ?)
10300      if ( typeof options === "number" || $.fx.speeds[ options ] ) {
10301          callback = speed;
10302          speed = options;
10303          options = {};
10304      }
10305  
10306      // catch (effect, options, callback)
10307      if ( $.isFunction( speed ) ) {
10308          callback = speed;
10309          speed = null;
10310      }
10311  
10312      // add options to effect
10313      if ( options ) {
10314          $.extend( effect, options );
10315      }
10316  
10317      speed = speed || options.duration;
10318      effect.duration = $.fx.off ? 0 :
10319          typeof speed === "number" ? speed :
10320          speed in $.fx.speeds ? $.fx.speeds[ speed ] :
10321          $.fx.speeds._default;
10322  
10323      effect.complete = callback || options.complete;
10324  
10325      return effect;
10326  }
10327  
10328  function standardAnimationOption( option ) {
10329      // Valid standard speeds (nothing, number, named speed)
10330      if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
10331          return true;
10332      }
10333  
10334      // Invalid strings - treat as "normal" speed
10335      if ( typeof option === "string" && !$.effects.effect[ option ] ) {
10336          return true;
10337      }
10338  
10339      // Complete callback
10340      if ( $.isFunction( option ) ) {
10341          return true;
10342      }
10343  
10344      // Options hash (but not naming an effect)
10345      if ( typeof option === "object" && !option.effect ) {
10346          return true;
10347      }
10348  
10349      // Didn't match any standard API
10350      return false;
10351  }
10352  
10353  $.fn.extend({
10354      effect: function( /* effect, options, speed, callback */ ) {
10355          var args = _normalizeArguments.apply( this, arguments ),
10356              mode = args.mode,
10357              queue = args.queue,
10358              effectMethod = $.effects.effect[ args.effect ];
10359  
10360          if ( $.fx.off || !effectMethod ) {
10361              // delegate to the original method (e.g., .show()) if possible
10362              if ( mode ) {
10363                  return this[ mode ]( args.duration, args.complete );
10364              } else {
10365                  return this.each( function() {
10366                      if ( args.complete ) {
10367                          args.complete.call( this );
10368                      }
10369                  });
10370              }
10371          }
10372  
10373  		function run( next ) {
10374              var elem = $( this ),
10375                  complete = args.complete,
10376                  mode = args.mode;
10377  
10378  			function done() {
10379                  if ( $.isFunction( complete ) ) {
10380                      complete.call( elem[0] );
10381                  }
10382                  if ( $.isFunction( next ) ) {
10383                      next();
10384                  }
10385              }
10386  
10387              // If the element already has the correct final state, delegate to
10388              // the core methods so the internal tracking of "olddisplay" works.
10389              if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
10390                  elem[ mode ]();
10391                  done();
10392              } else {
10393                  effectMethod.call( elem[0], args, done );
10394              }
10395          }
10396  
10397          return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
10398      },
10399  
10400      show: (function( orig ) {
10401          return function( option ) {
10402              if ( standardAnimationOption( option ) ) {
10403                  return orig.apply( this, arguments );
10404              } else {
10405                  var args = _normalizeArguments.apply( this, arguments );
10406                  args.mode = "show";
10407                  return this.effect.call( this, args );
10408              }
10409          };
10410      })( $.fn.show ),
10411  
10412      hide: (function( orig ) {
10413          return function( option ) {
10414              if ( standardAnimationOption( option ) ) {
10415                  return orig.apply( this, arguments );
10416              } else {
10417                  var args = _normalizeArguments.apply( this, arguments );
10418                  args.mode = "hide";
10419                  return this.effect.call( this, args );
10420              }
10421          };
10422      })( $.fn.hide ),
10423  
10424      toggle: (function( orig ) {
10425          return function( option ) {
10426              if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
10427                  return orig.apply( this, arguments );
10428              } else {
10429                  var args = _normalizeArguments.apply( this, arguments );
10430                  args.mode = "toggle";
10431                  return this.effect.call( this, args );
10432              }
10433          };
10434      })( $.fn.toggle ),
10435  
10436      // helper functions
10437      cssUnit: function(key) {
10438          var style = this.css( key ),
10439              val = [];
10440  
10441          $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
10442              if ( style.indexOf( unit ) > 0 ) {
10443                  val = [ parseFloat( style ), unit ];
10444              }
10445          });
10446          return val;
10447      }
10448  });
10449  
10450  })();
10451  
10452  /******************************************************************************/
10453  /*********************************** EASING ***********************************/
10454  /******************************************************************************/
10455  
10456  (function() {
10457  
10458  // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
10459  
10460  var baseEasings = {};
10461  
10462  $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
10463      baseEasings[ name ] = function( p ) {
10464          return Math.pow( p, i + 2 );
10465      };
10466  });
10467  
10468  $.extend( baseEasings, {
10469      Sine: function( p ) {
10470          return 1 - Math.cos( p * Math.PI / 2 );
10471      },
10472      Circ: function( p ) {
10473          return 1 - Math.sqrt( 1 - p * p );
10474      },
10475      Elastic: function( p ) {
10476          return p === 0 || p === 1 ? p :
10477              -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
10478      },
10479      Back: function( p ) {
10480          return p * p * ( 3 * p - 2 );
10481      },
10482      Bounce: function( p ) {
10483          var pow2,
10484              bounce = 4;
10485  
10486          while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
10487          return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
10488      }
10489  });
10490  
10491  $.each( baseEasings, function( name, easeIn ) {
10492      $.easing[ "easeIn" + name ] = easeIn;
10493      $.easing[ "easeOut" + name ] = function( p ) {
10494          return 1 - easeIn( 1 - p );
10495      };
10496      $.easing[ "easeInOut" + name ] = function( p ) {
10497          return p < 0.5 ?
10498              easeIn( p * 2 ) / 2 :
10499              1 - easeIn( p * -2 + 2 ) / 2;
10500      };
10501  });
10502  
10503  })();
10504  
10505  var effect = $.effects;
10506  
10507  
10508  /*!
10509   * jQuery UI Effects Blind 1.11.1
10510   * http://jqueryui.com
10511   *
10512   * Copyright 2014 jQuery Foundation and other contributors
10513   * Released under the MIT license.
10514   * http://jquery.org/license
10515   *
10516   * http://api.jqueryui.com/blind-effect/
10517   */
10518  
10519  
10520  var effectBlind = $.effects.effect.blind = function( o, done ) {
10521      // Create element
10522      var el = $( this ),
10523          rvertical = /up|down|vertical/,
10524          rpositivemotion = /up|left|vertical|horizontal/,
10525          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10526          mode = $.effects.setMode( el, o.mode || "hide" ),
10527          direction = o.direction || "up",
10528          vertical = rvertical.test( direction ),
10529          ref = vertical ? "height" : "width",
10530          ref2 = vertical ? "top" : "left",
10531          motion = rpositivemotion.test( direction ),
10532          animation = {},
10533          show = mode === "show",
10534          wrapper, distance, margin;
10535  
10536      // if already wrapped, the wrapper's properties are my property. #6245
10537      if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10538          $.effects.save( el.parent(), props );
10539      } else {
10540          $.effects.save( el, props );
10541      }
10542      el.show();
10543      wrapper = $.effects.createWrapper( el ).css({
10544          overflow: "hidden"
10545      });
10546  
10547      distance = wrapper[ ref ]();
10548      margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10549  
10550      animation[ ref ] = show ? distance : 0;
10551      if ( !motion ) {
10552          el
10553              .css( vertical ? "bottom" : "right", 0 )
10554              .css( vertical ? "top" : "left", "auto" )
10555              .css({ position: "absolute" });
10556  
10557          animation[ ref2 ] = show ? margin : distance + margin;
10558      }
10559  
10560      // start at 0 if we are showing
10561      if ( show ) {
10562          wrapper.css( ref, 0 );
10563          if ( !motion ) {
10564              wrapper.css( ref2, margin + distance );
10565          }
10566      }
10567  
10568      // Animate
10569      wrapper.animate( animation, {
10570          duration: o.duration,
10571          easing: o.easing,
10572          queue: false,
10573          complete: function() {
10574              if ( mode === "hide" ) {
10575                  el.hide();
10576              }
10577              $.effects.restore( el, props );
10578              $.effects.removeWrapper( el );
10579              done();
10580          }
10581      });
10582  };
10583  
10584  
10585  /*!
10586   * jQuery UI Effects Bounce 1.11.1
10587   * http://jqueryui.com
10588   *
10589   * Copyright 2014 jQuery Foundation and other contributors
10590   * Released under the MIT license.
10591   * http://jquery.org/license
10592   *
10593   * http://api.jqueryui.com/bounce-effect/
10594   */
10595  
10596  
10597  var effectBounce = $.effects.effect.bounce = function( o, done ) {
10598      var el = $( this ),
10599          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10600  
10601          // defaults:
10602          mode = $.effects.setMode( el, o.mode || "effect" ),
10603          hide = mode === "hide",
10604          show = mode === "show",
10605          direction = o.direction || "up",
10606          distance = o.distance,
10607          times = o.times || 5,
10608  
10609          // number of internal animations
10610          anims = times * 2 + ( show || hide ? 1 : 0 ),
10611          speed = o.duration / anims,
10612          easing = o.easing,
10613  
10614          // utility:
10615          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10616          motion = ( direction === "up" || direction === "left" ),
10617          i,
10618          upAnim,
10619          downAnim,
10620  
10621          // we will need to re-assemble the queue to stack our animations in place
10622          queue = el.queue(),
10623          queuelen = queue.length;
10624  
10625      // Avoid touching opacity to prevent clearType and PNG issues in IE
10626      if ( show || hide ) {
10627          props.push( "opacity" );
10628      }
10629  
10630      $.effects.save( el, props );
10631      el.show();
10632      $.effects.createWrapper( el ); // Create Wrapper
10633  
10634      // default distance for the BIGGEST bounce is the outer Distance / 3
10635      if ( !distance ) {
10636          distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10637      }
10638  
10639      if ( show ) {
10640          downAnim = { opacity: 1 };
10641          downAnim[ ref ] = 0;
10642  
10643          // if we are showing, force opacity 0 and set the initial position
10644          // then do the "first" animation
10645          el.css( "opacity", 0 )
10646              .css( ref, motion ? -distance * 2 : distance * 2 )
10647              .animate( downAnim, speed, easing );
10648      }
10649  
10650      // start at the smallest distance if we are hiding
10651      if ( hide ) {
10652          distance = distance / Math.pow( 2, times - 1 );
10653      }
10654  
10655      downAnim = {};
10656      downAnim[ ref ] = 0;
10657      // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10658      for ( i = 0; i < times; i++ ) {
10659          upAnim = {};
10660          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10661  
10662          el.animate( upAnim, speed, easing )
10663              .animate( downAnim, speed, easing );
10664  
10665          distance = hide ? distance * 2 : distance / 2;
10666      }
10667  
10668      // Last Bounce when Hiding
10669      if ( hide ) {
10670          upAnim = { opacity: 0 };
10671          upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10672  
10673          el.animate( upAnim, speed, easing );
10674      }
10675  
10676      el.queue(function() {
10677          if ( hide ) {
10678              el.hide();
10679          }
10680          $.effects.restore( el, props );
10681          $.effects.removeWrapper( el );
10682          done();
10683      });
10684  
10685      // inject all the animations we just queued to be first in line (after "inprogress")
10686      if ( queuelen > 1) {
10687          queue.splice.apply( queue,
10688              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10689      }
10690      el.dequeue();
10691  
10692  };
10693  
10694  
10695  /*!
10696   * jQuery UI Effects Clip 1.11.1
10697   * http://jqueryui.com
10698   *
10699   * Copyright 2014 jQuery Foundation and other contributors
10700   * Released under the MIT license.
10701   * http://jquery.org/license
10702   *
10703   * http://api.jqueryui.com/clip-effect/
10704   */
10705  
10706  
10707  var effectClip = $.effects.effect.clip = function( o, done ) {
10708      // Create element
10709      var el = $( this ),
10710          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10711          mode = $.effects.setMode( el, o.mode || "hide" ),
10712          show = mode === "show",
10713          direction = o.direction || "vertical",
10714          vert = direction === "vertical",
10715          size = vert ? "height" : "width",
10716          position = vert ? "top" : "left",
10717          animation = {},
10718          wrapper, animate, distance;
10719  
10720      // Save & Show
10721      $.effects.save( el, props );
10722      el.show();
10723  
10724      // Create Wrapper
10725      wrapper = $.effects.createWrapper( el ).css({
10726          overflow: "hidden"
10727      });
10728      animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10729      distance = animate[ size ]();
10730  
10731      // Shift
10732      if ( show ) {
10733          animate.css( size, 0 );
10734          animate.css( position, distance / 2 );
10735      }
10736  
10737      // Create Animation Object:
10738      animation[ size ] = show ? distance : 0;
10739      animation[ position ] = show ? 0 : distance / 2;
10740  
10741      // Animate
10742      animate.animate( animation, {
10743          queue: false,
10744          duration: o.duration,
10745          easing: o.easing,
10746          complete: function() {
10747              if ( !show ) {
10748                  el.hide();
10749              }
10750              $.effects.restore( el, props );
10751              $.effects.removeWrapper( el );
10752              done();
10753          }
10754      });
10755  
10756  };
10757  
10758  
10759  /*!
10760   * jQuery UI Effects Drop 1.11.1
10761   * http://jqueryui.com
10762   *
10763   * Copyright 2014 jQuery Foundation and other contributors
10764   * Released under the MIT license.
10765   * http://jquery.org/license
10766   *
10767   * http://api.jqueryui.com/drop-effect/
10768   */
10769  
10770  
10771  var effectDrop = $.effects.effect.drop = function( o, done ) {
10772  
10773      var el = $( this ),
10774          props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10775          mode = $.effects.setMode( el, o.mode || "hide" ),
10776          show = mode === "show",
10777          direction = o.direction || "left",
10778          ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10779          motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10780          animation = {
10781              opacity: show ? 1 : 0
10782          },
10783          distance;
10784  
10785      // Adjust
10786      $.effects.save( el, props );
10787      el.show();
10788      $.effects.createWrapper( el );
10789  
10790      distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10791  
10792      if ( show ) {
10793          el
10794              .css( "opacity", 0 )
10795              .css( ref, motion === "pos" ? -distance : distance );
10796      }
10797  
10798      // Animation
10799      animation[ ref ] = ( show ?
10800          ( motion === "pos" ? "+=" : "-=" ) :
10801          ( motion === "pos" ? "-=" : "+=" ) ) +
10802          distance;
10803  
10804      // Animate
10805      el.animate( animation, {
10806          queue: false,
10807          duration: o.duration,
10808          easing: o.easing,
10809          complete: function() {
10810              if ( mode === "hide" ) {
10811                  el.hide();
10812              }
10813              $.effects.restore( el, props );
10814              $.effects.removeWrapper( el );
10815              done();
10816          }
10817      });
10818  };
10819  
10820  
10821  /*!
10822   * jQuery UI Effects Explode 1.11.1
10823   * http://jqueryui.com
10824   *
10825   * Copyright 2014 jQuery Foundation and other contributors
10826   * Released under the MIT license.
10827   * http://jquery.org/license
10828   *
10829   * http://api.jqueryui.com/explode-effect/
10830   */
10831  
10832  
10833  var effectExplode = $.effects.effect.explode = function( o, done ) {
10834  
10835      var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10836          cells = rows,
10837          el = $( this ),
10838          mode = $.effects.setMode( el, o.mode || "hide" ),
10839          show = mode === "show",
10840  
10841          // show and then visibility:hidden the element before calculating offset
10842          offset = el.show().css( "visibility", "hidden" ).offset(),
10843  
10844          // width and height of a piece
10845          width = Math.ceil( el.outerWidth() / cells ),
10846          height = Math.ceil( el.outerHeight() / rows ),
10847          pieces = [],
10848  
10849          // loop
10850          i, j, left, top, mx, my;
10851  
10852      // children animate complete:
10853  	function childComplete() {
10854          pieces.push( this );
10855          if ( pieces.length === rows * cells ) {
10856              animComplete();
10857          }
10858      }
10859  
10860      // clone the element for each row and cell.
10861      for ( i = 0; i < rows ; i++ ) { // ===>
10862          top = offset.top + i * height;
10863          my = i - ( rows - 1 ) / 2 ;
10864  
10865          for ( j = 0; j < cells ; j++ ) { // |||
10866              left = offset.left + j * width;
10867              mx = j - ( cells - 1 ) / 2 ;
10868  
10869              // Create a clone of the now hidden main element that will be absolute positioned
10870              // within a wrapper div off the -left and -top equal to size of our pieces
10871              el
10872                  .clone()
10873                  .appendTo( "body" )
10874                  .wrap( "<div></div>" )
10875                  .css({
10876                      position: "absolute",
10877                      visibility: "visible",
10878                      left: -j * width,
10879                      top: -i * height
10880                  })
10881  
10882              // select the wrapper - make it overflow: hidden and absolute positioned based on
10883              // where the original was located +left and +top equal to the size of pieces
10884                  .parent()
10885                  .addClass( "ui-effects-explode" )
10886                  .css({
10887                      position: "absolute",
10888                      overflow: "hidden",
10889                      width: width,
10890                      height: height,
10891                      left: left + ( show ? mx * width : 0 ),
10892                      top: top + ( show ? my * height : 0 ),
10893                      opacity: show ? 0 : 1
10894                  }).animate({
10895                      left: left + ( show ? 0 : mx * width ),
10896                      top: top + ( show ? 0 : my * height ),
10897                      opacity: show ? 1 : 0
10898                  }, o.duration || 500, o.easing, childComplete );
10899          }
10900      }
10901  
10902  	function animComplete() {
10903          el.css({
10904              visibility: "visible"
10905          });
10906          $( pieces ).remove();
10907          if ( !show ) {
10908              el.hide();
10909          }
10910          done();
10911      }
10912  };
10913  
10914  
10915  /*!
10916   * jQuery UI Effects Fade 1.11.1
10917   * http://jqueryui.com
10918   *
10919   * Copyright 2014 jQuery Foundation and other contributors
10920   * Released under the MIT license.
10921   * http://jquery.org/license
10922   *
10923   * http://api.jqueryui.com/fade-effect/
10924   */
10925  
10926  
10927  var effectFade = $.effects.effect.fade = function( o, done ) {
10928      var el = $( this ),
10929          mode = $.effects.setMode( el, o.mode || "toggle" );
10930  
10931      el.animate({
10932          opacity: mode
10933      }, {
10934          queue: false,
10935          duration: o.duration,
10936          easing: o.easing,
10937          complete: done
10938      });
10939  };
10940  
10941  
10942  /*!
10943   * jQuery UI Effects Fold 1.11.1
10944   * http://jqueryui.com
10945   *
10946   * Copyright 2014 jQuery Foundation and other contributors
10947   * Released under the MIT license.
10948   * http://jquery.org/license
10949   *
10950   * http://api.jqueryui.com/fold-effect/
10951   */
10952  
10953  
10954  var effectFold = $.effects.effect.fold = function( o, done ) {
10955  
10956      // Create element
10957      var el = $( this ),
10958          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10959          mode = $.effects.setMode( el, o.mode || "hide" ),
10960          show = mode === "show",
10961          hide = mode === "hide",
10962          size = o.size || 15,
10963          percent = /([0-9]+)%/.exec( size ),
10964          horizFirst = !!o.horizFirst,
10965          widthFirst = show !== horizFirst,
10966          ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10967          duration = o.duration / 2,
10968          wrapper, distance,
10969          animation1 = {},
10970          animation2 = {};
10971  
10972      $.effects.save( el, props );
10973      el.show();
10974  
10975      // Create Wrapper
10976      wrapper = $.effects.createWrapper( el ).css({
10977          overflow: "hidden"
10978      });
10979      distance = widthFirst ?
10980          [ wrapper.width(), wrapper.height() ] :
10981          [ wrapper.height(), wrapper.width() ];
10982  
10983      if ( percent ) {
10984          size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10985      }
10986      if ( show ) {
10987          wrapper.css( horizFirst ? {
10988              height: 0,
10989              width: size
10990          } : {
10991              height: size,
10992              width: 0
10993          });
10994      }
10995  
10996      // Animation
10997      animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10998      animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10999  
11000      // Animate
11001      wrapper
11002          .animate( animation1, duration, o.easing )
11003          .animate( animation2, duration, o.easing, function() {
11004              if ( hide ) {
11005                  el.hide();
11006              }
11007              $.effects.restore( el, props );
11008              $.effects.removeWrapper( el );
11009              done();
11010          });
11011  
11012  };
11013  
11014  
11015  /*!
11016   * jQuery UI Effects Highlight 1.11.1
11017   * http://jqueryui.com
11018   *
11019   * Copyright 2014 jQuery Foundation and other contributors
11020   * Released under the MIT license.
11021   * http://jquery.org/license
11022   *
11023   * http://api.jqueryui.com/highlight-effect/
11024   */
11025  
11026  
11027  var effectHighlight = $.effects.effect.highlight = function( o, done ) {
11028      var elem = $( this ),
11029          props = [ "backgroundImage", "backgroundColor", "opacity" ],
11030          mode = $.effects.setMode( elem, o.mode || "show" ),
11031          animation = {
11032              backgroundColor: elem.css( "backgroundColor" )
11033          };
11034  
11035      if (mode === "hide") {
11036          animation.opacity = 0;
11037      }
11038  
11039      $.effects.save( elem, props );
11040  
11041      elem
11042          .show()
11043          .css({
11044              backgroundImage: "none",
11045              backgroundColor: o.color || "#ffff99"
11046          })
11047          .animate( animation, {
11048              queue: false,
11049              duration: o.duration,
11050              easing: o.easing,
11051              complete: function() {
11052                  if ( mode === "hide" ) {
11053                      elem.hide();
11054                  }
11055                  $.effects.restore( elem, props );
11056                  done();
11057              }
11058          });
11059  };
11060  
11061  
11062  /*!
11063   * jQuery UI Effects Size 1.11.1
11064   * http://jqueryui.com
11065   *
11066   * Copyright 2014 jQuery Foundation and other contributors
11067   * Released under the MIT license.
11068   * http://jquery.org/license
11069   *
11070   * http://api.jqueryui.com/size-effect/
11071   */
11072  
11073  
11074  var effectSize = $.effects.effect.size = function( o, done ) {
11075  
11076      // Create element
11077      var original, baseline, factor,
11078          el = $( this ),
11079          props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11080  
11081          // Always restore
11082          props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11083  
11084          // Copy for children
11085          props2 = [ "width", "height", "overflow" ],
11086          cProps = [ "fontSize" ],
11087          vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11088          hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11089  
11090          // Set options
11091          mode = $.effects.setMode( el, o.mode || "effect" ),
11092          restore = o.restore || mode !== "effect",
11093          scale = o.scale || "both",
11094          origin = o.origin || [ "middle", "center" ],
11095          position = el.css( "position" ),
11096          props = restore ? props0 : props1,
11097          zero = {
11098              height: 0,
11099              width: 0,
11100              outerHeight: 0,
11101              outerWidth: 0
11102          };
11103  
11104      if ( mode === "show" ) {
11105          el.show();
11106      }
11107      original = {
11108          height: el.height(),
11109          width: el.width(),
11110          outerHeight: el.outerHeight(),
11111          outerWidth: el.outerWidth()
11112      };
11113  
11114      if ( o.mode === "toggle" && mode === "show" ) {
11115          el.from = o.to || zero;
11116          el.to = o.from || original;
11117      } else {
11118          el.from = o.from || ( mode === "show" ? zero : original );
11119          el.to = o.to || ( mode === "hide" ? zero : original );
11120      }
11121  
11122      // Set scaling factor
11123      factor = {
11124          from: {
11125              y: el.from.height / original.height,
11126              x: el.from.width / original.width
11127          },
11128          to: {
11129              y: el.to.height / original.height,
11130              x: el.to.width / original.width
11131          }
11132      };
11133  
11134      // Scale the css box
11135      if ( scale === "box" || scale === "both" ) {
11136  
11137          // Vertical props scaling
11138          if ( factor.from.y !== factor.to.y ) {
11139              props = props.concat( vProps );
11140              el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11141              el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11142          }
11143  
11144          // Horizontal props scaling
11145          if ( factor.from.x !== factor.to.x ) {
11146              props = props.concat( hProps );
11147              el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11148              el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11149          }
11150      }
11151  
11152      // Scale the content
11153      if ( scale === "content" || scale === "both" ) {
11154  
11155          // Vertical props scaling
11156          if ( factor.from.y !== factor.to.y ) {
11157              props = props.concat( cProps ).concat( props2 );
11158              el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11159              el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11160          }
11161      }
11162  
11163      $.effects.save( el, props );
11164      el.show();
11165      $.effects.createWrapper( el );
11166      el.css( "overflow", "hidden" ).css( el.from );
11167  
11168      // Adjust
11169      if (origin) { // Calculate baseline shifts
11170          baseline = $.effects.getBaseline( origin, original );
11171          el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11172          el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11173          el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11174          el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11175      }
11176      el.css( el.from ); // set top & left
11177  
11178      // Animate
11179      if ( scale === "content" || scale === "both" ) { // Scale the children
11180  
11181          // Add margins/font-size
11182          vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11183          hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11184          props2 = props0.concat(vProps).concat(hProps);
11185  
11186          el.find( "*[width]" ).each( function() {
11187              var child = $( this ),
11188                  c_original = {
11189                      height: child.height(),
11190                      width: child.width(),
11191                      outerHeight: child.outerHeight(),
11192                      outerWidth: child.outerWidth()
11193                  };
11194              if (restore) {
11195                  $.effects.save(child, props2);
11196              }
11197  
11198              child.from = {
11199                  height: c_original.height * factor.from.y,
11200                  width: c_original.width * factor.from.x,
11201                  outerHeight: c_original.outerHeight * factor.from.y,
11202                  outerWidth: c_original.outerWidth * factor.from.x
11203              };
11204              child.to = {
11205                  height: c_original.height * factor.to.y,
11206                  width: c_original.width * factor.to.x,
11207                  outerHeight: c_original.height * factor.to.y,
11208                  outerWidth: c_original.width * factor.to.x
11209              };
11210  
11211              // Vertical props scaling
11212              if ( factor.from.y !== factor.to.y ) {
11213                  child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11214                  child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11215              }
11216  
11217              // Horizontal props scaling
11218              if ( factor.from.x !== factor.to.x ) {
11219                  child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11220                  child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11221              }
11222  
11223              // Animate children
11224              child.css( child.from );
11225              child.animate( child.to, o.duration, o.easing, function() {
11226  
11227                  // Restore children
11228                  if ( restore ) {
11229                      $.effects.restore( child, props2 );
11230                  }
11231              });
11232          });
11233      }
11234  
11235      // Animate
11236      el.animate( el.to, {
11237          queue: false,
11238          duration: o.duration,
11239          easing: o.easing,
11240          complete: function() {
11241              if ( el.to.opacity === 0 ) {
11242                  el.css( "opacity", el.from.opacity );
11243              }
11244              if ( mode === "hide" ) {
11245                  el.hide();
11246              }
11247              $.effects.restore( el, props );
11248              if ( !restore ) {
11249  
11250                  // we need to calculate our new positioning based on the scaling
11251                  if ( position === "static" ) {
11252                      el.css({
11253                          position: "relative",
11254                          top: el.to.top,
11255                          left: el.to.left
11256                      });
11257                  } else {
11258                      $.each([ "top", "left" ], function( idx, pos ) {
11259                          el.css( pos, function( _, str ) {
11260                              var val = parseInt( str, 10 ),
11261                                  toRef = idx ? el.to.left : el.to.top;
11262  
11263                              // if original was "auto", recalculate the new value from wrapper
11264                              if ( str === "auto" ) {
11265                                  return toRef + "px";
11266                              }
11267  
11268                              return val + toRef + "px";
11269                          });
11270                      });
11271                  }
11272              }
11273  
11274              $.effects.removeWrapper( el );
11275              done();
11276          }
11277      });
11278  
11279  };
11280  
11281  
11282  /*!
11283   * jQuery UI Effects Scale 1.11.1
11284   * http://jqueryui.com
11285   *
11286   * Copyright 2014 jQuery Foundation and other contributors
11287   * Released under the MIT license.
11288   * http://jquery.org/license
11289   *
11290   * http://api.jqueryui.com/scale-effect/
11291   */
11292  
11293  
11294  var effectScale = $.effects.effect.scale = function( o, done ) {
11295  
11296      // Create element
11297      var el = $( this ),
11298          options = $.extend( true, {}, o ),
11299          mode = $.effects.setMode( el, o.mode || "effect" ),
11300          percent = parseInt( o.percent, 10 ) ||
11301              ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11302          direction = o.direction || "both",
11303          origin = o.origin,
11304          original = {
11305              height: el.height(),
11306              width: el.width(),
11307              outerHeight: el.outerHeight(),
11308              outerWidth: el.outerWidth()
11309          },
11310          factor = {
11311              y: direction !== "horizontal" ? (percent / 100) : 1,
11312              x: direction !== "vertical" ? (percent / 100) : 1
11313          };
11314  
11315      // We are going to pass this effect to the size effect:
11316      options.effect = "size";
11317      options.queue = false;
11318      options.complete = done;
11319  
11320      // Set default origin and restore for show/hide
11321      if ( mode !== "effect" ) {
11322          options.origin = origin || [ "middle", "center" ];
11323          options.restore = true;
11324      }
11325  
11326      options.from = o.from || ( mode === "show" ? {
11327          height: 0,
11328          width: 0,
11329          outerHeight: 0,
11330          outerWidth: 0
11331      } : original );
11332      options.to = {
11333          height: original.height * factor.y,
11334          width: original.width * factor.x,
11335          outerHeight: original.outerHeight * factor.y,
11336          outerWidth: original.outerWidth * factor.x
11337      };
11338  
11339      // Fade option to support puff
11340      if ( options.fade ) {
11341          if ( mode === "show" ) {
11342              options.from.opacity = 0;
11343              options.to.opacity = 1;
11344          }
11345          if ( mode === "hide" ) {
11346              options.from.opacity = 1;
11347              options.to.opacity = 0;
11348          }
11349      }
11350  
11351      // Animate
11352      el.effect( options );
11353  
11354  };
11355  
11356  
11357  /*!
11358   * jQuery UI Effects Puff 1.11.1
11359   * http://jqueryui.com
11360   *
11361   * Copyright 2014 jQuery Foundation and other contributors
11362   * Released under the MIT license.
11363   * http://jquery.org/license
11364   *
11365   * http://api.jqueryui.com/puff-effect/
11366   */
11367  
11368  
11369  var effectPuff = $.effects.effect.puff = function( o, done ) {
11370      var elem = $( this ),
11371          mode = $.effects.setMode( elem, o.mode || "hide" ),
11372          hide = mode === "hide",
11373          percent = parseInt( o.percent, 10 ) || 150,
11374          factor = percent / 100,
11375          original = {
11376              height: elem.height(),
11377              width: elem.width(),
11378              outerHeight: elem.outerHeight(),
11379              outerWidth: elem.outerWidth()
11380          };
11381  
11382      $.extend( o, {
11383          effect: "scale",
11384          queue: false,
11385          fade: true,
11386          mode: mode,
11387          complete: done,
11388          percent: hide ? percent : 100,
11389          from: hide ?
11390              original :
11391              {
11392                  height: original.height * factor,
11393                  width: original.width * factor,
11394                  outerHeight: original.outerHeight * factor,
11395                  outerWidth: original.outerWidth * factor
11396              }
11397      });
11398  
11399      elem.effect( o );
11400  };
11401  
11402  
11403  /*!
11404   * jQuery UI Effects Pulsate 1.11.1
11405   * http://jqueryui.com
11406   *
11407   * Copyright 2014 jQuery Foundation and other contributors
11408   * Released under the MIT license.
11409   * http://jquery.org/license
11410   *
11411   * http://api.jqueryui.com/pulsate-effect/
11412   */
11413  
11414  
11415  var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
11416      var elem = $( this ),
11417          mode = $.effects.setMode( elem, o.mode || "show" ),
11418          show = mode === "show",
11419          hide = mode === "hide",
11420          showhide = ( show || mode === "hide" ),
11421  
11422          // showing or hiding leaves of the "last" animation
11423          anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
11424          duration = o.duration / anims,
11425          animateTo = 0,
11426          queue = elem.queue(),
11427          queuelen = queue.length,
11428          i;
11429  
11430      if ( show || !elem.is(":visible")) {
11431          elem.css( "opacity", 0 ).show();
11432          animateTo = 1;
11433      }
11434  
11435      // anims - 1 opacity "toggles"
11436      for ( i = 1; i < anims; i++ ) {
11437          elem.animate({
11438              opacity: animateTo
11439          }, duration, o.easing );
11440          animateTo = 1 - animateTo;
11441      }
11442  
11443      elem.animate({
11444          opacity: animateTo
11445      }, duration, o.easing);
11446  
11447      elem.queue(function() {
11448          if ( hide ) {
11449              elem.hide();
11450          }
11451          done();
11452      });
11453  
11454      // We just queued up "anims" animations, we need to put them next in the queue
11455      if ( queuelen > 1 ) {
11456          queue.splice.apply( queue,
11457              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11458      }
11459      elem.dequeue();
11460  };
11461  
11462  
11463  /*!
11464   * jQuery UI Effects Shake 1.11.1
11465   * http://jqueryui.com
11466   *
11467   * Copyright 2014 jQuery Foundation and other contributors
11468   * Released under the MIT license.
11469   * http://jquery.org/license
11470   *
11471   * http://api.jqueryui.com/shake-effect/
11472   */
11473  
11474  
11475  var effectShake = $.effects.effect.shake = function( o, done ) {
11476  
11477      var el = $( this ),
11478          props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11479          mode = $.effects.setMode( el, o.mode || "effect" ),
11480          direction = o.direction || "left",
11481          distance = o.distance || 20,
11482          times = o.times || 3,
11483          anims = times * 2 + 1,
11484          speed = Math.round( o.duration / anims ),
11485          ref = (direction === "up" || direction === "down") ? "top" : "left",
11486          positiveMotion = (direction === "up" || direction === "left"),
11487          animation = {},
11488          animation1 = {},
11489          animation2 = {},
11490          i,
11491  
11492          // we will need to re-assemble the queue to stack our animations in place
11493          queue = el.queue(),
11494          queuelen = queue.length;
11495  
11496      $.effects.save( el, props );
11497      el.show();
11498      $.effects.createWrapper( el );
11499  
11500      // Animation
11501      animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11502      animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11503      animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11504  
11505      // Animate
11506      el.animate( animation, speed, o.easing );
11507  
11508      // Shakes
11509      for ( i = 1; i < times; i++ ) {
11510          el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11511      }
11512      el
11513          .animate( animation1, speed, o.easing )
11514          .animate( animation, speed / 2, o.easing )
11515          .queue(function() {
11516              if ( mode === "hide" ) {
11517                  el.hide();
11518              }
11519              $.effects.restore( el, props );
11520              $.effects.removeWrapper( el );
11521              done();
11522          });
11523  
11524      // inject all the animations we just queued to be first in line (after "inprogress")
11525      if ( queuelen > 1) {
11526          queue.splice.apply( queue,
11527              [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11528      }
11529      el.dequeue();
11530  
11531  };
11532  
11533  
11534  /*!
11535   * jQuery UI Effects Slide 1.11.1
11536   * http://jqueryui.com
11537   *
11538   * Copyright 2014 jQuery Foundation and other contributors
11539   * Released under the MIT license.
11540   * http://jquery.org/license
11541   *
11542   * http://api.jqueryui.com/slide-effect/
11543   */
11544  
11545  
11546  var effectSlide = $.effects.effect.slide = function( o, done ) {
11547  
11548      // Create element
11549      var el = $( this ),
11550          props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11551          mode = $.effects.setMode( el, o.mode || "show" ),
11552          show = mode === "show",
11553          direction = o.direction || "left",
11554          ref = (direction === "up" || direction === "down") ? "top" : "left",
11555          positiveMotion = (direction === "up" || direction === "left"),
11556          distance,
11557          animation = {};
11558  
11559      // Adjust
11560      $.effects.save( el, props );
11561      el.show();
11562      distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11563  
11564      $.effects.createWrapper( el ).css({
11565          overflow: "hidden"
11566      });
11567  
11568      if ( show ) {
11569          el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11570      }
11571  
11572      // Animation
11573      animation[ ref ] = ( show ?
11574          ( positiveMotion ? "+=" : "-=") :
11575          ( positiveMotion ? "-=" : "+=")) +
11576          distance;
11577  
11578      // Animate
11579      el.animate( animation, {
11580          queue: false,
11581          duration: o.duration,
11582          easing: o.easing,
11583          complete: function() {
11584              if ( mode === "hide" ) {
11585                  el.hide();
11586              }
11587              $.effects.restore( el, props );
11588              $.effects.removeWrapper( el );
11589              done();
11590          }
11591      });
11592  };
11593  
11594  
11595  /*!
11596   * jQuery UI Effects Transfer 1.11.1
11597   * http://jqueryui.com
11598   *
11599   * Copyright 2014 jQuery Foundation and other contributors
11600   * Released under the MIT license.
11601   * http://jquery.org/license
11602   *
11603   * http://api.jqueryui.com/transfer-effect/
11604   */
11605  
11606  
11607  var effectTransfer = $.effects.effect.transfer = function( o, done ) {
11608      var elem = $( this ),
11609          target = $( o.to ),
11610          targetFixed = target.css( "position" ) === "fixed",
11611          body = $("body"),
11612          fixTop = targetFixed ? body.scrollTop() : 0,
11613          fixLeft = targetFixed ? body.scrollLeft() : 0,
11614          endPosition = target.offset(),
11615          animation = {
11616              top: endPosition.top - fixTop,
11617              left: endPosition.left - fixLeft,
11618              height: target.innerHeight(),
11619              width: target.innerWidth()
11620          },
11621          startPosition = elem.offset(),
11622          transfer = $( "<div class='ui-effects-transfer'></div>" )
11623              .appendTo( document.body )
11624              .addClass( o.className )
11625              .css({
11626                  top: startPosition.top - fixTop,
11627                  left: startPosition.left - fixLeft,
11628                  height: elem.innerHeight(),
11629                  width: elem.innerWidth(),
11630                  position: targetFixed ? "fixed" : "absolute"
11631              })
11632              .animate( animation, o.duration, o.easing, function() {
11633                  transfer.remove();
11634                  done();
11635              });
11636  };
11637  
11638  
11639  /*!
11640   * jQuery UI Progressbar 1.11.1
11641   * http://jqueryui.com
11642   *
11643   * Copyright 2014 jQuery Foundation and other contributors
11644   * Released under the MIT license.
11645   * http://jquery.org/license
11646   *
11647   * http://api.jqueryui.com/progressbar/
11648   */
11649  
11650  
11651  var progressbar = $.widget( "ui.progressbar", {
11652      version: "1.11.1",
11653      options: {
11654          max: 100,
11655          value: 0,
11656  
11657          change: null,
11658          complete: null
11659      },
11660  
11661      min: 0,
11662  
11663      _create: function() {
11664          // Constrain initial value
11665          this.oldValue = this.options.value = this._constrainedValue();
11666  
11667          this.element
11668              .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11669              .attr({
11670                  // Only set static values, aria-valuenow and aria-valuemax are
11671                  // set inside _refreshValue()
11672                  role: "progressbar",
11673                  "aria-valuemin": this.min
11674              });
11675  
11676          this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
11677              .appendTo( this.element );
11678  
11679          this._refreshValue();
11680      },
11681  
11682      _destroy: function() {
11683          this.element
11684              .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
11685              .removeAttr( "role" )
11686              .removeAttr( "aria-valuemin" )
11687              .removeAttr( "aria-valuemax" )
11688              .removeAttr( "aria-valuenow" );
11689  
11690          this.valueDiv.remove();
11691      },
11692  
11693      value: function( newValue ) {
11694          if ( newValue === undefined ) {
11695              return this.options.value;
11696          }
11697  
11698          this.options.value = this._constrainedValue( newValue );
11699          this._refreshValue();
11700      },
11701  
11702      _constrainedValue: function( newValue ) {
11703          if ( newValue === undefined ) {
11704              newValue = this.options.value;
11705          }
11706  
11707          this.indeterminate = newValue === false;
11708  
11709          // sanitize value
11710          if ( typeof newValue !== "number" ) {
11711              newValue = 0;
11712          }
11713  
11714          return this.indeterminate ? false :
11715              Math.min( this.options.max, Math.max( this.min, newValue ) );
11716      },
11717  
11718      _setOptions: function( options ) {
11719          // Ensure "value" option is set after other values (like max)
11720          var value = options.value;
11721          delete options.value;
11722  
11723          this._super( options );
11724  
11725          this.options.value = this._constrainedValue( value );
11726          this._refreshValue();
11727      },
11728  
11729      _setOption: function( key, value ) {
11730          if ( key === "max" ) {
11731              // Don't allow a max less than min
11732              value = Math.max( this.min, value );
11733          }
11734          if ( key === "disabled" ) {
11735              this.element
11736                  .toggleClass( "ui-state-disabled", !!value )
11737                  .attr( "aria-disabled", value );
11738          }
11739          this._super( key, value );
11740      },
11741  
11742      _percentage: function() {
11743          return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
11744      },
11745  
11746      _refreshValue: function() {
11747          var value = this.options.value,
11748              percentage = this._percentage();
11749  
11750          this.valueDiv
11751              .toggle( this.indeterminate || value > this.min )
11752              .toggleClass( "ui-corner-right", value === this.options.max )
11753              .width( percentage.toFixed(0) + "%" );
11754  
11755          this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
11756  
11757          if ( this.indeterminate ) {
11758              this.element.removeAttr( "aria-valuenow" );
11759              if ( !this.overlayDiv ) {
11760                  this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
11761              }
11762          } else {
11763              this.element.attr({
11764                  "aria-valuemax": this.options.max,
11765                  "aria-valuenow": value
11766              });
11767              if ( this.overlayDiv ) {
11768                  this.overlayDiv.remove();
11769                  this.overlayDiv = null;
11770              }
11771          }
11772  
11773          if ( this.oldValue !== value ) {
11774              this.oldValue = value;
11775              this._trigger( "change" );
11776          }
11777          if ( value === this.options.max ) {
11778              this._trigger( "complete" );
11779          }
11780      }
11781  });
11782  
11783  
11784  /*!
11785   * jQuery UI Selectable 1.11.1
11786   * http://jqueryui.com
11787   *
11788   * Copyright 2014 jQuery Foundation and other contributors
11789   * Released under the MIT license.
11790   * http://jquery.org/license
11791   *
11792   * http://api.jqueryui.com/selectable/
11793   */
11794  
11795  
11796  var selectable = $.widget("ui.selectable", $.ui.mouse, {
11797      version: "1.11.1",
11798      options: {
11799          appendTo: "body",
11800          autoRefresh: true,
11801          distance: 0,
11802          filter: "*",
11803          tolerance: "touch",
11804  
11805          // callbacks
11806          selected: null,
11807          selecting: null,
11808          start: null,
11809          stop: null,
11810          unselected: null,
11811          unselecting: null
11812      },
11813      _create: function() {
11814          var selectees,
11815              that = this;
11816  
11817          this.element.addClass("ui-selectable");
11818  
11819          this.dragged = false;
11820  
11821          // cache selectee children based on filter
11822          this.refresh = function() {
11823              selectees = $(that.options.filter, that.element[0]);
11824              selectees.addClass("ui-selectee");
11825              selectees.each(function() {
11826                  var $this = $(this),
11827                      pos = $this.offset();
11828                  $.data(this, "selectable-item", {
11829                      element: this,
11830                      $element: $this,
11831                      left: pos.left,
11832                      top: pos.top,
11833                      right: pos.left + $this.outerWidth(),
11834                      bottom: pos.top + $this.outerHeight(),
11835                      startselected: false,
11836                      selected: $this.hasClass("ui-selected"),
11837                      selecting: $this.hasClass("ui-selecting"),
11838                      unselecting: $this.hasClass("ui-unselecting")
11839                  });
11840              });
11841          };
11842          this.refresh();
11843  
11844          this.selectees = selectees.addClass("ui-selectee");
11845  
11846          this._mouseInit();
11847  
11848          this.helper = $("<div class='ui-selectable-helper'></div>");
11849      },
11850  
11851      _destroy: function() {
11852          this.selectees
11853              .removeClass("ui-selectee")
11854              .removeData("selectable-item");
11855          this.element
11856              .removeClass("ui-selectable ui-selectable-disabled");
11857          this._mouseDestroy();
11858      },
11859  
11860      _mouseStart: function(event) {
11861          var that = this,
11862              options = this.options;
11863  
11864          this.opos = [ event.pageX, event.pageY ];
11865  
11866          if (this.options.disabled) {
11867              return;
11868          }
11869  
11870          this.selectees = $(options.filter, this.element[0]);
11871  
11872          this._trigger("start", event);
11873  
11874          $(options.appendTo).append(this.helper);
11875          // position helper (lasso)
11876          this.helper.css({
11877              "left": event.pageX,
11878              "top": event.pageY,
11879              "width": 0,
11880              "height": 0
11881          });
11882  
11883          if (options.autoRefresh) {
11884              this.refresh();
11885          }
11886  
11887          this.selectees.filter(".ui-selected").each(function() {
11888              var selectee = $.data(this, "selectable-item");
11889              selectee.startselected = true;
11890              if (!event.metaKey && !event.ctrlKey) {
11891                  selectee.$element.removeClass("ui-selected");
11892                  selectee.selected = false;
11893                  selectee.$element.addClass("ui-unselecting");
11894                  selectee.unselecting = true;
11895                  // selectable UNSELECTING callback
11896                  that._trigger("unselecting", event, {
11897                      unselecting: selectee.element
11898                  });
11899              }
11900          });
11901  
11902          $(event.target).parents().addBack().each(function() {
11903              var doSelect,
11904                  selectee = $.data(this, "selectable-item");
11905              if (selectee) {
11906                  doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
11907                  selectee.$element
11908                      .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
11909                      .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
11910                  selectee.unselecting = !doSelect;
11911                  selectee.selecting = doSelect;
11912                  selectee.selected = doSelect;
11913                  // selectable (UN)SELECTING callback
11914                  if (doSelect) {
11915                      that._trigger("selecting", event, {
11916                          selecting: selectee.element
11917                      });
11918                  } else {
11919                      that._trigger("unselecting", event, {
11920                          unselecting: selectee.element
11921                      });
11922                  }
11923                  return false;
11924              }
11925          });
11926  
11927      },
11928  
11929      _mouseDrag: function(event) {
11930  
11931          this.dragged = true;
11932  
11933          if (this.options.disabled) {
11934              return;
11935          }
11936  
11937          var tmp,
11938              that = this,
11939              options = this.options,
11940              x1 = this.opos[0],
11941              y1 = this.opos[1],
11942              x2 = event.pageX,
11943              y2 = event.pageY;
11944  
11945          if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
11946          if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
11947          this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
11948  
11949          this.selectees.each(function() {
11950              var selectee = $.data(this, "selectable-item"),
11951                  hit = false;
11952  
11953              //prevent helper from being selected if appendTo: selectable
11954              if (!selectee || selectee.element === that.element[0]) {
11955                  return;
11956              }
11957  
11958              if (options.tolerance === "touch") {
11959                  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
11960              } else if (options.tolerance === "fit") {
11961                  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
11962              }
11963  
11964              if (hit) {
11965                  // SELECT
11966                  if (selectee.selected) {
11967                      selectee.$element.removeClass("ui-selected");
11968                      selectee.selected = false;
11969                  }
11970                  if (selectee.unselecting) {
11971                      selectee.$element.removeClass("ui-unselecting");
11972                      selectee.unselecting = false;
11973                  }
11974                  if (!selectee.selecting) {
11975                      selectee.$element.addClass("ui-selecting");
11976                      selectee.selecting = true;
11977                      // selectable SELECTING callback
11978                      that._trigger("selecting", event, {
11979                          selecting: selectee.element
11980                      });
11981                  }
11982              } else {
11983                  // UNSELECT
11984                  if (selectee.selecting) {
11985                      if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
11986                          selectee.$element.removeClass("ui-selecting");
11987                          selectee.selecting = false;
11988                          selectee.$element.addClass("ui-selected");
11989                          selectee.selected = true;
11990                      } else {
11991                          selectee.$element.removeClass("ui-selecting");
11992                          selectee.selecting = false;
11993                          if (selectee.startselected) {
11994                              selectee.$element.addClass("ui-unselecting");
11995                              selectee.unselecting = true;
11996                          }
11997                          // selectable UNSELECTING callback
11998                          that._trigger("unselecting", event, {
11999                              unselecting: selectee.element
12000                          });
12001                      }
12002                  }
12003                  if (selectee.selected) {
12004                      if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
12005                          selectee.$element.removeClass("ui-selected");
12006                          selectee.selected = false;
12007  
12008                          selectee.$element.addClass("ui-unselecting");
12009                          selectee.unselecting = true;
12010                          // selectable UNSELECTING callback
12011                          that._trigger("unselecting", event, {
12012                              unselecting: selectee.element
12013                          });
12014                      }
12015                  }
12016              }
12017          });
12018  
12019          return false;
12020      },
12021  
12022      _mouseStop: function(event) {
12023          var that = this;
12024  
12025          this.dragged = false;
12026  
12027          $(".ui-unselecting", this.element[0]).each(function() {
12028              var selectee = $.data(this, "selectable-item");
12029              selectee.$element.removeClass("ui-unselecting");
12030              selectee.unselecting = false;
12031              selectee.startselected = false;
12032              that._trigger("unselected", event, {
12033                  unselected: selectee.element
12034              });
12035          });
12036          $(".ui-selecting", this.element[0]).each(function() {
12037              var selectee = $.data(this, "selectable-item");
12038              selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
12039              selectee.selecting = false;
12040              selectee.selected = true;
12041              selectee.startselected = true;
12042              that._trigger("selected", event, {
12043                  selected: selectee.element
12044              });
12045          });
12046          this._trigger("stop", event);
12047  
12048          this.helper.remove();
12049  
12050          return false;
12051      }
12052  
12053  });
12054  
12055  
12056  /*!
12057   * jQuery UI Selectmenu 1.11.1
12058   * http://jqueryui.com
12059   *
12060   * Copyright 2014 jQuery Foundation and other contributors
12061   * Released under the MIT license.
12062   * http://jquery.org/license
12063   *
12064   * http://api.jqueryui.com/selectmenu
12065   */
12066  
12067  
12068  var selectmenu = $.widget( "ui.selectmenu", {
12069      version: "1.11.1",
12070      defaultElement: "<select>",
12071      options: {
12072          appendTo: null,
12073          disabled: null,
12074          icons: {
12075              button: "ui-icon-triangle-1-s"
12076          },
12077          position: {
12078              my: "left top",
12079              at: "left bottom",
12080              collision: "none"
12081          },
12082          width: null,
12083  
12084          // callbacks
12085          change: null,
12086          close: null,
12087          focus: null,
12088          open: null,
12089          select: null
12090      },
12091  
12092      _create: function() {
12093          var selectmenuId = this.element.uniqueId().attr( "id" );
12094          this.ids = {
12095              element: selectmenuId,
12096              button: selectmenuId + "-button",
12097              menu: selectmenuId + "-menu"
12098          };
12099  
12100          this._drawButton();
12101          this._drawMenu();
12102  
12103          if ( this.options.disabled ) {
12104              this.disable();
12105          }
12106      },
12107  
12108      _drawButton: function() {
12109          var that = this,
12110              tabindex = this.element.attr( "tabindex" );
12111  
12112          // Associate existing label with the new button
12113          this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
12114          this._on( this.label, {
12115              click: function( event ) {
12116                  this.button.focus();
12117                  event.preventDefault();
12118              }
12119          });
12120  
12121          // Hide original select element
12122          this.element.hide();
12123  
12124          // Create button
12125          this.button = $( "<span>", {
12126              "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
12127              tabindex: tabindex || this.options.disabled ? -1 : 0,
12128              id: this.ids.button,
12129              role: "combobox",
12130              "aria-expanded": "false",
12131              "aria-autocomplete": "list",
12132              "aria-owns": this.ids.menu,
12133              "aria-haspopup": "true"
12134          })
12135              .insertAfter( this.element );
12136  
12137          $( "<span>", {
12138              "class": "ui-icon " + this.options.icons.button
12139          })
12140              .prependTo( this.button );
12141  
12142          this.buttonText = $( "<span>", {
12143              "class": "ui-selectmenu-text"
12144          })
12145              .appendTo( this.button );
12146  
12147          this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
12148          this._resizeButton();
12149  
12150          this._on( this.button, this._buttonEvents );
12151          this.button.one( "focusin", function() {
12152  
12153              // Delay rendering the menu items until the button receives focus.
12154              // The menu may have already been rendered via a programmatic open.
12155              if ( !that.menuItems ) {
12156                  that._refreshMenu();
12157              }
12158          });
12159          this._hoverable( this.button );
12160          this._focusable( this.button );
12161      },
12162  
12163      _drawMenu: function() {
12164          var that = this;
12165  
12166          // Create menu
12167          this.menu = $( "<ul>", {
12168              "aria-hidden": "true",
12169              "aria-labelledby": this.ids.button,
12170              id: this.ids.menu
12171          });
12172  
12173          // Wrap menu
12174          this.menuWrap = $( "<div>", {
12175              "class": "ui-selectmenu-menu ui-front"
12176          })
12177              .append( this.menu )
12178              .appendTo( this._appendTo() );
12179  
12180          // Initialize menu widget
12181          this.menuInstance = this.menu
12182              .menu({
12183                  role: "listbox",
12184                  select: function( event, ui ) {
12185                      event.preventDefault();
12186                      that._select( ui.item.data( "ui-selectmenu-item" ), event );
12187                  },
12188                  focus: function( event, ui ) {
12189                      var item = ui.item.data( "ui-selectmenu-item" );
12190  
12191                      // Prevent inital focus from firing and check if its a newly focused item
12192                      if ( that.focusIndex != null && item.index !== that.focusIndex ) {
12193                          that._trigger( "focus", event, { item: item } );
12194                          if ( !that.isOpen ) {
12195                              that._select( item, event );
12196                          }
12197                      }
12198                      that.focusIndex = item.index;
12199  
12200                      that.button.attr( "aria-activedescendant",
12201                          that.menuItems.eq( item.index ).attr( "id" ) );
12202                  }
12203              })
12204              .menu( "instance" );
12205  
12206          // Adjust menu styles to dropdown
12207          this.menu
12208              .addClass( "ui-corner-bottom" )
12209              .removeClass( "ui-corner-all" );
12210  
12211          // Don't close the menu on mouseleave
12212          this.menuInstance._off( this.menu, "mouseleave" );
12213  
12214          // Cancel the menu's collapseAll on document click
12215          this.menuInstance._closeOnDocumentClick = function() {
12216              return false;
12217          };
12218  
12219          // Selects often contain empty items, but never contain dividers
12220          this.menuInstance._isDivider = function() {
12221              return false;
12222          };
12223      },
12224  
12225      refresh: function() {
12226          this._refreshMenu();
12227          this._setText( this.buttonText, this._getSelectedItem().text() );
12228          if ( !this.options.width ) {
12229              this._resizeButton();
12230          }
12231      },
12232  
12233      _refreshMenu: function() {
12234          this.menu.empty();
12235  
12236          var item,
12237              options = this.element.find( "option" );
12238  
12239          if ( !options.length ) {
12240              return;
12241          }
12242  
12243          this._parseOptions( options );
12244          this._renderMenu( this.menu, this.items );
12245  
12246          this.menuInstance.refresh();
12247          this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
12248  
12249          item = this._getSelectedItem();
12250  
12251          // Update the menu to have the correct item focused
12252          this.menuInstance.focus( null, item );
12253          this._setAria( item.data( "ui-selectmenu-item" ) );
12254  
12255          // Set disabled state
12256          this._setOption( "disabled", this.element.prop( "disabled" ) );
12257      },
12258  
12259      open: function( event ) {
12260          if ( this.options.disabled ) {
12261              return;
12262          }
12263  
12264          // If this is the first time the menu is being opened, render the items
12265          if ( !this.menuItems ) {
12266              this._refreshMenu();
12267          } else {
12268  
12269              // Menu clears focus on close, reset focus to selected item
12270              this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
12271              this.menuInstance.focus( null, this._getSelectedItem() );
12272          }
12273  
12274          this.isOpen = true;
12275          this._toggleAttr();
12276          this._resizeMenu();
12277          this._position();
12278  
12279          this._on( this.document, this._documentClick );
12280  
12281          this._trigger( "open", event );
12282      },
12283  
12284      _position: function() {
12285          this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
12286      },
12287  
12288      close: function( event ) {
12289          if ( !this.isOpen ) {
12290              return;
12291          }
12292  
12293          this.isOpen = false;
12294          this._toggleAttr();
12295  
12296          this._off( this.document );
12297  
12298          this._trigger( "close", event );
12299      },
12300  
12301      widget: function() {
12302          return this.button;
12303      },
12304  
12305      menuWidget: function() {
12306          return this.menu;
12307      },
12308  
12309      _renderMenu: function( ul, items ) {
12310          var that = this,
12311              currentOptgroup = "";
12312  
12313          $.each( items, function( index, item ) {
12314              if ( item.optgroup !== currentOptgroup ) {
12315                  $( "<li>", {
12316                      "class": "ui-selectmenu-optgroup ui-menu-divider" +
12317                          ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
12318                              " ui-state-disabled" :
12319                              "" ),
12320                      text: item.optgroup
12321                  })
12322                      .appendTo( ul );
12323  
12324                  currentOptgroup = item.optgroup;
12325              }
12326  
12327              that._renderItemData( ul, item );
12328          });
12329      },
12330  
12331      _renderItemData: function( ul, item ) {
12332          return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
12333      },
12334  
12335      _renderItem: function( ul, item ) {
12336          var li = $( "<li>" );
12337  
12338          if ( item.disabled ) {
12339              li.addClass( "ui-state-disabled" );
12340          }
12341          this._setText( li, item.label );
12342  
12343          return li.appendTo( ul );
12344      },
12345  
12346      _setText: function( element, value ) {
12347          if ( value ) {
12348              element.text( value );
12349          } else {
12350              element.html( "&#160;" );
12351          }
12352      },
12353  
12354      _move: function( direction, event ) {
12355          var item, next,
12356              filter = ".ui-menu-item";
12357  
12358          if ( this.isOpen ) {
12359              item = this.menuItems.eq( this.focusIndex );
12360          } else {
12361              item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
12362              filter += ":not(.ui-state-disabled)";
12363          }
12364  
12365          if ( direction === "first" || direction === "last" ) {
12366              next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
12367          } else {
12368              next = item[ direction + "All" ]( filter ).eq( 0 );
12369          }
12370  
12371          if ( next.length ) {
12372              this.menuInstance.focus( event, next );
12373          }
12374      },
12375  
12376      _getSelectedItem: function() {
12377          return this.menuItems.eq( this.element[ 0 ].selectedIndex );
12378      },
12379  
12380      _toggle: function( event ) {
12381          this[ this.isOpen ? "close" : "open" ]( event );
12382      },
12383  
12384      _documentClick: {
12385          mousedown: function( event ) {
12386              if ( !this.isOpen ) {
12387                  return;
12388              }
12389  
12390              if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
12391                  this.close( event );
12392              }
12393          }
12394      },
12395  
12396      _buttonEvents: {
12397  
12398          // Prevent text selection from being reset when interacting with the selectmenu (#10144)
12399          mousedown: function( event ) {
12400              event.preventDefault();
12401          },
12402  
12403          click: "_toggle",
12404  
12405          keydown: function( event ) {
12406              var preventDefault = true;
12407              switch ( event.keyCode ) {
12408                  case $.ui.keyCode.TAB:
12409                  case $.ui.keyCode.ESCAPE:
12410                      this.close( event );
12411                      preventDefault = false;
12412                      break;
12413                  case $.ui.keyCode.ENTER:
12414                      if ( this.isOpen ) {
12415                          this._selectFocusedItem( event );
12416                      }
12417                      break;
12418                  case $.ui.keyCode.UP:
12419                      if ( event.altKey ) {
12420                          this._toggle( event );
12421                      } else {
12422                          this._move( "prev", event );
12423                      }
12424                      break;
12425                  case $.ui.keyCode.DOWN:
12426                      if ( event.altKey ) {
12427                          this._toggle( event );
12428                      } else {
12429                          this._move( "next", event );
12430                      }
12431                      break;
12432                  case $.ui.keyCode.SPACE:
12433                      if ( this.isOpen ) {
12434                          this._selectFocusedItem( event );
12435                      } else {
12436                          this._toggle( event );
12437                      }
12438                      break;
12439                  case $.ui.keyCode.LEFT:
12440                      this._move( "prev", event );
12441                      break;
12442                  case $.ui.keyCode.RIGHT:
12443                      this._move( "next", event );
12444                      break;
12445                  case $.ui.keyCode.HOME:
12446                  case $.ui.keyCode.PAGE_UP:
12447                      this._move( "first", event );
12448                      break;
12449                  case $.ui.keyCode.END:
12450                  case $.ui.keyCode.PAGE_DOWN:
12451                      this._move( "last", event );
12452                      break;
12453                  default:
12454                      this.menu.trigger( event );
12455                      preventDefault = false;
12456              }
12457  
12458              if ( preventDefault ) {
12459                  event.preventDefault();
12460              }
12461          }
12462      },
12463  
12464      _selectFocusedItem: function( event ) {
12465          var item = this.menuItems.eq( this.focusIndex );
12466          if ( !item.hasClass( "ui-state-disabled" ) ) {
12467              this._select( item.data( "ui-selectmenu-item" ), event );
12468          }
12469      },
12470  
12471      _select: function( item, event ) {
12472          var oldIndex = this.element[ 0 ].selectedIndex;
12473  
12474          // Change native select element
12475          this.element[ 0 ].selectedIndex = item.index;
12476          this._setText( this.buttonText, item.label );
12477          this._setAria( item );
12478          this._trigger( "select", event, { item: item } );
12479  
12480          if ( item.index !== oldIndex ) {
12481              this._trigger( "change", event, { item: item } );
12482          }
12483  
12484          this.close( event );
12485      },
12486  
12487      _setAria: function( item ) {
12488          var id = this.menuItems.eq( item.index ).attr( "id" );
12489  
12490          this.button.attr({
12491              "aria-labelledby": id,
12492              "aria-activedescendant": id
12493          });
12494          this.menu.attr( "aria-activedescendant", id );
12495      },
12496  
12497      _setOption: function( key, value ) {
12498          if ( key === "icons" ) {
12499              this.button.find( "span.ui-icon" )
12500                  .removeClass( this.options.icons.button )
12501                  .addClass( value.button );
12502          }
12503  
12504          this._super( key, value );
12505  
12506          if ( key === "appendTo" ) {
12507              this.menuWrap.appendTo( this._appendTo() );
12508          }
12509  
12510          if ( key === "disabled" ) {
12511              this.menuInstance.option( "disabled", value );
12512              this.button
12513                  .toggleClass( "ui-state-disabled", value )
12514                  .attr( "aria-disabled", value );
12515  
12516              this.element.prop( "disabled", value );
12517              if ( value ) {
12518                  this.button.attr( "tabindex", -1 );
12519                  this.close();
12520              } else {
12521                  this.button.attr( "tabindex", 0 );
12522              }
12523          }
12524  
12525          if ( key === "width" ) {
12526              this._resizeButton();
12527          }
12528      },
12529  
12530      _appendTo: function() {
12531          var element = this.options.appendTo;
12532  
12533          if ( element ) {
12534              element = element.jquery || element.nodeType ?
12535                  $( element ) :
12536                  this.document.find( element ).eq( 0 );
12537          }
12538  
12539          if ( !element || !element[ 0 ] ) {
12540              element = this.element.closest( ".ui-front" );
12541          }
12542  
12543          if ( !element.length ) {
12544              element = this.document[ 0 ].body;
12545          }
12546  
12547          return element;
12548      },
12549  
12550      _toggleAttr: function() {
12551          this.button
12552              .toggleClass( "ui-corner-top", this.isOpen )
12553              .toggleClass( "ui-corner-all", !this.isOpen )
12554              .attr( "aria-expanded", this.isOpen );
12555          this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
12556          this.menu.attr( "aria-hidden", !this.isOpen );
12557      },
12558  
12559      _resizeButton: function() {
12560          var width = this.options.width;
12561  
12562          if ( !width ) {
12563              width = this.element.show().outerWidth();
12564              this.element.hide();
12565          }
12566  
12567          this.button.outerWidth( width );
12568      },
12569  
12570      _resizeMenu: function() {
12571          this.menu.outerWidth( Math.max(
12572              this.button.outerWidth(),
12573  
12574              // support: IE10
12575              // IE10 wraps long text (possibly a rounding bug)
12576              // so we add 1px to avoid the wrapping
12577              this.menu.width( "" ).outerWidth() + 1
12578          ) );
12579      },
12580  
12581      _getCreateOptions: function() {
12582          return { disabled: this.element.prop( "disabled" ) };
12583      },
12584  
12585      _parseOptions: function( options ) {
12586          var data = [];
12587          options.each(function( index, item ) {
12588              var option = $( item ),
12589                  optgroup = option.parent( "optgroup" );
12590              data.push({
12591                  element: option,
12592                  index: index,
12593                  value: option.attr( "value" ),
12594                  label: option.text(),
12595                  optgroup: optgroup.attr( "label" ) || "",
12596                  disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
12597              });
12598          });
12599          this.items = data;
12600      },
12601  
12602      _destroy: function() {
12603          this.menuWrap.remove();
12604          this.button.remove();
12605          this.element.show();
12606          this.element.removeUniqueId();
12607          this.label.attr( "for", this.ids.element );
12608      }
12609  });
12610  
12611  
12612  /*!
12613   * jQuery UI Slider 1.11.1
12614   * http://jqueryui.com
12615   *
12616   * Copyright 2014 jQuery Foundation and other contributors
12617   * Released under the MIT license.
12618   * http://jquery.org/license
12619   *
12620   * http://api.jqueryui.com/slider/
12621   */
12622  
12623  
12624  var slider = $.widget( "ui.slider", $.ui.mouse, {
12625      version: "1.11.1",
12626      widgetEventPrefix: "slide",
12627  
12628      options: {
12629          animate: false,
12630          distance: 0,
12631          max: 100,
12632          min: 0,
12633          orientation: "horizontal",
12634          range: false,
12635          step: 1,
12636          value: 0,
12637          values: null,
12638  
12639          // callbacks
12640          change: null,
12641          slide: null,
12642          start: null,
12643          stop: null
12644      },
12645  
12646      // number of pages in a slider
12647      // (how many times can you page up/down to go through the whole range)
12648      numPages: 5,
12649  
12650      _create: function() {
12651          this._keySliding = false;
12652          this._mouseSliding = false;
12653          this._animateOff = true;
12654          this._handleIndex = null;
12655          this._detectOrientation();
12656          this._mouseInit();
12657  
12658          this.element
12659              .addClass( "ui-slider" +
12660                  " ui-slider-" + this.orientation +
12661                  " ui-widget" +
12662                  " ui-widget-content" +
12663                  " ui-corner-all");
12664  
12665          this._refresh();
12666          this._setOption( "disabled", this.options.disabled );
12667  
12668          this._animateOff = false;
12669      },
12670  
12671      _refresh: function() {
12672          this._createRange();
12673          this._createHandles();
12674          this._setupEvents();
12675          this._refreshValue();
12676      },
12677  
12678      _createHandles: function() {
12679          var i, handleCount,
12680              options = this.options,
12681              existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12682              handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
12683              handles = [];
12684  
12685          handleCount = ( options.values && options.values.length ) || 1;
12686  
12687          if ( existingHandles.length > handleCount ) {
12688              existingHandles.slice( handleCount ).remove();
12689              existingHandles = existingHandles.slice( 0, handleCount );
12690          }
12691  
12692          for ( i = existingHandles.length; i < handleCount; i++ ) {
12693              handles.push( handle );
12694          }
12695  
12696          this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12697  
12698          this.handle = this.handles.eq( 0 );
12699  
12700          this.handles.each(function( i ) {
12701              $( this ).data( "ui-slider-handle-index", i );
12702          });
12703      },
12704  
12705      _createRange: function() {
12706          var options = this.options,
12707              classes = "";
12708  
12709          if ( options.range ) {
12710              if ( options.range === true ) {
12711                  if ( !options.values ) {
12712                      options.values = [ this._valueMin(), this._valueMin() ];
12713                  } else if ( options.values.length && options.values.length !== 2 ) {
12714                      options.values = [ options.values[0], options.values[0] ];
12715                  } else if ( $.isArray( options.values ) ) {
12716                      options.values = options.values.slice(0);
12717                  }
12718              }
12719  
12720              if ( !this.range || !this.range.length ) {
12721                  this.range = $( "<div></div>" )
12722                      .appendTo( this.element );
12723  
12724                  classes = "ui-slider-range" +
12725                  // note: this isn't the most fittingly semantic framework class for this element,
12726                  // but worked best visually with a variety of themes
12727                  " ui-widget-header ui-corner-all";
12728              } else {
12729                  this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12730                      // Handle range switching from true to min/max
12731                      .css({
12732                          "left": "",
12733                          "bottom": ""
12734                      });
12735              }
12736  
12737              this.range.addClass( classes +
12738                  ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12739          } else {
12740              if ( this.range ) {
12741                  this.range.remove();
12742              }
12743              this.range = null;
12744          }
12745      },
12746  
12747      _setupEvents: function() {
12748          this._off( this.handles );
12749          this._on( this.handles, this._handleEvents );
12750          this._hoverable( this.handles );
12751          this._focusable( this.handles );
12752      },
12753  
12754      _destroy: function() {
12755          this.handles.remove();
12756          if ( this.range ) {
12757              this.range.remove();
12758          }
12759  
12760          this.element
12761              .removeClass( "ui-slider" +
12762                  " ui-slider-horizontal" +
12763                  " ui-slider-vertical" +
12764                  " ui-widget" +
12765                  " ui-widget-content" +
12766                  " ui-corner-all" );
12767  
12768          this._mouseDestroy();
12769      },
12770  
12771      _mouseCapture: function( event ) {
12772          var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12773              that = this,
12774              o = this.options;
12775  
12776          if ( o.disabled ) {
12777              return false;
12778          }
12779  
12780          this.elementSize = {
12781              width: this.element.outerWidth(),
12782              height: this.element.outerHeight()
12783          };
12784          this.elementOffset = this.element.offset();
12785  
12786          position = { x: event.pageX, y: event.pageY };
12787          normValue = this._normValueFromMouse( position );
12788          distance = this._valueMax() - this._valueMin() + 1;
12789          this.handles.each(function( i ) {
12790              var thisDistance = Math.abs( normValue - that.values(i) );
12791              if (( distance > thisDistance ) ||
12792                  ( distance === thisDistance &&
12793                      (i === that._lastChangedValue || that.values(i) === o.min ))) {
12794                  distance = thisDistance;
12795                  closestHandle = $( this );
12796                  index = i;
12797              }
12798          });
12799  
12800          allowed = this._start( event, index );
12801          if ( allowed === false ) {
12802              return false;
12803          }
12804          this._mouseSliding = true;
12805  
12806          this._handleIndex = index;
12807  
12808          closestHandle
12809              .addClass( "ui-state-active" )
12810              .focus();
12811  
12812          offset = closestHandle.offset();
12813          mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12814          this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12815              left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12816              top: event.pageY - offset.top -
12817                  ( closestHandle.height() / 2 ) -
12818                  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12819                  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12820                  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12821          };
12822  
12823          if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12824              this._slide( event, index, normValue );
12825          }
12826          this._animateOff = true;
12827          return true;
12828      },
12829  
12830      _mouseStart: function() {
12831          return true;
12832      },
12833  
12834      _mouseDrag: function( event ) {
12835          var position = { x: event.pageX, y: event.pageY },
12836              normValue = this._normValueFromMouse( position );
12837  
12838          this._slide( event, this._handleIndex, normValue );
12839  
12840          return false;
12841      },
12842  
12843      _mouseStop: function( event ) {
12844          this.handles.removeClass( "ui-state-active" );
12845          this._mouseSliding = false;
12846  
12847          this._stop( event, this._handleIndex );
12848          this._change( event, this._handleIndex );
12849  
12850          this._handleIndex = null;
12851          this._clickOffset = null;
12852          this._animateOff = false;
12853  
12854          return false;
12855      },
12856  
12857      _detectOrientation: function() {
12858          this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12859      },
12860  
12861      _normValueFromMouse: function( position ) {
12862          var pixelTotal,
12863              pixelMouse,
12864              percentMouse,
12865              valueTotal,
12866              valueMouse;
12867  
12868          if ( this.orientation === "horizontal" ) {
12869              pixelTotal = this.elementSize.width;
12870              pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12871          } else {
12872              pixelTotal = this.elementSize.height;
12873              pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12874          }
12875  
12876          percentMouse = ( pixelMouse / pixelTotal );
12877          if ( percentMouse > 1 ) {
12878              percentMouse = 1;
12879          }
12880          if ( percentMouse < 0 ) {
12881              percentMouse = 0;
12882          }
12883          if ( this.orientation === "vertical" ) {
12884              percentMouse = 1 - percentMouse;
12885          }
12886  
12887          valueTotal = this._valueMax() - this._valueMin();
12888          valueMouse = this._valueMin() + percentMouse * valueTotal;
12889  
12890          return this._trimAlignValue( valueMouse );
12891      },
12892  
12893      _start: function( event, index ) {
12894          var uiHash = {
12895              handle: this.handles[ index ],
12896              value: this.value()
12897          };
12898          if ( this.options.values && this.options.values.length ) {
12899              uiHash.value = this.values( index );
12900              uiHash.values = this.values();
12901          }
12902          return this._trigger( "start", event, uiHash );
12903      },
12904  
12905      _slide: function( event, index, newVal ) {
12906          var otherVal,
12907              newValues,
12908              allowed;
12909  
12910          if ( this.options.values && this.options.values.length ) {
12911              otherVal = this.values( index ? 0 : 1 );
12912  
12913              if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12914                      ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12915                  ) {
12916                  newVal = otherVal;
12917              }
12918  
12919              if ( newVal !== this.values( index ) ) {
12920                  newValues = this.values();
12921                  newValues[ index ] = newVal;
12922                  // A slide can be canceled by returning false from the slide callback
12923                  allowed = this._trigger( "slide", event, {
12924                      handle: this.handles[ index ],
12925                      value: newVal,
12926                      values: newValues
12927                  } );
12928                  otherVal = this.values( index ? 0 : 1 );
12929                  if ( allowed !== false ) {
12930                      this.values( index, newVal );
12931                  }
12932              }
12933          } else {
12934              if ( newVal !== this.value() ) {
12935                  // A slide can be canceled by returning false from the slide callback
12936                  allowed = this._trigger( "slide", event, {
12937                      handle: this.handles[ index ],
12938                      value: newVal
12939                  } );
12940                  if ( allowed !== false ) {
12941                      this.value( newVal );
12942                  }
12943              }
12944          }
12945      },
12946  
12947      _stop: function( event, index ) {
12948          var uiHash = {
12949              handle: this.handles[ index ],
12950              value: this.value()
12951          };
12952          if ( this.options.values && this.options.values.length ) {
12953              uiHash.value = this.values( index );
12954              uiHash.values = this.values();
12955          }
12956  
12957          this._trigger( "stop", event, uiHash );
12958      },
12959  
12960      _change: function( event, index ) {
12961          if ( !this._keySliding && !this._mouseSliding ) {
12962              var uiHash = {
12963                  handle: this.handles[ index ],
12964                  value: this.value()
12965              };
12966              if ( this.options.values && this.options.values.length ) {
12967                  uiHash.value = this.values( index );
12968                  uiHash.values = this.values();
12969              }
12970  
12971              //store the last changed value index for reference when handles overlap
12972              this._lastChangedValue = index;
12973  
12974              this._trigger( "change", event, uiHash );
12975          }
12976      },
12977  
12978      value: function( newValue ) {
12979          if ( arguments.length ) {
12980              this.options.value = this._trimAlignValue( newValue );
12981              this._refreshValue();
12982              this._change( null, 0 );
12983              return;
12984          }
12985  
12986          return this._value();
12987      },
12988  
12989      values: function( index, newValue ) {
12990          var vals,
12991              newValues,
12992              i;
12993  
12994          if ( arguments.length > 1 ) {
12995              this.options.values[ index ] = this._trimAlignValue( newValue );
12996              this._refreshValue();
12997              this._change( null, index );
12998              return;
12999          }
13000  
13001          if ( arguments.length ) {
13002              if ( $.isArray( arguments[ 0 ] ) ) {
13003                  vals = this.options.values;
13004                  newValues = arguments[ 0 ];
13005                  for ( i = 0; i < vals.length; i += 1 ) {
13006                      vals[ i ] = this._trimAlignValue( newValues[ i ] );
13007                      this._change( null, i );
13008                  }
13009                  this._refreshValue();
13010              } else {
13011                  if ( this.options.values && this.options.values.length ) {
13012                      return this._values( index );
13013                  } else {
13014                      return this.value();
13015                  }
13016              }
13017          } else {
13018              return this._values();
13019          }
13020      },
13021  
13022      _setOption: function( key, value ) {
13023          var i,
13024              valsLength = 0;
13025  
13026          if ( key === "range" && this.options.range === true ) {
13027              if ( value === "min" ) {
13028                  this.options.value = this._values( 0 );
13029                  this.options.values = null;
13030              } else if ( value === "max" ) {
13031                  this.options.value = this._values( this.options.values.length - 1 );
13032                  this.options.values = null;
13033              }
13034          }
13035  
13036          if ( $.isArray( this.options.values ) ) {
13037              valsLength = this.options.values.length;
13038          }
13039  
13040          if ( key === "disabled" ) {
13041              this.element.toggleClass( "ui-state-disabled", !!value );
13042          }
13043  
13044          this._super( key, value );
13045  
13046          switch ( key ) {
13047              case "orientation":
13048                  this._detectOrientation();
13049                  this.element
13050                      .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13051                      .addClass( "ui-slider-" + this.orientation );
13052                  this._refreshValue();
13053  
13054                  // Reset positioning from previous orientation
13055                  this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
13056                  break;
13057              case "value":
13058                  this._animateOff = true;
13059                  this._refreshValue();
13060                  this._change( null, 0 );
13061                  this._animateOff = false;
13062                  break;
13063              case "values":
13064                  this._animateOff = true;
13065                  this._refreshValue();
13066                  for ( i = 0; i < valsLength; i += 1 ) {
13067                      this._change( null, i );
13068                  }
13069                  this._animateOff = false;
13070                  break;
13071              case "min":
13072              case "max":
13073                  this._animateOff = true;
13074                  this._refreshValue();
13075                  this._animateOff = false;
13076                  break;
13077              case "range":
13078                  this._animateOff = true;
13079                  this._refresh();
13080                  this._animateOff = false;
13081                  break;
13082          }
13083      },
13084  
13085      //internal value getter
13086      // _value() returns value trimmed by min and max, aligned by step
13087      _value: function() {
13088          var val = this.options.value;
13089          val = this._trimAlignValue( val );
13090  
13091          return val;
13092      },
13093  
13094      //internal values getter
13095      // _values() returns array of values trimmed by min and max, aligned by step
13096      // _values( index ) returns single value trimmed by min and max, aligned by step
13097      _values: function( index ) {
13098          var val,
13099              vals,
13100              i;
13101  
13102          if ( arguments.length ) {
13103              val = this.options.values[ index ];
13104              val = this._trimAlignValue( val );
13105  
13106              return val;
13107          } else if ( this.options.values && this.options.values.length ) {
13108              // .slice() creates a copy of the array
13109              // this copy gets trimmed by min and max and then returned
13110              vals = this.options.values.slice();
13111              for ( i = 0; i < vals.length; i+= 1) {
13112                  vals[ i ] = this._trimAlignValue( vals[ i ] );
13113              }
13114  
13115              return vals;
13116          } else {
13117              return [];
13118          }
13119      },
13120  
13121      // returns the step-aligned value that val is closest to, between (inclusive) min and max
13122      _trimAlignValue: function( val ) {
13123          if ( val <= this._valueMin() ) {
13124              return this._valueMin();
13125          }
13126          if ( val >= this._valueMax() ) {
13127              return this._valueMax();
13128          }
13129          var step = ( this.options.step > 0 ) ? this.options.step : 1,
13130              valModStep = (val - this._valueMin()) % step,
13131              alignValue = val - valModStep;
13132  
13133          if ( Math.abs(valModStep) * 2 >= step ) {
13134              alignValue += ( valModStep > 0 ) ? step : ( -step );
13135          }
13136  
13137          // Since JavaScript has problems with large floats, round
13138          // the final value to 5 digits after the decimal point (see #4124)
13139          return parseFloat( alignValue.toFixed(5) );
13140      },
13141  
13142      _valueMin: function() {
13143          return this.options.min;
13144      },
13145  
13146      _valueMax: function() {
13147          return this.options.max;
13148      },
13149  
13150      _refreshValue: function() {
13151          var lastValPercent, valPercent, value, valueMin, valueMax,
13152              oRange = this.options.range,
13153              o = this.options,
13154              that = this,
13155              animate = ( !this._animateOff ) ? o.animate : false,
13156              _set = {};
13157  
13158          if ( this.options.values && this.options.values.length ) {
13159              this.handles.each(function( i ) {
13160                  valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13161                  _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13162                  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13163                  if ( that.options.range === true ) {
13164                      if ( that.orientation === "horizontal" ) {
13165                          if ( i === 0 ) {
13166                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13167                          }
13168                          if ( i === 1 ) {
13169                              that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13170                          }
13171                      } else {
13172                          if ( i === 0 ) {
13173                              that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13174                          }
13175                          if ( i === 1 ) {
13176                              that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13177                          }
13178                      }
13179                  }
13180                  lastValPercent = valPercent;
13181              });
13182          } else {
13183              value = this.value();
13184              valueMin = this._valueMin();
13185              valueMax = this._valueMax();
13186              valPercent = ( valueMax !== valueMin ) ?
13187                      ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13188                      0;
13189              _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13190              this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13191  
13192              if ( oRange === "min" && this.orientation === "horizontal" ) {
13193                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13194              }
13195              if ( oRange === "max" && this.orientation === "horizontal" ) {
13196                  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13197              }
13198              if ( oRange === "min" && this.orientation === "vertical" ) {
13199                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13200              }
13201              if ( oRange === "max" && this.orientation === "vertical" ) {
13202                  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13203              }
13204          }
13205      },
13206  
13207      _handleEvents: {
13208          keydown: function( event ) {
13209              var allowed, curVal, newVal, step,
13210                  index = $( event.target ).data( "ui-slider-handle-index" );
13211  
13212              switch ( event.keyCode ) {
13213                  case $.ui.keyCode.HOME:
13214                  case $.ui.keyCode.END:
13215                  case $.ui.keyCode.PAGE_UP:
13216                  case $.ui.keyCode.PAGE_DOWN:
13217                  case $.ui.keyCode.UP:
13218                  case $.ui.keyCode.RIGHT:
13219                  case $.ui.keyCode.DOWN:
13220                  case $.ui.keyCode.LEFT:
13221                      event.preventDefault();
13222                      if ( !this._keySliding ) {
13223                          this._keySliding = true;
13224                          $( event.target ).addClass( "ui-state-active" );
13225                          allowed = this._start( event, index );
13226                          if ( allowed === false ) {
13227                              return;
13228                          }
13229                      }
13230                      break;
13231              }
13232  
13233              step = this.options.step;
13234              if ( this.options.values && this.options.values.length ) {
13235                  curVal = newVal = this.values( index );
13236              } else {
13237                  curVal = newVal = this.value();
13238              }
13239  
13240              switch ( event.keyCode ) {
13241                  case $.ui.keyCode.HOME:
13242                      newVal = this._valueMin();
13243                      break;
13244                  case $.ui.keyCode.END:
13245                      newVal = this._valueMax();
13246                      break;
13247                  case $.ui.keyCode.PAGE_UP:
13248                      newVal = this._trimAlignValue(
13249                          curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
13250                      );
13251                      break;
13252                  case $.ui.keyCode.PAGE_DOWN:
13253                      newVal = this._trimAlignValue(
13254                          curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
13255                      break;
13256                  case $.ui.keyCode.UP:
13257                  case $.ui.keyCode.RIGHT:
13258                      if ( curVal === this._valueMax() ) {
13259                          return;
13260                      }
13261                      newVal = this._trimAlignValue( curVal + step );
13262                      break;
13263                  case $.ui.keyCode.DOWN:
13264                  case $.ui.keyCode.LEFT:
13265                      if ( curVal === this._valueMin() ) {
13266                          return;
13267                      }
13268                      newVal = this._trimAlignValue( curVal - step );
13269                      break;
13270              }
13271  
13272              this._slide( event, index, newVal );
13273          },
13274          keyup: function( event ) {
13275              var index = $( event.target ).data( "ui-slider-handle-index" );
13276  
13277              if ( this._keySliding ) {
13278                  this._keySliding = false;
13279                  this._stop( event, index );
13280                  this._change( event, index );
13281                  $( event.target ).removeClass( "ui-state-active" );
13282              }
13283          }
13284      }
13285  });
13286  
13287  
13288  /*!
13289   * jQuery UI Sortable 1.11.1
13290   * http://jqueryui.com
13291   *
13292   * Copyright 2014 jQuery Foundation and other contributors
13293   * Released under the MIT license.
13294   * http://jquery.org/license
13295   *
13296   * http://api.jqueryui.com/sortable/
13297   */
13298  
13299  
13300  var sortable = $.widget("ui.sortable", $.ui.mouse, {
13301      version: "1.11.1",
13302      widgetEventPrefix: "sort",
13303      ready: false,
13304      options: {
13305          appendTo: "parent",
13306          axis: false,
13307          connectWith: false,
13308          containment: false,
13309          cursor: "auto",
13310          cursorAt: false,
13311          dropOnEmpty: true,
13312          forcePlaceholderSize: false,
13313          forceHelperSize: false,
13314          grid: false,
13315          handle: false,
13316          helper: "original",
13317          items: "> *",
13318          opacity: false,
13319          placeholder: false,
13320          revert: false,
13321          scroll: true,
13322          scrollSensitivity: 20,
13323          scrollSpeed: 20,
13324          scope: "default",
13325          tolerance: "intersect",
13326          zIndex: 1000,
13327  
13328          // callbacks
13329          activate: null,
13330          beforeStop: null,
13331          change: null,
13332          deactivate: null,
13333          out: null,
13334          over: null,
13335          receive: null,
13336          remove: null,
13337          sort: null,
13338          start: null,
13339          stop: null,
13340          update: null
13341      },
13342  
13343      _isOverAxis: function( x, reference, size ) {
13344          return ( x >= reference ) && ( x < ( reference + size ) );
13345      },
13346  
13347      _isFloating: function( item ) {
13348          return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
13349      },
13350  
13351      _create: function() {
13352  
13353          var o = this.options;
13354          this.containerCache = {};
13355          this.element.addClass("ui-sortable");
13356  
13357          //Get the items
13358          this.refresh();
13359  
13360          //Let's determine if the items are being displayed horizontally
13361          this.floating = this.items.length ? o.axis === "x" || this._isFloating(this.items[0].item) : false;
13362  
13363          //Let's determine the parent's offset
13364          this.offset = this.element.offset();
13365  
13366          //Initialize mouse events for interaction
13367          this._mouseInit();
13368  
13369          this._setHandleClassName();
13370  
13371          //We're ready to go
13372          this.ready = true;
13373  
13374      },
13375  
13376      _setOption: function( key, value ) {
13377          this._super( key, value );
13378  
13379          if ( key === "handle" ) {
13380              this._setHandleClassName();
13381          }
13382      },
13383  
13384      _setHandleClassName: function() {
13385          this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
13386          $.each( this.items, function() {
13387              ( this.instance.options.handle ?
13388                  this.item.find( this.instance.options.handle ) : this.item )
13389                  .addClass( "ui-sortable-handle" );
13390          });
13391      },
13392  
13393      _destroy: function() {
13394          this.element
13395              .removeClass( "ui-sortable ui-sortable-disabled" )
13396              .find( ".ui-sortable-handle" )
13397                  .removeClass( "ui-sortable-handle" );
13398          this._mouseDestroy();
13399  
13400          for ( var i = this.items.length - 1; i >= 0; i-- ) {
13401              this.items[i].item.removeData(this.widgetName + "-item");
13402          }
13403  
13404          return this;
13405      },
13406  
13407      _mouseCapture: function(event, overrideHandle) {
13408          var currentItem = null,
13409              validHandle = false,
13410              that = this;
13411  
13412          if (this.reverting) {
13413              return false;
13414          }
13415  
13416          if(this.options.disabled || this.options.type === "static") {
13417              return false;
13418          }
13419  
13420          //We have to refresh the items data once first
13421          this._refreshItems(event);
13422  
13423          //Find out if the clicked node (or one of its parents) is a actual item in this.items
13424          $(event.target).parents().each(function() {
13425              if($.data(this, that.widgetName + "-item") === that) {
13426                  currentItem = $(this);
13427                  return false;
13428              }
13429          });
13430          if($.data(event.target, that.widgetName + "-item") === that) {
13431              currentItem = $(event.target);
13432          }
13433  
13434          if(!currentItem) {
13435              return false;
13436          }
13437          if(this.options.handle && !overrideHandle) {
13438              $(this.options.handle, currentItem).find("*").addBack().each(function() {
13439                  if(this === event.target) {
13440                      validHandle = true;
13441                  }
13442              });
13443              if(!validHandle) {
13444                  return false;
13445              }
13446          }
13447  
13448          this.currentItem = currentItem;
13449          this._removeCurrentsFromItems();
13450          return true;
13451  
13452      },
13453  
13454      _mouseStart: function(event, overrideHandle, noActivation) {
13455  
13456          var i, body,
13457              o = this.options;
13458  
13459          this.currentContainer = this;
13460  
13461          //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
13462          this.refreshPositions();
13463  
13464          //Create and append the visible helper
13465          this.helper = this._createHelper(event);
13466  
13467          //Cache the helper size
13468          this._cacheHelperProportions();
13469  
13470          /*
13471           * - Position generation -
13472           * This block generates everything position related - it's the core of draggables.
13473           */
13474  
13475          //Cache the margins of the original element
13476          this._cacheMargins();
13477  
13478          //Get the next scrolling parent
13479          this.scrollParent = this.helper.scrollParent();
13480  
13481          //The element's absolute position on the page minus margins
13482          this.offset = this.currentItem.offset();
13483          this.offset = {
13484              top: this.offset.top - this.margins.top,
13485              left: this.offset.left - this.margins.left
13486          };
13487  
13488          $.extend(this.offset, {
13489              click: { //Where the click happened, relative to the element
13490                  left: event.pageX - this.offset.left,
13491                  top: event.pageY - this.offset.top
13492              },
13493              parent: this._getParentOffset(),
13494              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
13495          });
13496  
13497          // Only after we got the offset, we can change the helper's position to absolute
13498          // TODO: Still need to figure out a way to make relative sorting possible
13499          this.helper.css("position", "absolute");
13500          this.cssPosition = this.helper.css("position");
13501  
13502          //Generate the original position
13503          this.originalPosition = this._generatePosition(event);
13504          this.originalPageX = event.pageX;
13505          this.originalPageY = event.pageY;
13506  
13507          //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
13508          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
13509  
13510          //Cache the former DOM position
13511          this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
13512  
13513          //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
13514          if(this.helper[0] !== this.currentItem[0]) {
13515              this.currentItem.hide();
13516          }
13517  
13518          //Create the placeholder
13519          this._createPlaceholder();
13520  
13521          //Set a containment if given in the options
13522          if(o.containment) {
13523              this._setContainment();
13524          }
13525  
13526          if( o.cursor && o.cursor !== "auto" ) { // cursor option
13527              body = this.document.find( "body" );
13528  
13529              // support: IE
13530              this.storedCursor = body.css( "cursor" );
13531              body.css( "cursor", o.cursor );
13532  
13533              this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
13534          }
13535  
13536          if(o.opacity) { // opacity option
13537              if (this.helper.css("opacity")) {
13538                  this._storedOpacity = this.helper.css("opacity");
13539              }
13540              this.helper.css("opacity", o.opacity);
13541          }
13542  
13543          if(o.zIndex) { // zIndex option
13544              if (this.helper.css("zIndex")) {
13545                  this._storedZIndex = this.helper.css("zIndex");
13546              }
13547              this.helper.css("zIndex", o.zIndex);
13548          }
13549  
13550          //Prepare scrolling
13551          if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13552              this.overflowOffset = this.scrollParent.offset();
13553          }
13554  
13555          //Call callbacks
13556          this._trigger("start", event, this._uiHash());
13557  
13558          //Recache the helper size
13559          if(!this._preserveHelperProportions) {
13560              this._cacheHelperProportions();
13561          }
13562  
13563  
13564          //Post "activate" events to possible containers
13565          if( !noActivation ) {
13566              for ( i = this.containers.length - 1; i >= 0; i-- ) {
13567                  this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
13568              }
13569          }
13570  
13571          //Prepare possible droppables
13572          if($.ui.ddmanager) {
13573              $.ui.ddmanager.current = this;
13574          }
13575  
13576          if ($.ui.ddmanager && !o.dropBehaviour) {
13577              $.ui.ddmanager.prepareOffsets(this, event);
13578          }
13579  
13580          this.dragging = true;
13581  
13582          this.helper.addClass("ui-sortable-helper");
13583          this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
13584          return true;
13585  
13586      },
13587  
13588      _mouseDrag: function(event) {
13589          var i, item, itemElement, intersection,
13590              o = this.options,
13591              scrolled = false;
13592  
13593          //Compute the helpers position
13594          this.position = this._generatePosition(event);
13595          this.positionAbs = this._convertPositionTo("absolute");
13596  
13597          if (!this.lastPositionAbs) {
13598              this.lastPositionAbs = this.positionAbs;
13599          }
13600  
13601          //Do scrolling
13602          if(this.options.scroll) {
13603              if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
13604  
13605                  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
13606                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
13607                  } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
13608                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
13609                  }
13610  
13611                  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
13612                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
13613                  } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
13614                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
13615                  }
13616  
13617              } else {
13618  
13619                  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
13620                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
13621                  } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
13622                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
13623                  }
13624  
13625                  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
13626                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
13627                  } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
13628                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
13629                  }
13630  
13631              }
13632  
13633              if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
13634                  $.ui.ddmanager.prepareOffsets(this, event);
13635              }
13636          }
13637  
13638          //Regenerate the absolute position used for position checks
13639          this.positionAbs = this._convertPositionTo("absolute");
13640  
13641          //Set the helper position
13642          if(!this.options.axis || this.options.axis !== "y") {
13643              this.helper[0].style.left = this.position.left+"px";
13644          }
13645          if(!this.options.axis || this.options.axis !== "x") {
13646              this.helper[0].style.top = this.position.top+"px";
13647          }
13648  
13649          //Rearrange
13650          for (i = this.items.length - 1; i >= 0; i--) {
13651  
13652              //Cache variables and intersection, continue if no intersection
13653              item = this.items[i];
13654              itemElement = item.item[0];
13655              intersection = this._intersectsWithPointer(item);
13656              if (!intersection) {
13657                  continue;
13658              }
13659  
13660              // Only put the placeholder inside the current Container, skip all
13661              // items from other containers. This works because when moving
13662              // an item from one container to another the
13663              // currentContainer is switched before the placeholder is moved.
13664              //
13665              // Without this, moving items in "sub-sortables" can cause
13666              // the placeholder to jitter between the outer and inner container.
13667              if (item.instance !== this.currentContainer) {
13668                  continue;
13669              }
13670  
13671              // cannot intersect with itself
13672              // no useless actions that have been done before
13673              // no action if the item moved is the parent of the item checked
13674              if (itemElement !== this.currentItem[0] &&
13675                  this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
13676                  !$.contains(this.placeholder[0], itemElement) &&
13677                  (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
13678              ) {
13679  
13680                  this.direction = intersection === 1 ? "down" : "up";
13681  
13682                  if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
13683                      this._rearrange(event, item);
13684                  } else {
13685                      break;
13686                  }
13687  
13688                  this._trigger("change", event, this._uiHash());
13689                  break;
13690              }
13691          }
13692  
13693          //Post events to containers
13694          this._contactContainers(event);
13695  
13696          //Interconnect with droppables
13697          if($.ui.ddmanager) {
13698              $.ui.ddmanager.drag(this, event);
13699          }
13700  
13701          //Call callbacks
13702          this._trigger("sort", event, this._uiHash());
13703  
13704          this.lastPositionAbs = this.positionAbs;
13705          return false;
13706  
13707      },
13708  
13709      _mouseStop: function(event, noPropagation) {
13710  
13711          if(!event) {
13712              return;
13713          }
13714  
13715          //If we are using droppables, inform the manager about the drop
13716          if ($.ui.ddmanager && !this.options.dropBehaviour) {
13717              $.ui.ddmanager.drop(this, event);
13718          }
13719  
13720          if(this.options.revert) {
13721              var that = this,
13722                  cur = this.placeholder.offset(),
13723                  axis = this.options.axis,
13724                  animation = {};
13725  
13726              if ( !axis || axis === "x" ) {
13727                  animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
13728              }
13729              if ( !axis || axis === "y" ) {
13730                  animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
13731              }
13732              this.reverting = true;
13733              $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
13734                  that._clear(event);
13735              });
13736          } else {
13737              this._clear(event, noPropagation);
13738          }
13739  
13740          return false;
13741  
13742      },
13743  
13744      cancel: function() {
13745  
13746          if(this.dragging) {
13747  
13748              this._mouseUp({ target: null });
13749  
13750              if(this.options.helper === "original") {
13751                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13752              } else {
13753                  this.currentItem.show();
13754              }
13755  
13756              //Post deactivating events to containers
13757              for (var i = this.containers.length - 1; i >= 0; i--){
13758                  this.containers[i]._trigger("deactivate", null, this._uiHash(this));
13759                  if(this.containers[i].containerCache.over) {
13760                      this.containers[i]._trigger("out", null, this._uiHash(this));
13761                      this.containers[i].containerCache.over = 0;
13762                  }
13763              }
13764  
13765          }
13766  
13767          if (this.placeholder) {
13768              //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13769              if(this.placeholder[0].parentNode) {
13770                  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13771              }
13772              if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
13773                  this.helper.remove();
13774              }
13775  
13776              $.extend(this, {
13777                  helper: null,
13778                  dragging: false,
13779                  reverting: false,
13780                  _noFinalSort: null
13781              });
13782  
13783              if(this.domPosition.prev) {
13784                  $(this.domPosition.prev).after(this.currentItem);
13785              } else {
13786                  $(this.domPosition.parent).prepend(this.currentItem);
13787              }
13788          }
13789  
13790          return this;
13791  
13792      },
13793  
13794      serialize: function(o) {
13795  
13796          var items = this._getItemsAsjQuery(o && o.connected),
13797              str = [];
13798          o = o || {};
13799  
13800          $(items).each(function() {
13801              var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
13802              if (res) {
13803                  str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
13804              }
13805          });
13806  
13807          if(!str.length && o.key) {
13808              str.push(o.key + "=");
13809          }
13810  
13811          return str.join("&");
13812  
13813      },
13814  
13815      toArray: function(o) {
13816  
13817          var items = this._getItemsAsjQuery(o && o.connected),
13818              ret = [];
13819  
13820          o = o || {};
13821  
13822          items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
13823          return ret;
13824  
13825      },
13826  
13827      /* Be careful with the following core functions */
13828      _intersectsWith: function(item) {
13829  
13830          var x1 = this.positionAbs.left,
13831              x2 = x1 + this.helperProportions.width,
13832              y1 = this.positionAbs.top,
13833              y2 = y1 + this.helperProportions.height,
13834              l = item.left,
13835              r = l + item.width,
13836              t = item.top,
13837              b = t + item.height,
13838              dyClick = this.offset.click.top,
13839              dxClick = this.offset.click.left,
13840              isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
13841              isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
13842              isOverElement = isOverElementHeight && isOverElementWidth;
13843  
13844          if ( this.options.tolerance === "pointer" ||
13845              this.options.forcePointerForContainers ||
13846              (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
13847          ) {
13848              return isOverElement;
13849          } else {
13850  
13851              return (l < x1 + (this.helperProportions.width / 2) && // Right Half
13852                  x2 - (this.helperProportions.width / 2) < r && // Left Half
13853                  t < y1 + (this.helperProportions.height / 2) && // Bottom Half
13854                  y2 - (this.helperProportions.height / 2) < b ); // Top Half
13855  
13856          }
13857      },
13858  
13859      _intersectsWithPointer: function(item) {
13860  
13861          var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
13862              isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
13863              isOverElement = isOverElementHeight && isOverElementWidth,
13864              verticalDirection = this._getDragVerticalDirection(),
13865              horizontalDirection = this._getDragHorizontalDirection();
13866  
13867          if (!isOverElement) {
13868              return false;
13869          }
13870  
13871          return this.floating ?
13872              ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
13873              : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
13874  
13875      },
13876  
13877      _intersectsWithSides: function(item) {
13878  
13879          var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
13880              isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
13881              verticalDirection = this._getDragVerticalDirection(),
13882              horizontalDirection = this._getDragHorizontalDirection();
13883  
13884          if (this.floating && horizontalDirection) {
13885              return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
13886          } else {
13887              return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
13888          }
13889  
13890      },
13891  
13892      _getDragVerticalDirection: function() {
13893          var delta = this.positionAbs.top - this.lastPositionAbs.top;
13894          return delta !== 0 && (delta > 0 ? "down" : "up");
13895      },
13896  
13897      _getDragHorizontalDirection: function() {
13898          var delta = this.positionAbs.left - this.lastPositionAbs.left;
13899          return delta !== 0 && (delta > 0 ? "right" : "left");
13900      },
13901  
13902      refresh: function(event) {
13903          this._refreshItems(event);
13904          this._setHandleClassName();
13905          this.refreshPositions();
13906          return this;
13907      },
13908  
13909      _connectWith: function() {
13910          var options = this.options;
13911          return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
13912      },
13913  
13914      _getItemsAsjQuery: function(connected) {
13915  
13916          var i, j, cur, inst,
13917              items = [],
13918              queries = [],
13919              connectWith = this._connectWith();
13920  
13921          if(connectWith && connected) {
13922              for (i = connectWith.length - 1; i >= 0; i--){
13923                  cur = $(connectWith[i]);
13924                  for ( j = cur.length - 1; j >= 0; j--){
13925                      inst = $.data(cur[j], this.widgetFullName);
13926                      if(inst && inst !== this && !inst.options.disabled) {
13927                          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]);
13928                      }
13929                  }
13930              }
13931          }
13932  
13933          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]);
13934  
13935  		function addItems() {
13936              items.push( this );
13937          }
13938          for (i = queries.length - 1; i >= 0; i--){
13939              queries[i][0].each( addItems );
13940          }
13941  
13942          return $(items);
13943  
13944      },
13945  
13946      _removeCurrentsFromItems: function() {
13947  
13948          var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
13949  
13950          this.items = $.grep(this.items, function (item) {
13951              for (var j=0; j < list.length; j++) {
13952                  if(list[j] === item.item[0]) {
13953                      return false;
13954                  }
13955              }
13956              return true;
13957          });
13958  
13959      },
13960  
13961      _refreshItems: function(event) {
13962  
13963          this.items = [];
13964          this.containers = [this];
13965  
13966          var i, j, cur, inst, targetData, _queries, item, queriesLength,
13967              items = this.items,
13968              queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
13969              connectWith = this._connectWith();
13970  
13971          if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
13972              for (i = connectWith.length - 1; i >= 0; i--){
13973                  cur = $(connectWith[i]);
13974                  for (j = cur.length - 1; j >= 0; j--){
13975                      inst = $.data(cur[j], this.widgetFullName);
13976                      if(inst && inst !== this && !inst.options.disabled) {
13977                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
13978                          this.containers.push(inst);
13979                      }
13980                  }
13981              }
13982          }
13983  
13984          for (i = queries.length - 1; i >= 0; i--) {
13985              targetData = queries[i][1];
13986              _queries = queries[i][0];
13987  
13988              for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
13989                  item = $(_queries[j]);
13990  
13991                  item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
13992  
13993                  items.push({
13994                      item: item,
13995                      instance: targetData,
13996                      width: 0, height: 0,
13997                      left: 0, top: 0
13998                  });
13999              }
14000          }
14001  
14002      },
14003  
14004      refreshPositions: function(fast) {
14005  
14006          //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
14007          if(this.offsetParent && this.helper) {
14008              this.offset.parent = this._getParentOffset();
14009          }
14010  
14011          var i, item, t, p;
14012  
14013          for (i = this.items.length - 1; i >= 0; i--){
14014              item = this.items[i];
14015  
14016              //We ignore calculating positions of all connected containers when we're not over them
14017              if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
14018                  continue;
14019              }
14020  
14021              t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
14022  
14023              if (!fast) {
14024                  item.width = t.outerWidth();
14025                  item.height = t.outerHeight();
14026              }
14027  
14028              p = t.offset();
14029              item.left = p.left;
14030              item.top = p.top;
14031          }
14032  
14033          if(this.options.custom && this.options.custom.refreshContainers) {
14034              this.options.custom.refreshContainers.call(this);
14035          } else {
14036              for (i = this.containers.length - 1; i >= 0; i--){
14037                  p = this.containers[i].element.offset();
14038                  this.containers[i].containerCache.left = p.left;
14039                  this.containers[i].containerCache.top = p.top;
14040                  this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
14041                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
14042              }
14043          }
14044  
14045          return this;
14046      },
14047  
14048      _createPlaceholder: function(that) {
14049          that = that || this;
14050          var className,
14051              o = that.options;
14052  
14053          if(!o.placeholder || o.placeholder.constructor === String) {
14054              className = o.placeholder;
14055              o.placeholder = {
14056                  element: function() {
14057  
14058                      var nodeName = that.currentItem[0].nodeName.toLowerCase(),
14059                          element = $( "<" + nodeName + ">", that.document[0] )
14060                              .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
14061                              .removeClass("ui-sortable-helper");
14062  
14063                      if ( nodeName === "tr" ) {
14064                          that.currentItem.children().each(function() {
14065                              $( "<td>&#160;</td>", that.document[0] )
14066                                  .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
14067                                  .appendTo( element );
14068                          });
14069                      } else if ( nodeName === "img" ) {
14070                          element.attr( "src", that.currentItem.attr( "src" ) );
14071                      }
14072  
14073                      if ( !className ) {
14074                          element.css( "visibility", "hidden" );
14075                      }
14076  
14077                      return element;
14078                  },
14079                  update: function(container, p) {
14080  
14081                      // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
14082                      // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
14083                      if(className && !o.forcePlaceholderSize) {
14084                          return;
14085                      }
14086  
14087                      //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
14088                      if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
14089                      if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
14090                  }
14091              };
14092          }
14093  
14094          //Create the placeholder
14095          that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
14096  
14097          //Append it after the actual current item
14098          that.currentItem.after(that.placeholder);
14099  
14100          //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
14101          o.placeholder.update(that, that.placeholder);
14102  
14103      },
14104  
14105      _contactContainers: function(event) {
14106          var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
14107              innermostContainer = null,
14108              innermostIndex = null;
14109  
14110          // get innermost container that intersects with item
14111          for (i = this.containers.length - 1; i >= 0; i--) {
14112  
14113              // never consider a container that's located within the item itself
14114              if($.contains(this.currentItem[0], this.containers[i].element[0])) {
14115                  continue;
14116              }
14117  
14118              if(this._intersectsWith(this.containers[i].containerCache)) {
14119  
14120                  // if we've already found a container and it's more "inner" than this, then continue
14121                  if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
14122                      continue;
14123                  }
14124  
14125                  innermostContainer = this.containers[i];
14126                  innermostIndex = i;
14127  
14128              } else {
14129                  // container doesn't intersect. trigger "out" event if necessary
14130                  if(this.containers[i].containerCache.over) {
14131                      this.containers[i]._trigger("out", event, this._uiHash(this));
14132                      this.containers[i].containerCache.over = 0;
14133                  }
14134              }
14135  
14136          }
14137  
14138          // if no intersecting containers found, return
14139          if(!innermostContainer) {
14140              return;
14141          }
14142  
14143          // move the item into the container if it's not there already
14144          if(this.containers.length === 1) {
14145              if (!this.containers[innermostIndex].containerCache.over) {
14146                  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14147                  this.containers[innermostIndex].containerCache.over = 1;
14148              }
14149          } else {
14150  
14151              //When entering a new container, we will find the item with the least distance and append our item near it
14152              dist = 10000;
14153              itemWithLeastDistance = null;
14154              floating = innermostContainer.floating || this._isFloating(this.currentItem);
14155              posProperty = floating ? "left" : "top";
14156              sizeProperty = floating ? "width" : "height";
14157              axis = floating ? "clientX" : "clientY";
14158  
14159              for (j = this.items.length - 1; j >= 0; j--) {
14160                  if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
14161                      continue;
14162                  }
14163                  if(this.items[j].item[0] === this.currentItem[0]) {
14164                      continue;
14165                  }
14166  
14167                  cur = this.items[j].item.offset()[posProperty];
14168                  nearBottom = false;
14169                  if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
14170                      nearBottom = true;
14171                  }
14172  
14173                  if ( Math.abs( event[ axis ] - cur ) < dist ) {
14174                      dist = Math.abs( event[ axis ] - cur );
14175                      itemWithLeastDistance = this.items[ j ];
14176                      this.direction = nearBottom ? "up": "down";
14177                  }
14178              }
14179  
14180              //Check if dropOnEmpty is enabled
14181              if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
14182                  return;
14183              }
14184  
14185              if(this.currentContainer === this.containers[innermostIndex]) {
14186                  return;
14187              }
14188  
14189              itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
14190              this._trigger("change", event, this._uiHash());
14191              this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
14192              this.currentContainer = this.containers[innermostIndex];
14193  
14194              //Update the placeholder
14195              this.options.placeholder.update(this.currentContainer, this.placeholder);
14196  
14197              this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
14198              this.containers[innermostIndex].containerCache.over = 1;
14199          }
14200  
14201  
14202      },
14203  
14204      _createHelper: function(event) {
14205  
14206          var o = this.options,
14207              helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
14208  
14209          //Add the helper to the DOM if that didn't happen already
14210          if(!helper.parents("body").length) {
14211              $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
14212          }
14213  
14214          if(helper[0] === this.currentItem[0]) {
14215              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") };
14216          }
14217  
14218          if(!helper[0].style.width || o.forceHelperSize) {
14219              helper.width(this.currentItem.width());
14220          }
14221          if(!helper[0].style.height || o.forceHelperSize) {
14222              helper.height(this.currentItem.height());
14223          }
14224  
14225          return helper;
14226  
14227      },
14228  
14229      _adjustOffsetFromHelper: function(obj) {
14230          if (typeof obj === "string") {
14231              obj = obj.split(" ");
14232          }
14233          if ($.isArray(obj)) {
14234              obj = {left: +obj[0], top: +obj[1] || 0};
14235          }
14236          if ("left" in obj) {
14237              this.offset.click.left = obj.left + this.margins.left;
14238          }
14239          if ("right" in obj) {
14240              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
14241          }
14242          if ("top" in obj) {
14243              this.offset.click.top = obj.top + this.margins.top;
14244          }
14245          if ("bottom" in obj) {
14246              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
14247          }
14248      },
14249  
14250      _getParentOffset: function() {
14251  
14252  
14253          //Get the offsetParent and cache its position
14254          this.offsetParent = this.helper.offsetParent();
14255          var po = this.offsetParent.offset();
14256  
14257          // This is a special case where we need to modify a offset calculated on start, since the following happened:
14258          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
14259          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
14260          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
14261          if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
14262              po.left += this.scrollParent.scrollLeft();
14263              po.top += this.scrollParent.scrollTop();
14264          }
14265  
14266          // This needs to be actually done for all browsers, since pageX/pageY includes this information
14267          // with an ugly IE fix
14268          if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
14269              po = { top: 0, left: 0 };
14270          }
14271  
14272          return {
14273              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
14274              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
14275          };
14276  
14277      },
14278  
14279      _getRelativeOffset: function() {
14280  
14281          if(this.cssPosition === "relative") {
14282              var p = this.currentItem.position();
14283              return {
14284                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
14285                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
14286              };
14287          } else {
14288              return { top: 0, left: 0 };
14289          }
14290  
14291      },
14292  
14293      _cacheMargins: function() {
14294          this.margins = {
14295              left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
14296              top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
14297          };
14298      },
14299  
14300      _cacheHelperProportions: function() {
14301          this.helperProportions = {
14302              width: this.helper.outerWidth(),
14303              height: this.helper.outerHeight()
14304          };
14305      },
14306  
14307      _setContainment: function() {
14308  
14309          var ce, co, over,
14310              o = this.options;
14311          if(o.containment === "parent") {
14312              o.containment = this.helper[0].parentNode;
14313          }
14314          if(o.containment === "document" || o.containment === "window") {
14315              this.containment = [
14316                  0 - this.offset.relative.left - this.offset.parent.left,
14317                  0 - this.offset.relative.top - this.offset.parent.top,
14318                  $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
14319                  ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
14320              ];
14321          }
14322  
14323          if(!(/^(document|window|parent)$/).test(o.containment)) {
14324              ce = $(o.containment)[0];
14325              co = $(o.containment).offset();
14326              over = ($(ce).css("overflow") !== "hidden");
14327  
14328              this.containment = [
14329                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
14330                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
14331                  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,
14332                  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
14333              ];
14334          }
14335  
14336      },
14337  
14338      _convertPositionTo: function(d, pos) {
14339  
14340          if(!pos) {
14341              pos = this.position;
14342          }
14343          var mod = d === "absolute" ? 1 : -1,
14344              scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
14345              scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14346  
14347          return {
14348              top: (
14349                  pos.top    +                                                                // The absolute mouse position
14350                  this.offset.relative.top * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14351                  this.offset.parent.top * mod -                                            // The offsetParent's offset without borders (offset + border)
14352                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
14353              ),
14354              left: (
14355                  pos.left +                                                                // The absolute mouse position
14356                  this.offset.relative.left * mod +                                        // Only for relative positioned nodes: Relative offset from element to offset parent
14357                  this.offset.parent.left * mod    -                                        // The offsetParent's offset without borders (offset + border)
14358                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
14359              )
14360          };
14361  
14362      },
14363  
14364      _generatePosition: function(event) {
14365  
14366          var top, left,
14367              o = this.options,
14368              pageX = event.pageX,
14369              pageY = event.pageY,
14370              scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
14371  
14372          // This is another very weird special case that only happens for relative elements:
14373          // 1. If the css position is relative
14374          // 2. and the scroll parent is the document or similar to the offset parent
14375          // we have to refresh the relative offset during the scroll so there are no jumps
14376          if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
14377              this.offset.relative = this._getRelativeOffset();
14378          }
14379  
14380          /*
14381           * - Position constraining -
14382           * Constrain the position to a mix of grid, containment.
14383           */
14384  
14385          if(this.originalPosition) { //If we are not dragging yet, we won't check for options
14386  
14387              if(this.containment) {
14388                  if(event.pageX - this.offset.click.left < this.containment[0]) {
14389                      pageX = this.containment[0] + this.offset.click.left;
14390                  }
14391                  if(event.pageY - this.offset.click.top < this.containment[1]) {
14392                      pageY = this.containment[1] + this.offset.click.top;
14393                  }
14394                  if(event.pageX - this.offset.click.left > this.containment[2]) {
14395                      pageX = this.containment[2] + this.offset.click.left;
14396                  }
14397                  if(event.pageY - this.offset.click.top > this.containment[3]) {
14398                      pageY = this.containment[3] + this.offset.click.top;
14399                  }
14400              }
14401  
14402              if(o.grid) {
14403                  top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
14404                  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;
14405  
14406                  left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
14407                  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;
14408              }
14409  
14410          }
14411  
14412          return {
14413              top: (
14414                  pageY -                                                                // The absolute mouse position
14415                  this.offset.click.top -                                                    // Click offset (relative to the element)
14416                  this.offset.relative.top    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
14417                  this.offset.parent.top +                                                // The offsetParent's offset without borders (offset + border)
14418                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
14419              ),
14420              left: (
14421                  pageX -                                                                // The absolute mouse position
14422                  this.offset.click.left -                                                // Click offset (relative to the element)
14423                  this.offset.relative.left    -                                            // Only for relative positioned nodes: Relative offset from element to offset parent
14424                  this.offset.parent.left +                                                // The offsetParent's offset without borders (offset + border)
14425                  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
14426              )
14427          };
14428  
14429      },
14430  
14431      _rearrange: function(event, i, a, hardRefresh) {
14432  
14433          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));
14434  
14435          //Various things done here to improve the performance:
14436          // 1. we create a setTimeout, that calls refreshPositions
14437          // 2. on the instance, we have a counter variable, that get's higher after every append
14438          // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
14439          // 4. this lets only the last addition to the timeout stack through
14440          this.counter = this.counter ? ++this.counter : 1;
14441          var counter = this.counter;
14442  
14443          this._delay(function() {
14444              if(counter === this.counter) {
14445                  this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
14446              }
14447          });
14448  
14449      },
14450  
14451      _clear: function(event, noPropagation) {
14452  
14453          this.reverting = false;
14454          // We delay all events that have to be triggered to after the point where the placeholder has been removed and
14455          // everything else normalized again
14456          var i,
14457              delayedTriggers = [];
14458  
14459          // We first have to update the dom position of the actual currentItem
14460          // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
14461          if(!this._noFinalSort && this.currentItem.parent().length) {
14462              this.placeholder.before(this.currentItem);
14463          }
14464          this._noFinalSort = null;
14465  
14466          if(this.helper[0] === this.currentItem[0]) {
14467              for(i in this._storedCSS) {
14468                  if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
14469                      this._storedCSS[i] = "";
14470                  }
14471              }
14472              this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
14473          } else {
14474              this.currentItem.show();
14475          }
14476  
14477          if(this.fromOutside && !noPropagation) {
14478              delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
14479          }
14480          if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
14481              delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
14482          }
14483  
14484          // Check if the items Container has Changed and trigger appropriate
14485          // events.
14486          if (this !== this.currentContainer) {
14487              if(!noPropagation) {
14488                  delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
14489                  delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
14490                  delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
14491              }
14492          }
14493  
14494  
14495          //Post events to containers
14496  		function delayEvent( type, instance, container ) {
14497              return function( event ) {
14498                  container._trigger( type, event, instance._uiHash( instance ) );
14499              };
14500          }
14501          for (i = this.containers.length - 1; i >= 0; i--){
14502              if (!noPropagation) {
14503                  delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
14504              }
14505              if(this.containers[i].containerCache.over) {
14506                  delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
14507                  this.containers[i].containerCache.over = 0;
14508              }
14509          }
14510  
14511          //Do what was originally in plugins
14512          if ( this.storedCursor ) {
14513              this.document.find( "body" ).css( "cursor", this.storedCursor );
14514              this.storedStylesheet.remove();
14515          }
14516          if(this._storedOpacity) {
14517              this.helper.css("opacity", this._storedOpacity);
14518          }
14519          if(this._storedZIndex) {
14520              this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
14521          }
14522  
14523          this.dragging = false;
14524          if(this.cancelHelperRemoval) {
14525              if(!noPropagation) {
14526                  this._trigger("beforeStop", event, this._uiHash());
14527                  for (i=0; i < delayedTriggers.length; i++) {
14528                      delayedTriggers[i].call(this, event);
14529                  } //Trigger all delayed events
14530                  this._trigger("stop", event, this._uiHash());
14531              }
14532  
14533              this.fromOutside = false;
14534              return false;
14535          }
14536  
14537          if(!noPropagation) {
14538              this._trigger("beforeStop", event, this._uiHash());
14539          }
14540  
14541          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
14542          this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
14543  
14544          if(this.helper[0] !== this.currentItem[0]) {
14545              this.helper.remove();
14546          }
14547          this.helper = null;
14548  
14549          if(!noPropagation) {
14550              for (i=0; i < delayedTriggers.length; i++) {
14551                  delayedTriggers[i].call(this, event);
14552              } //Trigger all delayed events
14553              this._trigger("stop", event, this._uiHash());
14554          }
14555  
14556          this.fromOutside = false;
14557          return true;
14558  
14559      },
14560  
14561      _trigger: function() {
14562          if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
14563              this.cancel();
14564          }
14565      },
14566  
14567      _uiHash: function(_inst) {
14568          var inst = _inst || this;
14569          return {
14570              helper: inst.helper,
14571              placeholder: inst.placeholder || $([]),
14572              position: inst.position,
14573              originalPosition: inst.originalPosition,
14574              offset: inst.positionAbs,
14575              item: inst.currentItem,
14576              sender: _inst ? _inst.element : null
14577          };
14578      }
14579  
14580  });
14581  
14582  
14583  /*!
14584   * jQuery UI Spinner 1.11.1
14585   * http://jqueryui.com
14586   *
14587   * Copyright 2014 jQuery Foundation and other contributors
14588   * Released under the MIT license.
14589   * http://jquery.org/license
14590   *
14591   * http://api.jqueryui.com/spinner/
14592   */
14593  
14594  
14595  function spinner_modifier( fn ) {
14596      return function() {
14597          var previous = this.element.val();
14598          fn.apply( this, arguments );
14599          this._refresh();
14600          if ( previous !== this.element.val() ) {
14601              this._trigger( "change" );
14602          }
14603      };
14604  }
14605  
14606  var spinner = $.widget( "ui.spinner", {
14607      version: "1.11.1",
14608      defaultElement: "<input>",
14609      widgetEventPrefix: "spin",
14610      options: {
14611          culture: null,
14612          icons: {
14613              down: "ui-icon-triangle-1-s",
14614              up: "ui-icon-triangle-1-n"
14615          },
14616          incremental: true,
14617          max: null,
14618          min: null,
14619          numberFormat: null,
14620          page: 10,
14621          step: 1,
14622  
14623          change: null,
14624          spin: null,
14625          start: null,
14626          stop: null
14627      },
14628  
14629      _create: function() {
14630          // handle string values that need to be parsed
14631          this._setOption( "max", this.options.max );
14632          this._setOption( "min", this.options.min );
14633          this._setOption( "step", this.options.step );
14634  
14635          // Only format if there is a value, prevents the field from being marked
14636          // as invalid in Firefox, see #9573.
14637          if ( this.value() !== "" ) {
14638              // Format the value, but don't constrain.
14639              this._value( this.element.val(), true );
14640          }
14641  
14642          this._draw();
14643          this._on( this._events );
14644          this._refresh();
14645  
14646          // turning off autocomplete prevents the browser from remembering the
14647          // value when navigating through history, so we re-enable autocomplete
14648          // if the page is unloaded before the widget is destroyed. #7790
14649          this._on( this.window, {
14650              beforeunload: function() {
14651                  this.element.removeAttr( "autocomplete" );
14652              }
14653          });
14654      },
14655  
14656      _getCreateOptions: function() {
14657          var options = {},
14658              element = this.element;
14659  
14660          $.each( [ "min", "max", "step" ], function( i, option ) {
14661              var value = element.attr( option );
14662              if ( value !== undefined && value.length ) {
14663                  options[ option ] = value;
14664              }
14665          });
14666  
14667          return options;
14668      },
14669  
14670      _events: {
14671          keydown: function( event ) {
14672              if ( this._start( event ) && this._keydown( event ) ) {
14673                  event.preventDefault();
14674              }
14675          },
14676          keyup: "_stop",
14677          focus: function() {
14678              this.previous = this.element.val();
14679          },
14680          blur: function( event ) {
14681              if ( this.cancelBlur ) {
14682                  delete this.cancelBlur;
14683                  return;
14684              }
14685  
14686              this._stop();
14687              this._refresh();
14688              if ( this.previous !== this.element.val() ) {
14689                  this._trigger( "change", event );
14690              }
14691          },
14692          mousewheel: function( event, delta ) {
14693              if ( !delta ) {
14694                  return;
14695              }
14696              if ( !this.spinning && !this._start( event ) ) {
14697                  return false;
14698              }
14699  
14700              this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
14701              clearTimeout( this.mousewheelTimer );
14702              this.mousewheelTimer = this._delay(function() {
14703                  if ( this.spinning ) {
14704                      this._stop( event );
14705                  }
14706              }, 100 );
14707              event.preventDefault();
14708          },
14709          "mousedown .ui-spinner-button": function( event ) {
14710              var previous;
14711  
14712              // We never want the buttons to have focus; whenever the user is
14713              // interacting with the spinner, the focus should be on the input.
14714              // If the input is focused then this.previous is properly set from
14715              // when the input first received focus. If the input is not focused
14716              // then we need to set this.previous based on the value before spinning.
14717              previous = this.element[0] === this.document[0].activeElement ?
14718                  this.previous : this.element.val();
14719  			function checkFocus() {
14720                  var isActive = this.element[0] === this.document[0].activeElement;
14721                  if ( !isActive ) {
14722                      this.element.focus();
14723                      this.previous = previous;
14724                      // support: IE
14725                      // IE sets focus asynchronously, so we need to check if focus
14726                      // moved off of the input because the user clicked on the button.
14727                      this._delay(function() {
14728                          this.previous = previous;
14729                      });
14730                  }
14731              }
14732  
14733              // ensure focus is on (or stays on) the text field
14734              event.preventDefault();
14735              checkFocus.call( this );
14736  
14737              // support: IE
14738              // IE doesn't prevent moving focus even with event.preventDefault()
14739              // so we set a flag to know when we should ignore the blur event
14740              // and check (again) if focus moved off of the input.
14741              this.cancelBlur = true;
14742              this._delay(function() {
14743                  delete this.cancelBlur;
14744                  checkFocus.call( this );
14745              });
14746  
14747              if ( this._start( event ) === false ) {
14748                  return;
14749              }
14750  
14751              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14752          },
14753          "mouseup .ui-spinner-button": "_stop",
14754          "mouseenter .ui-spinner-button": function( event ) {
14755              // button will add ui-state-active if mouse was down while mouseleave and kept down
14756              if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
14757                  return;
14758              }
14759  
14760              if ( this._start( event ) === false ) {
14761                  return false;
14762              }
14763              this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
14764          },
14765          // TODO: do we really want to consider this a stop?
14766          // shouldn't we just stop the repeater and wait until mouseup before
14767          // we trigger the stop event?
14768          "mouseleave .ui-spinner-button": "_stop"
14769      },
14770  
14771      _draw: function() {
14772          var uiSpinner = this.uiSpinner = this.element
14773              .addClass( "ui-spinner-input" )
14774              .attr( "autocomplete", "off" )
14775              .wrap( this._uiSpinnerHtml() )
14776              .parent()
14777                  // add buttons
14778                  .append( this._buttonHtml() );
14779  
14780          this.element.attr( "role", "spinbutton" );
14781  
14782          // button bindings
14783          this.buttons = uiSpinner.find( ".ui-spinner-button" )
14784              .attr( "tabIndex", -1 )
14785              .button()
14786              .removeClass( "ui-corner-all" );
14787  
14788          // IE 6 doesn't understand height: 50% for the buttons
14789          // unless the wrapper has an explicit height
14790          if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
14791                  uiSpinner.height() > 0 ) {
14792              uiSpinner.height( uiSpinner.height() );
14793          }
14794  
14795          // disable spinner if element was already disabled
14796          if ( this.options.disabled ) {
14797              this.disable();
14798          }
14799      },
14800  
14801      _keydown: function( event ) {
14802          var options = this.options,
14803              keyCode = $.ui.keyCode;
14804  
14805          switch ( event.keyCode ) {
14806          case keyCode.UP:
14807              this._repeat( null, 1, event );
14808              return true;
14809          case keyCode.DOWN:
14810              this._repeat( null, -1, event );
14811              return true;
14812          case keyCode.PAGE_UP:
14813              this._repeat( null, options.page, event );
14814              return true;
14815          case keyCode.PAGE_DOWN:
14816              this._repeat( null, -options.page, event );
14817              return true;
14818          }
14819  
14820          return false;
14821      },
14822  
14823      _uiSpinnerHtml: function() {
14824          return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
14825      },
14826  
14827      _buttonHtml: function() {
14828          return "" +
14829              "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
14830                  "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
14831              "</a>" +
14832              "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
14833                  "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
14834              "</a>";
14835      },
14836  
14837      _start: function( event ) {
14838          if ( !this.spinning && this._trigger( "start", event ) === false ) {
14839              return false;
14840          }
14841  
14842          if ( !this.counter ) {
14843              this.counter = 1;
14844          }
14845          this.spinning = true;
14846          return true;
14847      },
14848  
14849      _repeat: function( i, steps, event ) {
14850          i = i || 500;
14851  
14852          clearTimeout( this.timer );
14853          this.timer = this._delay(function() {
14854              this._repeat( 40, steps, event );
14855          }, i );
14856  
14857          this._spin( steps * this.options.step, event );
14858      },
14859  
14860      _spin: function( step, event ) {
14861          var value = this.value() || 0;
14862  
14863          if ( !this.counter ) {
14864              this.counter = 1;
14865          }
14866  
14867          value = this._adjustValue( value + step * this._increment( this.counter ) );
14868  
14869          if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
14870              this._value( value );
14871              this.counter++;
14872          }
14873      },
14874  
14875      _increment: function( i ) {
14876          var incremental = this.options.incremental;
14877  
14878          if ( incremental ) {
14879              return $.isFunction( incremental ) ?
14880                  incremental( i ) :
14881                  Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
14882          }
14883  
14884          return 1;
14885      },
14886  
14887      _precision: function() {
14888          var precision = this._precisionOf( this.options.step );
14889          if ( this.options.min !== null ) {
14890              precision = Math.max( precision, this._precisionOf( this.options.min ) );
14891          }
14892          return precision;
14893      },
14894  
14895      _precisionOf: function( num ) {
14896          var str = num.toString(),
14897              decimal = str.indexOf( "." );
14898          return decimal === -1 ? 0 : str.length - decimal - 1;
14899      },
14900  
14901      _adjustValue: function( value ) {
14902          var base, aboveMin,
14903              options = this.options;
14904  
14905          // make sure we're at a valid step
14906          // - find out where we are relative to the base (min or 0)
14907          base = options.min !== null ? options.min : 0;
14908          aboveMin = value - base;
14909          // - round to the nearest step
14910          aboveMin = Math.round(aboveMin / options.step) * options.step;
14911          // - rounding is based on 0, so adjust back to our base
14912          value = base + aboveMin;
14913  
14914          // fix precision from bad JS floating point math
14915          value = parseFloat( value.toFixed( this._precision() ) );
14916  
14917          // clamp the value
14918          if ( options.max !== null && value > options.max) {
14919              return options.max;
14920          }
14921          if ( options.min !== null && value < options.min ) {
14922              return options.min;
14923          }
14924  
14925          return value;
14926      },
14927  
14928      _stop: function( event ) {
14929          if ( !this.spinning ) {
14930              return;
14931          }
14932  
14933          clearTimeout( this.timer );
14934          clearTimeout( this.mousewheelTimer );
14935          this.counter = 0;
14936          this.spinning = false;
14937          this._trigger( "stop", event );
14938      },
14939  
14940      _setOption: function( key, value ) {
14941          if ( key === "culture" || key === "numberFormat" ) {
14942              var prevValue = this._parse( this.element.val() );
14943              this.options[ key ] = value;
14944              this.element.val( this._format( prevValue ) );
14945              return;
14946          }
14947  
14948          if ( key === "max" || key === "min" || key === "step" ) {
14949              if ( typeof value === "string" ) {
14950                  value = this._parse( value );
14951              }
14952          }
14953          if ( key === "icons" ) {
14954              this.buttons.first().find( ".ui-icon" )
14955                  .removeClass( this.options.icons.up )
14956                  .addClass( value.up );
14957              this.buttons.last().find( ".ui-icon" )
14958                  .removeClass( this.options.icons.down )
14959                  .addClass( value.down );
14960          }
14961  
14962          this._super( key, value );
14963  
14964          if ( key === "disabled" ) {
14965              this.widget().toggleClass( "ui-state-disabled", !!value );
14966              this.element.prop( "disabled", !!value );
14967              this.buttons.button( value ? "disable" : "enable" );
14968          }
14969      },
14970  
14971      _setOptions: spinner_modifier(function( options ) {
14972          this._super( options );
14973      }),
14974  
14975      _parse: function( val ) {
14976          if ( typeof val === "string" && val !== "" ) {
14977              val = window.Globalize && this.options.numberFormat ?
14978                  Globalize.parseFloat( val, 10, this.options.culture ) : +val;
14979          }
14980          return val === "" || isNaN( val ) ? null : val;
14981      },
14982  
14983      _format: function( value ) {
14984          if ( value === "" ) {
14985              return "";
14986          }
14987          return window.Globalize && this.options.numberFormat ?
14988              Globalize.format( value, this.options.numberFormat, this.options.culture ) :
14989              value;
14990      },
14991  
14992      _refresh: function() {
14993          this.element.attr({
14994              "aria-valuemin": this.options.min,
14995              "aria-valuemax": this.options.max,
14996              // TODO: what should we do with values that can't be parsed?
14997              "aria-valuenow": this._parse( this.element.val() )
14998          });
14999      },
15000  
15001      isValid: function() {
15002          var value = this.value();
15003  
15004          // null is invalid
15005          if ( value === null ) {
15006              return false;
15007          }
15008  
15009          // if value gets adjusted, it's invalid
15010          return value === this._adjustValue( value );
15011      },
15012  
15013      // update the value without triggering change
15014      _value: function( value, allowAny ) {
15015          var parsed;
15016          if ( value !== "" ) {
15017              parsed = this._parse( value );
15018              if ( parsed !== null ) {
15019                  if ( !allowAny ) {
15020                      parsed = this._adjustValue( parsed );
15021                  }
15022                  value = this._format( parsed );
15023              }
15024          }
15025          this.element.val( value );
15026          this._refresh();
15027      },
15028  
15029      _destroy: function() {
15030          this.element
15031              .removeClass( "ui-spinner-input" )
15032              .prop( "disabled", false )
15033              .removeAttr( "autocomplete" )
15034              .removeAttr( "role" )
15035              .removeAttr( "aria-valuemin" )
15036              .removeAttr( "aria-valuemax" )
15037              .removeAttr( "aria-valuenow" );
15038          this.uiSpinner.replaceWith( this.element );
15039      },
15040  
15041      stepUp: spinner_modifier(function( steps ) {
15042          this._stepUp( steps );
15043      }),
15044      _stepUp: function( steps ) {
15045          if ( this._start() ) {
15046              this._spin( (steps || 1) * this.options.step );
15047              this._stop();
15048          }
15049      },
15050  
15051      stepDown: spinner_modifier(function( steps ) {
15052          this._stepDown( steps );
15053      }),
15054      _stepDown: function( steps ) {
15055          if ( this._start() ) {
15056              this._spin( (steps || 1) * -this.options.step );
15057              this._stop();
15058          }
15059      },
15060  
15061      pageUp: spinner_modifier(function( pages ) {
15062          this._stepUp( (pages || 1) * this.options.page );
15063      }),
15064  
15065      pageDown: spinner_modifier(function( pages ) {
15066          this._stepDown( (pages || 1) * this.options.page );
15067      }),
15068  
15069      value: function( newVal ) {
15070          if ( !arguments.length ) {
15071              return this._parse( this.element.val() );
15072          }
15073          spinner_modifier( this._value ).call( this, newVal );
15074      },
15075  
15076      widget: function() {
15077          return this.uiSpinner;
15078      }
15079  });
15080  
15081  
15082  /*!
15083   * jQuery UI Tabs 1.11.1
15084   * http://jqueryui.com
15085   *
15086   * Copyright 2014 jQuery Foundation and other contributors
15087   * Released under the MIT license.
15088   * http://jquery.org/license
15089   *
15090   * http://api.jqueryui.com/tabs/
15091   */
15092  
15093  
15094  var tabs = $.widget( "ui.tabs", {
15095      version: "1.11.1",
15096      delay: 300,
15097      options: {
15098          active: null,
15099          collapsible: false,
15100          event: "click",
15101          heightStyle: "content",
15102          hide: null,
15103          show: null,
15104  
15105          // callbacks
15106          activate: null,
15107          beforeActivate: null,
15108          beforeLoad: null,
15109          load: null
15110      },
15111  
15112      _isLocal: (function() {
15113          var rhash = /#.*$/;
15114  
15115          return function( anchor ) {
15116              var anchorUrl, locationUrl;
15117  
15118              // support: IE7
15119              // IE7 doesn't normalize the href property when set via script (#9317)
15120              anchor = anchor.cloneNode( false );
15121  
15122              anchorUrl = anchor.href.replace( rhash, "" );
15123              locationUrl = location.href.replace( rhash, "" );
15124  
15125              // decoding may throw an error if the URL isn't UTF-8 (#9518)
15126              try {
15127                  anchorUrl = decodeURIComponent( anchorUrl );
15128              } catch ( error ) {}
15129              try {
15130                  locationUrl = decodeURIComponent( locationUrl );
15131              } catch ( error ) {}
15132  
15133              return anchor.hash.length > 1 && anchorUrl === locationUrl;
15134          };
15135      })(),
15136  
15137      _create: function() {
15138          var that = this,
15139              options = this.options;
15140  
15141          this.running = false;
15142  
15143          this.element
15144              .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
15145              .toggleClass( "ui-tabs-collapsible", options.collapsible );
15146  
15147          this._processTabs();
15148          options.active = this._initialActive();
15149  
15150          // Take disabling tabs via class attribute from HTML
15151          // into account and update option properly.
15152          if ( $.isArray( options.disabled ) ) {
15153              options.disabled = $.unique( options.disabled.concat(
15154                  $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
15155                      return that.tabs.index( li );
15156                  })
15157              ) ).sort();
15158          }
15159  
15160          // check for length avoids error when initializing empty list
15161          if ( this.options.active !== false && this.anchors.length ) {
15162              this.active = this._findActive( options.active );
15163          } else {
15164              this.active = $();
15165          }
15166  
15167          this._refresh();
15168  
15169          if ( this.active.length ) {
15170              this.load( options.active );
15171          }
15172      },
15173  
15174      _initialActive: function() {
15175          var active = this.options.active,
15176              collapsible = this.options.collapsible,
15177              locationHash = location.hash.substring( 1 );
15178  
15179          if ( active === null ) {
15180              // check the fragment identifier in the URL
15181              if ( locationHash ) {
15182                  this.tabs.each(function( i, tab ) {
15183                      if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
15184                          active = i;
15185                          return false;
15186                      }
15187                  });
15188              }
15189  
15190              // check for a tab marked active via a class
15191              if ( active === null ) {
15192                  active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
15193              }
15194  
15195              // no active tab, set to false
15196              if ( active === null || active === -1 ) {
15197                  active = this.tabs.length ? 0 : false;
15198              }
15199          }
15200  
15201          // handle numbers: negative, out of range
15202          if ( active !== false ) {
15203              active = this.tabs.index( this.tabs.eq( active ) );
15204              if ( active === -1 ) {
15205                  active = collapsible ? false : 0;
15206              }
15207          }
15208  
15209          // don't allow collapsible: false and active: false
15210          if ( !collapsible && active === false && this.anchors.length ) {
15211              active = 0;
15212          }
15213  
15214          return active;
15215      },
15216  
15217      _getCreateEventData: function() {
15218          return {
15219              tab: this.active,
15220              panel: !this.active.length ? $() : this._getPanelForTab( this.active )
15221          };
15222      },
15223  
15224      _tabKeydown: function( event ) {
15225          var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
15226              selectedIndex = this.tabs.index( focusedTab ),
15227              goingForward = true;
15228  
15229          if ( this._handlePageNav( event ) ) {
15230              return;
15231          }
15232  
15233          switch ( event.keyCode ) {
15234              case $.ui.keyCode.RIGHT:
15235              case $.ui.keyCode.DOWN:
15236                  selectedIndex++;
15237                  break;
15238              case $.ui.keyCode.UP:
15239              case $.ui.keyCode.LEFT:
15240                  goingForward = false;
15241                  selectedIndex--;
15242                  break;
15243              case $.ui.keyCode.END:
15244                  selectedIndex = this.anchors.length - 1;
15245                  break;
15246              case $.ui.keyCode.HOME:
15247                  selectedIndex = 0;
15248                  break;
15249              case $.ui.keyCode.SPACE:
15250                  // Activate only, no collapsing
15251                  event.preventDefault();
15252                  clearTimeout( this.activating );
15253                  this._activate( selectedIndex );
15254                  return;
15255              case $.ui.keyCode.ENTER:
15256                  // Toggle (cancel delayed activation, allow collapsing)
15257                  event.preventDefault();
15258                  clearTimeout( this.activating );
15259                  // Determine if we should collapse or activate
15260                  this._activate( selectedIndex === this.options.active ? false : selectedIndex );
15261                  return;
15262              default:
15263                  return;
15264          }
15265  
15266          // Focus the appropriate tab, based on which key was pressed
15267          event.preventDefault();
15268          clearTimeout( this.activating );
15269          selectedIndex = this._focusNextTab( selectedIndex, goingForward );
15270  
15271          // Navigating with control key will prevent automatic activation
15272          if ( !event.ctrlKey ) {
15273              // Update aria-selected immediately so that AT think the tab is already selected.
15274              // Otherwise AT may confuse the user by stating that they need to activate the tab,
15275              // but the tab will already be activated by the time the announcement finishes.
15276              focusedTab.attr( "aria-selected", "false" );
15277              this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
15278  
15279              this.activating = this._delay(function() {
15280                  this.option( "active", selectedIndex );
15281              }, this.delay );
15282          }
15283      },
15284  
15285      _panelKeydown: function( event ) {
15286          if ( this._handlePageNav( event ) ) {
15287              return;
15288          }
15289  
15290          // Ctrl+up moves focus to the current tab
15291          if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
15292              event.preventDefault();
15293              this.active.focus();
15294          }
15295      },
15296  
15297      // Alt+page up/down moves focus to the previous/next tab (and activates)
15298      _handlePageNav: function( event ) {
15299          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
15300              this._activate( this._focusNextTab( this.options.active - 1, false ) );
15301              return true;
15302          }
15303          if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
15304              this._activate( this._focusNextTab( this.options.active + 1, true ) );
15305              return true;
15306          }
15307      },
15308  
15309      _findNextTab: function( index, goingForward ) {
15310          var lastTabIndex = this.tabs.length - 1;
15311  
15312  		function constrain() {
15313              if ( index > lastTabIndex ) {
15314                  index = 0;
15315              }
15316              if ( index < 0 ) {
15317                  index = lastTabIndex;
15318              }
15319              return index;
15320          }
15321  
15322          while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
15323              index = goingForward ? index + 1 : index - 1;
15324          }
15325  
15326          return index;
15327      },
15328  
15329      _focusNextTab: function( index, goingForward ) {
15330          index = this._findNextTab( index, goingForward );
15331          this.tabs.eq( index ).focus();
15332          return index;
15333      },
15334  
15335      _setOption: function( key, value ) {
15336          if ( key === "active" ) {
15337              // _activate() will handle invalid values and update this.options
15338              this._activate( value );
15339              return;
15340          }
15341  
15342          if ( key === "disabled" ) {
15343              // don't use the widget factory's disabled handling
15344              this._setupDisabled( value );
15345              return;
15346          }
15347  
15348          this._super( key, value);
15349  
15350          if ( key === "collapsible" ) {
15351              this.element.toggleClass( "ui-tabs-collapsible", value );
15352              // Setting collapsible: false while collapsed; open first panel
15353              if ( !value && this.options.active === false ) {
15354                  this._activate( 0 );
15355              }
15356          }
15357  
15358          if ( key === "event" ) {
15359              this._setupEvents( value );
15360          }
15361  
15362          if ( key === "heightStyle" ) {
15363              this._setupHeightStyle( value );
15364          }
15365      },
15366  
15367      _sanitizeSelector: function( hash ) {
15368          return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
15369      },
15370  
15371      refresh: function() {
15372          var options = this.options,
15373              lis = this.tablist.children( ":has(a[href])" );
15374  
15375          // get disabled tabs from class attribute from HTML
15376          // this will get converted to a boolean if needed in _refresh()
15377          options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
15378              return lis.index( tab );
15379          });
15380  
15381          this._processTabs();
15382  
15383          // was collapsed or no tabs
15384          if ( options.active === false || !this.anchors.length ) {
15385              options.active = false;
15386              this.active = $();
15387          // was active, but active tab is gone
15388          } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
15389              // all remaining tabs are disabled
15390              if ( this.tabs.length === options.disabled.length ) {
15391                  options.active = false;
15392                  this.active = $();
15393              // activate previous tab
15394              } else {
15395                  this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
15396              }
15397          // was active, active tab still exists
15398          } else {
15399              // make sure active index is correct
15400              options.active = this.tabs.index( this.active );
15401          }
15402  
15403          this._refresh();
15404      },
15405  
15406      _refresh: function() {
15407          this._setupDisabled( this.options.disabled );
15408          this._setupEvents( this.options.event );
15409          this._setupHeightStyle( this.options.heightStyle );
15410  
15411          this.tabs.not( this.active ).attr({
15412              "aria-selected": "false",
15413              "aria-expanded": "false",
15414              tabIndex: -1
15415          });
15416          this.panels.not( this._getPanelForTab( this.active ) )
15417              .hide()
15418              .attr({
15419                  "aria-hidden": "true"
15420              });
15421  
15422          // Make sure one tab is in the tab order
15423          if ( !this.active.length ) {
15424              this.tabs.eq( 0 ).attr( "tabIndex", 0 );
15425          } else {
15426              this.active
15427                  .addClass( "ui-tabs-active ui-state-active" )
15428                  .attr({
15429                      "aria-selected": "true",
15430                      "aria-expanded": "true",
15431                      tabIndex: 0
15432                  });
15433              this._getPanelForTab( this.active )
15434                  .show()
15435                  .attr({
15436                      "aria-hidden": "false"
15437                  });
15438          }
15439      },
15440  
15441      _processTabs: function() {
15442          var that = this;
15443  
15444          this.tablist = this._getList()
15445              .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15446              .attr( "role", "tablist" )
15447  
15448              // Prevent users from focusing disabled tabs via click
15449              .delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
15450                  if ( $( this ).is( ".ui-state-disabled" ) ) {
15451                      event.preventDefault();
15452                  }
15453              })
15454  
15455              // support: IE <9
15456              // Preventing the default action in mousedown doesn't prevent IE
15457              // from focusing the element, so if the anchor gets focused, blur.
15458              // We don't have to worry about focusing the previously focused
15459              // element since clicking on a non-focusable element should focus
15460              // the body anyway.
15461              .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
15462                  if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
15463                      this.blur();
15464                  }
15465              });
15466  
15467          this.tabs = this.tablist.find( "> li:has(a[href])" )
15468              .addClass( "ui-state-default ui-corner-top" )
15469              .attr({
15470                  role: "tab",
15471                  tabIndex: -1
15472              });
15473  
15474          this.anchors = this.tabs.map(function() {
15475                  return $( "a", this )[ 0 ];
15476              })
15477              .addClass( "ui-tabs-anchor" )
15478              .attr({
15479                  role: "presentation",
15480                  tabIndex: -1
15481              });
15482  
15483          this.panels = $();
15484  
15485          this.anchors.each(function( i, anchor ) {
15486              var selector, panel, panelId,
15487                  anchorId = $( anchor ).uniqueId().attr( "id" ),
15488                  tab = $( anchor ).closest( "li" ),
15489                  originalAriaControls = tab.attr( "aria-controls" );
15490  
15491              // inline tab
15492              if ( that._isLocal( anchor ) ) {
15493                  selector = anchor.hash;
15494                  panelId = selector.substring( 1 );
15495                  panel = that.element.find( that._sanitizeSelector( selector ) );
15496              // remote tab
15497              } else {
15498                  // If the tab doesn't already have aria-controls,
15499                  // generate an id by using a throw-away element
15500                  panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
15501                  selector = "#" + panelId;
15502                  panel = that.element.find( selector );
15503                  if ( !panel.length ) {
15504                      panel = that._createPanel( panelId );
15505                      panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
15506                  }
15507                  panel.attr( "aria-live", "polite" );
15508              }
15509  
15510              if ( panel.length) {
15511                  that.panels = that.panels.add( panel );
15512              }
15513              if ( originalAriaControls ) {
15514                  tab.data( "ui-tabs-aria-controls", originalAriaControls );
15515              }
15516              tab.attr({
15517                  "aria-controls": panelId,
15518                  "aria-labelledby": anchorId
15519              });
15520              panel.attr( "aria-labelledby", anchorId );
15521          });
15522  
15523          this.panels
15524              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15525              .attr( "role", "tabpanel" );
15526      },
15527  
15528      // allow overriding how to find the list for rare usage scenarios (#7715)
15529      _getList: function() {
15530          return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
15531      },
15532  
15533      _createPanel: function( id ) {
15534          return $( "<div>" )
15535              .attr( "id", id )
15536              .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
15537              .data( "ui-tabs-destroy", true );
15538      },
15539  
15540      _setupDisabled: function( disabled ) {
15541          if ( $.isArray( disabled ) ) {
15542              if ( !disabled.length ) {
15543                  disabled = false;
15544              } else if ( disabled.length === this.anchors.length ) {
15545                  disabled = true;
15546              }
15547          }
15548  
15549          // disable tabs
15550          for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
15551              if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
15552                  $( li )
15553                      .addClass( "ui-state-disabled" )
15554                      .attr( "aria-disabled", "true" );
15555              } else {
15556                  $( li )
15557                      .removeClass( "ui-state-disabled" )
15558                      .removeAttr( "aria-disabled" );
15559              }
15560          }
15561  
15562          this.options.disabled = disabled;
15563      },
15564  
15565      _setupEvents: function( event ) {
15566          var events = {};
15567          if ( event ) {
15568              $.each( event.split(" "), function( index, eventName ) {
15569                  events[ eventName ] = "_eventHandler";
15570              });
15571          }
15572  
15573          this._off( this.anchors.add( this.tabs ).add( this.panels ) );
15574          // Always prevent the default action, even when disabled
15575          this._on( true, this.anchors, {
15576              click: function( event ) {
15577                  event.preventDefault();
15578              }
15579          });
15580          this._on( this.anchors, events );
15581          this._on( this.tabs, { keydown: "_tabKeydown" } );
15582          this._on( this.panels, { keydown: "_panelKeydown" } );
15583  
15584          this._focusable( this.tabs );
15585          this._hoverable( this.tabs );
15586      },
15587  
15588      _setupHeightStyle: function( heightStyle ) {
15589          var maxHeight,
15590              parent = this.element.parent();
15591  
15592          if ( heightStyle === "fill" ) {
15593              maxHeight = parent.height();
15594              maxHeight -= this.element.outerHeight() - this.element.height();
15595  
15596              this.element.siblings( ":visible" ).each(function() {
15597                  var elem = $( this ),
15598                      position = elem.css( "position" );
15599  
15600                  if ( position === "absolute" || position === "fixed" ) {
15601                      return;
15602                  }
15603                  maxHeight -= elem.outerHeight( true );
15604              });
15605  
15606              this.element.children().not( this.panels ).each(function() {
15607                  maxHeight -= $( this ).outerHeight( true );
15608              });
15609  
15610              this.panels.each(function() {
15611                  $( this ).height( Math.max( 0, maxHeight -
15612                      $( this ).innerHeight() + $( this ).height() ) );
15613              })
15614              .css( "overflow", "auto" );
15615          } else if ( heightStyle === "auto" ) {
15616              maxHeight = 0;
15617              this.panels.each(function() {
15618                  maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15619              }).height( maxHeight );
15620          }
15621      },
15622  
15623      _eventHandler: function( event ) {
15624          var options = this.options,
15625              active = this.active,
15626              anchor = $( event.currentTarget ),
15627              tab = anchor.closest( "li" ),
15628              clickedIsActive = tab[ 0 ] === active[ 0 ],
15629              collapsing = clickedIsActive && options.collapsible,
15630              toShow = collapsing ? $() : this._getPanelForTab( tab ),
15631              toHide = !active.length ? $() : this._getPanelForTab( active ),
15632              eventData = {
15633                  oldTab: active,
15634                  oldPanel: toHide,
15635                  newTab: collapsing ? $() : tab,
15636                  newPanel: toShow
15637              };
15638  
15639          event.preventDefault();
15640  
15641          if ( tab.hasClass( "ui-state-disabled" ) ||
15642                  // tab is already loading
15643                  tab.hasClass( "ui-tabs-loading" ) ||
15644                  // can't switch durning an animation
15645                  this.running ||
15646                  // click on active header, but not collapsible
15647                  ( clickedIsActive && !options.collapsible ) ||
15648                  // allow canceling activation
15649                  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
15650              return;
15651          }
15652  
15653          options.active = collapsing ? false : this.tabs.index( tab );
15654  
15655          this.active = clickedIsActive ? $() : tab;
15656          if ( this.xhr ) {
15657              this.xhr.abort();
15658          }
15659  
15660          if ( !toHide.length && !toShow.length ) {
15661              $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
15662          }
15663  
15664          if ( toShow.length ) {
15665              this.load( this.tabs.index( tab ), event );
15666          }
15667          this._toggle( event, eventData );
15668      },
15669  
15670      // handles show/hide for selecting tabs
15671      _toggle: function( event, eventData ) {
15672          var that = this,
15673              toShow = eventData.newPanel,
15674              toHide = eventData.oldPanel;
15675  
15676          this.running = true;
15677  
15678  		function complete() {
15679              that.running = false;
15680              that._trigger( "activate", event, eventData );
15681          }
15682  
15683  		function show() {
15684              eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
15685  
15686              if ( toShow.length && that.options.show ) {
15687                  that._show( toShow, that.options.show, complete );
15688              } else {
15689                  toShow.show();
15690                  complete();
15691              }
15692          }
15693  
15694          // start out by hiding, then showing, then completing
15695          if ( toHide.length && this.options.hide ) {
15696              this._hide( toHide, this.options.hide, function() {
15697                  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15698                  show();
15699              });
15700          } else {
15701              eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
15702              toHide.hide();
15703              show();
15704          }
15705  
15706          toHide.attr( "aria-hidden", "true" );
15707          eventData.oldTab.attr({
15708              "aria-selected": "false",
15709              "aria-expanded": "false"
15710          });
15711          // If we're switching tabs, remove the old tab from the tab order.
15712          // If we're opening from collapsed state, remove the previous tab from the tab order.
15713          // If we're collapsing, then keep the collapsing tab in the tab order.
15714          if ( toShow.length && toHide.length ) {
15715              eventData.oldTab.attr( "tabIndex", -1 );
15716          } else if ( toShow.length ) {
15717              this.tabs.filter(function() {
15718                  return $( this ).attr( "tabIndex" ) === 0;
15719              })
15720              .attr( "tabIndex", -1 );
15721          }
15722  
15723          toShow.attr( "aria-hidden", "false" );
15724          eventData.newTab.attr({
15725              "aria-selected": "true",
15726              "aria-expanded": "true",
15727              tabIndex: 0
15728          });
15729      },
15730  
15731      _activate: function( index ) {
15732          var anchor,
15733              active = this._findActive( index );
15734  
15735          // trying to activate the already active panel
15736          if ( active[ 0 ] === this.active[ 0 ] ) {
15737              return;
15738          }
15739  
15740          // trying to collapse, simulate a click on the current active header
15741          if ( !active.length ) {
15742              active = this.active;
15743          }
15744  
15745          anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
15746          this._eventHandler({
15747              target: anchor,
15748              currentTarget: anchor,
15749              preventDefault: $.noop
15750          });
15751      },
15752  
15753      _findActive: function( index ) {
15754          return index === false ? $() : this.tabs.eq( index );
15755      },
15756  
15757      _getIndex: function( index ) {
15758          // meta-function to give users option to provide a href string instead of a numerical index.
15759          if ( typeof index === "string" ) {
15760              index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
15761          }
15762  
15763          return index;
15764      },
15765  
15766      _destroy: function() {
15767          if ( this.xhr ) {
15768              this.xhr.abort();
15769          }
15770  
15771          this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
15772  
15773          this.tablist
15774              .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
15775              .removeAttr( "role" );
15776  
15777          this.anchors
15778              .removeClass( "ui-tabs-anchor" )
15779              .removeAttr( "role" )
15780              .removeAttr( "tabIndex" )
15781              .removeUniqueId();
15782  
15783          this.tablist.unbind( this.eventNamespace );
15784  
15785          this.tabs.add( this.panels ).each(function() {
15786              if ( $.data( this, "ui-tabs-destroy" ) ) {
15787                  $( this ).remove();
15788              } else {
15789                  $( this )
15790                      .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
15791                          "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
15792                      .removeAttr( "tabIndex" )
15793                      .removeAttr( "aria-live" )
15794                      .removeAttr( "aria-busy" )
15795                      .removeAttr( "aria-selected" )
15796                      .removeAttr( "aria-labelledby" )
15797                      .removeAttr( "aria-hidden" )
15798                      .removeAttr( "aria-expanded" )
15799                      .removeAttr( "role" );
15800              }
15801          });
15802  
15803          this.tabs.each(function() {
15804              var li = $( this ),
15805                  prev = li.data( "ui-tabs-aria-controls" );
15806              if ( prev ) {
15807                  li
15808                      .attr( "aria-controls", prev )
15809                      .removeData( "ui-tabs-aria-controls" );
15810              } else {
15811                  li.removeAttr( "aria-controls" );
15812              }
15813          });
15814  
15815          this.panels.show();
15816  
15817          if ( this.options.heightStyle !== "content" ) {
15818              this.panels.css( "height", "" );
15819          }
15820      },
15821  
15822      enable: function( index ) {
15823          var disabled = this.options.disabled;
15824          if ( disabled === false ) {
15825              return;
15826          }
15827  
15828          if ( index === undefined ) {
15829              disabled = false;
15830          } else {
15831              index = this._getIndex( index );
15832              if ( $.isArray( disabled ) ) {
15833                  disabled = $.map( disabled, function( num ) {
15834                      return num !== index ? num : null;
15835                  });
15836              } else {
15837                  disabled = $.map( this.tabs, function( li, num ) {
15838                      return num !== index ? num : null;
15839                  });
15840              }
15841          }
15842          this._setupDisabled( disabled );
15843      },
15844  
15845      disable: function( index ) {
15846          var disabled = this.options.disabled;
15847          if ( disabled === true ) {
15848              return;
15849          }
15850  
15851          if ( index === undefined ) {
15852              disabled = true;
15853          } else {
15854              index = this._getIndex( index );
15855              if ( $.inArray( index, disabled ) !== -1 ) {
15856                  return;
15857              }
15858              if ( $.isArray( disabled ) ) {
15859                  disabled = $.merge( [ index ], disabled ).sort();
15860              } else {
15861                  disabled = [ index ];
15862              }
15863          }
15864          this._setupDisabled( disabled );
15865      },
15866  
15867      load: function( index, event ) {
15868          index = this._getIndex( index );
15869          var that = this,
15870              tab = this.tabs.eq( index ),
15871              anchor = tab.find( ".ui-tabs-anchor" ),
15872              panel = this._getPanelForTab( tab ),
15873              eventData = {
15874                  tab: tab,
15875                  panel: panel
15876              };
15877  
15878          // not remote
15879          if ( this._isLocal( anchor[ 0 ] ) ) {
15880              return;
15881          }
15882  
15883          this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
15884  
15885          // support: jQuery <1.8
15886          // jQuery <1.8 returns false if the request is canceled in beforeSend,
15887          // but as of 1.8, $.ajax() always returns a jqXHR object.
15888          if ( this.xhr && this.xhr.statusText !== "canceled" ) {
15889              tab.addClass( "ui-tabs-loading" );
15890              panel.attr( "aria-busy", "true" );
15891  
15892              this.xhr
15893                  .success(function( response ) {
15894                      // support: jQuery <1.8
15895                      // http://bugs.jquery.com/ticket/11778
15896                      setTimeout(function() {
15897                          panel.html( response );
15898                          that._trigger( "load", event, eventData );
15899                      }, 1 );
15900                  })
15901                  .complete(function( jqXHR, status ) {
15902                      // support: jQuery <1.8
15903                      // http://bugs.jquery.com/ticket/11778
15904                      setTimeout(function() {
15905                          if ( status === "abort" ) {
15906                              that.panels.stop( false, true );
15907                          }
15908  
15909                          tab.removeClass( "ui-tabs-loading" );
15910                          panel.removeAttr( "aria-busy" );
15911  
15912                          if ( jqXHR === that.xhr ) {
15913                              delete that.xhr;
15914                          }
15915                      }, 1 );
15916                  });
15917          }
15918      },
15919  
15920      _ajaxSettings: function( anchor, event, eventData ) {
15921          var that = this;
15922          return {
15923              url: anchor.attr( "href" ),
15924              beforeSend: function( jqXHR, settings ) {
15925                  return that._trigger( "beforeLoad", event,
15926                      $.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
15927              }
15928          };
15929      },
15930  
15931      _getPanelForTab: function( tab ) {
15932          var id = $( tab ).attr( "aria-controls" );
15933          return this.element.find( this._sanitizeSelector( "#" + id ) );
15934      }
15935  });
15936  
15937  
15938  /*!
15939   * jQuery UI Tooltip 1.11.1
15940   * http://jqueryui.com
15941   *
15942   * Copyright 2014 jQuery Foundation and other contributors
15943   * Released under the MIT license.
15944   * http://jquery.org/license
15945   *
15946   * http://api.jqueryui.com/tooltip/
15947   */
15948  
15949  
15950  var tooltip = $.widget( "ui.tooltip", {
15951      version: "1.11.1",
15952      options: {
15953          content: function() {
15954              // support: IE<9, Opera in jQuery <1.7
15955              // .text() can't accept undefined, so coerce to a string
15956              var title = $( this ).attr( "title" ) || "";
15957              // Escape title, since we're going from an attribute to raw HTML
15958              return $( "<a>" ).text( title ).html();
15959          },
15960          hide: true,
15961          // Disabled elements have inconsistent behavior across browsers (#8661)
15962          items: "[title]:not([disabled])",
15963          position: {
15964              my: "left top+15",
15965              at: "left bottom",
15966              collision: "flipfit flip"
15967          },
15968          show: true,
15969          tooltipClass: null,
15970          track: false,
15971  
15972          // callbacks
15973          close: null,
15974          open: null
15975      },
15976  
15977      _addDescribedBy: function( elem, id ) {
15978          var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
15979          describedby.push( id );
15980          elem
15981              .data( "ui-tooltip-id", id )
15982              .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
15983      },
15984  
15985      _removeDescribedBy: function( elem ) {
15986          var id = elem.data( "ui-tooltip-id" ),
15987              describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
15988              index = $.inArray( id, describedby );
15989  
15990          if ( index !== -1 ) {
15991              describedby.splice( index, 1 );
15992          }
15993  
15994          elem.removeData( "ui-tooltip-id" );
15995          describedby = $.trim( describedby.join( " " ) );
15996          if ( describedby ) {
15997              elem.attr( "aria-describedby", describedby );
15998          } else {
15999              elem.removeAttr( "aria-describedby" );
16000          }
16001      },
16002  
16003      _create: function() {
16004          this._on({
16005              mouseover: "open",
16006              focusin: "open"
16007          });
16008  
16009          // IDs of generated tooltips, needed for destroy
16010          this.tooltips = {};
16011          // IDs of parent tooltips where we removed the title attribute
16012          this.parents = {};
16013  
16014          if ( this.options.disabled ) {
16015              this._disable();
16016          }
16017  
16018          // Append the aria-live region so tooltips announce correctly
16019          this.liveRegion = $( "<div>" )
16020              .attr({
16021                  role: "log",
16022                  "aria-live": "assertive",
16023                  "aria-relevant": "additions"
16024              })
16025              .addClass( "ui-helper-hidden-accessible" )
16026              .appendTo( this.document[ 0 ].body );
16027      },
16028  
16029      _setOption: function( key, value ) {
16030          var that = this;
16031  
16032          if ( key === "disabled" ) {
16033              this[ value ? "_disable" : "_enable" ]();
16034              this.options[ key ] = value;
16035              // disable element style changes
16036              return;
16037          }
16038  
16039          this._super( key, value );
16040  
16041          if ( key === "content" ) {
16042              $.each( this.tooltips, function( id, element ) {
16043                  that._updateContent( element );
16044              });
16045          }
16046      },
16047  
16048      _disable: function() {
16049          var that = this;
16050  
16051          // close open tooltips
16052          $.each( this.tooltips, function( id, element ) {
16053              var event = $.Event( "blur" );
16054              event.target = event.currentTarget = element[0];
16055              that.close( event, true );
16056          });
16057  
16058          // remove title attributes to prevent native tooltips
16059          this.element.find( this.options.items ).addBack().each(function() {
16060              var element = $( this );
16061              if ( element.is( "[title]" ) ) {
16062                  element
16063                      .data( "ui-tooltip-title", element.attr( "title" ) )
16064                      .removeAttr( "title" );
16065              }
16066          });
16067      },
16068  
16069      _enable: function() {
16070          // restore title attributes
16071          this.element.find( this.options.items ).addBack().each(function() {
16072              var element = $( this );
16073              if ( element.data( "ui-tooltip-title" ) ) {
16074                  element.attr( "title", element.data( "ui-tooltip-title" ) );
16075              }
16076          });
16077      },
16078  
16079      open: function( event ) {
16080          var that = this,
16081              target = $( event ? event.target : this.element )
16082                  // we need closest here due to mouseover bubbling,
16083                  // but always pointing at the same event target
16084                  .closest( this.options.items );
16085  
16086          // No element to show a tooltip for or the tooltip is already open
16087          if ( !target.length || target.data( "ui-tooltip-id" ) ) {
16088              return;
16089          }
16090  
16091          if ( target.attr( "title" ) ) {
16092              target.data( "ui-tooltip-title", target.attr( "title" ) );
16093          }
16094  
16095          target.data( "ui-tooltip-open", true );
16096  
16097          // kill parent tooltips, custom or native, for hover
16098          if ( event && event.type === "mouseover" ) {
16099              target.parents().each(function() {
16100                  var parent = $( this ),
16101                      blurEvent;
16102                  if ( parent.data( "ui-tooltip-open" ) ) {
16103                      blurEvent = $.Event( "blur" );
16104                      blurEvent.target = blurEvent.currentTarget = this;
16105                      that.close( blurEvent, true );
16106                  }
16107                  if ( parent.attr( "title" ) ) {
16108                      parent.uniqueId();
16109                      that.parents[ this.id ] = {
16110                          element: this,
16111                          title: parent.attr( "title" )
16112                      };
16113                      parent.attr( "title", "" );
16114                  }
16115              });
16116          }
16117  
16118          this._updateContent( target, event );
16119      },
16120  
16121      _updateContent: function( target, event ) {
16122          var content,
16123              contentOption = this.options.content,
16124              that = this,
16125              eventType = event ? event.type : null;
16126  
16127          if ( typeof contentOption === "string" ) {
16128              return this._open( event, target, contentOption );
16129          }
16130  
16131          content = contentOption.call( target[0], function( response ) {
16132              // ignore async response if tooltip was closed already
16133              if ( !target.data( "ui-tooltip-open" ) ) {
16134                  return;
16135              }
16136              // IE may instantly serve a cached response for ajax requests
16137              // delay this call to _open so the other call to _open runs first
16138              that._delay(function() {
16139                  // jQuery creates a special event for focusin when it doesn't
16140                  // exist natively. To improve performance, the native event
16141                  // object is reused and the type is changed. Therefore, we can't
16142                  // rely on the type being correct after the event finished
16143                  // bubbling, so we set it back to the previous value. (#8740)
16144                  if ( event ) {
16145                      event.type = eventType;
16146                  }
16147                  this._open( event, target, response );
16148              });
16149          });
16150          if ( content ) {
16151              this._open( event, target, content );
16152          }
16153      },
16154  
16155      _open: function( event, target, content ) {
16156          var tooltip, events, delayedShow, a11yContent,
16157              positionOption = $.extend( {}, this.options.position );
16158  
16159          if ( !content ) {
16160              return;
16161          }
16162  
16163          // Content can be updated multiple times. If the tooltip already
16164          // exists, then just update the content and bail.
16165          tooltip = this._find( target );
16166          if ( tooltip.length ) {
16167              tooltip.find( ".ui-tooltip-content" ).html( content );
16168              return;
16169          }
16170  
16171          // if we have a title, clear it to prevent the native tooltip
16172          // we have to check first to avoid defining a title if none exists
16173          // (we don't want to cause an element to start matching [title])
16174          //
16175          // We use removeAttr only for key events, to allow IE to export the correct
16176          // accessible attributes. For mouse events, set to empty string to avoid
16177          // native tooltip showing up (happens only when removing inside mouseover).
16178          if ( target.is( "[title]" ) ) {
16179              if ( event && event.type === "mouseover" ) {
16180                  target.attr( "title", "" );
16181              } else {
16182                  target.removeAttr( "title" );
16183              }
16184          }
16185  
16186          tooltip = this._tooltip( target );
16187          this._addDescribedBy( target, tooltip.attr( "id" ) );
16188          tooltip.find( ".ui-tooltip-content" ).html( content );
16189  
16190          // Support: Voiceover on OS X, JAWS on IE <= 9
16191          // JAWS announces deletions even when aria-relevant="additions"
16192          // Voiceover will sometimes re-read the entire log region's contents from the beginning
16193          this.liveRegion.children().hide();
16194          if ( content.clone ) {
16195              a11yContent = content.clone();
16196              a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
16197          } else {
16198              a11yContent = content;
16199          }
16200          $( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
16201  
16202  		function position( event ) {
16203              positionOption.of = event;
16204              if ( tooltip.is( ":hidden" ) ) {
16205                  return;
16206              }
16207              tooltip.position( positionOption );
16208          }
16209          if ( this.options.track && event && /^mouse/.test( event.type ) ) {
16210              this._on( this.document, {
16211                  mousemove: position
16212              });
16213              // trigger once to override element-relative positioning
16214              position( event );
16215          } else {
16216              tooltip.position( $.extend({
16217                  of: target
16218              }, this.options.position ) );
16219          }
16220  
16221          this.hiding = false;
16222          this.closing = false;
16223          tooltip.hide();
16224  
16225          this._show( tooltip, this.options.show );
16226          // Handle tracking tooltips that are shown with a delay (#8644). As soon
16227          // as the tooltip is visible, position the tooltip using the most recent
16228          // event.
16229          if ( this.options.show && this.options.show.delay ) {
16230              delayedShow = this.delayedShow = setInterval(function() {
16231                  if ( tooltip.is( ":visible" ) ) {
16232                      position( positionOption.of );
16233                      clearInterval( delayedShow );
16234                  }
16235              }, $.fx.interval );
16236          }
16237  
16238          this._trigger( "open", event, { tooltip: tooltip } );
16239  
16240          events = {
16241              keyup: function( event ) {
16242                  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
16243                      var fakeEvent = $.Event(event);
16244                      fakeEvent.currentTarget = target[0];
16245                      this.close( fakeEvent, true );
16246                  }
16247              }
16248          };
16249  
16250          // Only bind remove handler for delegated targets. Non-delegated
16251          // tooltips will handle this in destroy.
16252          if ( target[ 0 ] !== this.element[ 0 ] ) {
16253              events.remove = function() {
16254                  this._removeTooltip( tooltip );
16255              };
16256          }
16257  
16258          if ( !event || event.type === "mouseover" ) {
16259              events.mouseleave = "close";
16260          }
16261          if ( !event || event.type === "focusin" ) {
16262              events.focusout = "close";
16263          }
16264          this._on( true, target, events );
16265      },
16266  
16267      close: function( event ) {
16268          var that = this,
16269              target = $( event ? event.currentTarget : this.element ),
16270              tooltip = this._find( target );
16271  
16272          // disabling closes the tooltip, so we need to track when we're closing
16273          // to avoid an infinite loop in case the tooltip becomes disabled on close
16274          if ( this.closing ) {
16275              return;
16276          }
16277  
16278          // Clear the interval for delayed tracking tooltips
16279          clearInterval( this.delayedShow );
16280  
16281          // only set title if we had one before (see comment in _open())
16282          // If the title attribute has changed since open(), don't restore
16283          if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
16284              target.attr( "title", target.data( "ui-tooltip-title" ) );
16285          }
16286  
16287          this._removeDescribedBy( target );
16288  
16289          this.hiding = true;
16290          tooltip.stop( true );
16291          this._hide( tooltip, this.options.hide, function() {
16292              that._removeTooltip( $( this ) );
16293              this.hiding = false;
16294              this.closing = false;
16295          });
16296  
16297          target.removeData( "ui-tooltip-open" );
16298          this._off( target, "mouseleave focusout keyup" );
16299  
16300          // Remove 'remove' binding only on delegated targets
16301          if ( target[ 0 ] !== this.element[ 0 ] ) {
16302              this._off( target, "remove" );
16303          }
16304          this._off( this.document, "mousemove" );
16305  
16306          if ( event && event.type === "mouseleave" ) {
16307              $.each( this.parents, function( id, parent ) {
16308                  $( parent.element ).attr( "title", parent.title );
16309                  delete that.parents[ id ];
16310              });
16311          }
16312  
16313          this.closing = true;
16314          this._trigger( "close", event, { tooltip: tooltip } );
16315          if ( !this.hiding ) {
16316              this.closing = false;
16317          }
16318      },
16319  
16320      _tooltip: function( element ) {
16321          var tooltip = $( "<div>" )
16322                  .attr( "role", "tooltip" )
16323                  .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
16324                      ( this.options.tooltipClass || "" ) ),
16325              id = tooltip.uniqueId().attr( "id" );
16326  
16327          $( "<div>" )
16328              .addClass( "ui-tooltip-content" )
16329              .appendTo( tooltip );
16330  
16331          tooltip.appendTo( this.document[0].body );
16332          this.tooltips[ id ] = element;
16333          return tooltip;
16334      },
16335  
16336      _find: function( target ) {
16337          var id = target.data( "ui-tooltip-id" );
16338          return id ? $( "#" + id ) : $();
16339      },
16340  
16341      _removeTooltip: function( tooltip ) {
16342          tooltip.remove();
16343          delete this.tooltips[ tooltip.attr( "id" ) ];
16344      },
16345  
16346      _destroy: function() {
16347          var that = this;
16348  
16349          // close open tooltips
16350          $.each( this.tooltips, function( id, element ) {
16351              // Delegate to close method to handle common cleanup
16352              var event = $.Event( "blur" );
16353              event.target = event.currentTarget = element[0];
16354              that.close( event, true );
16355  
16356              // Remove immediately; destroying an open tooltip doesn't use the
16357              // hide animation
16358              $( "#" + id ).remove();
16359  
16360              // Restore the title
16361              if ( element.data( "ui-tooltip-title" ) ) {
16362                  // If the title attribute has changed since open(), don't restore
16363                  if ( !element.attr( "title" ) ) {
16364                      element.attr( "title", element.data( "ui-tooltip-title" ) );
16365                  }
16366                  element.removeData( "ui-tooltip-title" );
16367              }
16368          });
16369          this.liveRegion.remove();
16370      }
16371  });
16372  
16373  
16374  
16375  }));


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1