b2evolution PHP Cross Reference Blogging Systems

Source: /rsc/js/jquery/jquery.ui.all.js - 11802 lines - 377848 bytes - Summary - Text - Print

   1  /*!
   2   * jQuery UI 1.8.18
   3   *
   4   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
   5   * Dual licensed under the MIT or GPL Version 2 licenses.
   6   * http://jquery.org/license
   7   *
   8   * http://docs.jquery.com/UI
   9   */
  10  (function( $, undefined ) {
  11  
  12  // prevent duplicate loading
  13  // this is only a problem because we proxy existing functions
  14  // and we don't want to double proxy them
  15  $.ui = $.ui || {};
  16  if ( $.ui.version ) {
  17      return;
  18  }
  19  
  20  $.extend( $.ui, {
  21      version: "1.8.18",
  22  
  23      keyCode: {
  24          ALT: 18,
  25          BACKSPACE: 8,
  26          CAPS_LOCK: 20,
  27          COMMA: 188,
  28          COMMAND: 91,
  29          COMMAND_LEFT: 91, // COMMAND
  30          COMMAND_RIGHT: 93,
  31          CONTROL: 17,
  32          DELETE: 46,
  33          DOWN: 40,
  34          END: 35,
  35          ENTER: 13,
  36          ESCAPE: 27,
  37          HOME: 36,
  38          INSERT: 45,
  39          LEFT: 37,
  40          MENU: 93, // COMMAND_RIGHT
  41          NUMPAD_ADD: 107,
  42          NUMPAD_DECIMAL: 110,
  43          NUMPAD_DIVIDE: 111,
  44          NUMPAD_ENTER: 108,
  45          NUMPAD_MULTIPLY: 106,
  46          NUMPAD_SUBTRACT: 109,
  47          PAGE_DOWN: 34,
  48          PAGE_UP: 33,
  49          PERIOD: 190,
  50          RIGHT: 39,
  51          SHIFT: 16,
  52          SPACE: 32,
  53          TAB: 9,
  54          UP: 38,
  55          WINDOWS: 91 // COMMAND
  56      }
  57  });
  58  
  59  // plugins
  60  $.fn.extend({
  61      propAttr: $.fn.prop || $.fn.attr,
  62  
  63      _focus: $.fn.focus,
  64      focus: function( delay, fn ) {
  65          return typeof delay === "number" ?
  66              this.each(function() {
  67                  var elem = this;
  68                  setTimeout(function() {
  69                      $( elem ).focus();
  70                      if ( fn ) {
  71                          fn.call( elem );
  72                      }
  73                  }, delay );
  74              }) :
  75              this._focus.apply( this, arguments );
  76      },
  77  
  78      scrollParent: function() {
  79          var scrollParent;
  80          if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
  81              scrollParent = this.parents().filter(function() {
  82                  return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
  83              }).eq(0);
  84          } else {
  85              scrollParent = this.parents().filter(function() {
  86                  return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
  87              }).eq(0);
  88          }
  89  
  90          return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
  91      },
  92  
  93      zIndex: function( zIndex ) {
  94          if ( zIndex !== undefined ) {
  95              return this.css( "zIndex", zIndex );
  96          }
  97  
  98          if ( this.length ) {
  99              var elem = $( this[ 0 ] ), position, value;
 100              while ( elem.length && elem[ 0 ] !== document ) {
 101                  // Ignore z-index if position is set to a value where z-index is ignored by the browser
 102                  // This makes behavior of this function consistent across browsers
 103                  // WebKit always returns auto if the element is positioned
 104                  position = elem.css( "position" );
 105                  if ( position === "absolute" || position === "relative" || position === "fixed" ) {
 106                      // IE returns 0 when zIndex is not specified
 107                      // other browsers return a string
 108                      // we ignore the case of nested elements with an explicit value of 0
 109                      // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
 110                      value = parseInt( elem.css( "zIndex" ), 10 );
 111                      if ( !isNaN( value ) && value !== 0 ) {
 112                          return value;
 113                      }
 114                  }
 115                  elem = elem.parent();
 116              }
 117          }
 118  
 119          return 0;
 120      },
 121  
 122      disableSelection: function() {
 123          return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
 124              ".ui-disableSelection", function( event ) {
 125                  event.preventDefault();
 126              });
 127      },
 128  
 129      enableSelection: function() {
 130          return this.unbind( ".ui-disableSelection" );
 131      }
 132  });
 133  
 134  $.each( [ "Width", "Height" ], function( i, name ) {
 135      var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
 136          type = name.toLowerCase(),
 137          orig = {
 138              innerWidth: $.fn.innerWidth,
 139              innerHeight: $.fn.innerHeight,
 140              outerWidth: $.fn.outerWidth,
 141              outerHeight: $.fn.outerHeight
 142          };
 143  
 144  	function reduce( elem, size, border, margin ) {
 145          $.each( side, function() {
 146              size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
 147              if ( border ) {
 148                  size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
 149              }
 150              if ( margin ) {
 151                  size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
 152              }
 153          });
 154          return size;
 155      }
 156  
 157      $.fn[ "inner" + name ] = function( size ) {
 158          if ( size === undefined ) {
 159              return orig[ "inner" + name ].call( this );
 160          }
 161  
 162          return this.each(function() {
 163              $( this ).css( type, reduce( this, size ) + "px" );
 164          });
 165      };
 166  
 167      $.fn[ "outer" + name] = function( size, margin ) {
 168          if ( typeof size !== "number" ) {
 169              return orig[ "outer" + name ].call( this, size );
 170          }
 171  
 172          return this.each(function() {
 173              $( this).css( type, reduce( this, size, true, margin ) + "px" );
 174          });
 175      };
 176  });
 177  
 178  // selectors
 179  function focusable( element, isTabIndexNotNaN ) {
 180      var nodeName = element.nodeName.toLowerCase();
 181      if ( "area" === nodeName ) {
 182          var map = element.parentNode,
 183              mapName = map.name,
 184              img;
 185          if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
 186              return false;
 187          }
 188          img = $( "img[usemap=#" + mapName + "]" )[0];
 189          return !!img && visible( img );
 190      }
 191      return ( /input|select|textarea|button|object/.test( nodeName )
 192          ? !element.disabled
 193          : "a" == nodeName
 194              ? element.href || isTabIndexNotNaN
 195              : isTabIndexNotNaN)
 196          // the element and all of its ancestors must be visible
 197          && visible( element );
 198  }
 199  
 200  function visible( element ) {
 201      return !$( element ).parents().andSelf().filter(function() {
 202          return $.curCSS( this, "visibility" ) === "hidden" ||
 203              $.expr.filters.hidden( this );
 204      }).length;
 205  }
 206  
 207  $.extend( $.expr[ ":" ], {
 208      data: function( elem, i, match ) {
 209          return !!$.data( elem, match[ 3 ] );
 210      },
 211  
 212      focusable: function( element ) {
 213          return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
 214      },
 215  
 216      tabbable: function( element ) {
 217          var tabIndex = $.attr( element, "tabindex" ),
 218              isTabIndexNaN = isNaN( tabIndex );
 219          return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
 220      }
 221  });
 222  
 223  // support
 224  $(function() {
 225      var body = document.body,
 226          div = body.appendChild( div = document.createElement( "div" ) );
 227  
 228      // access offsetHeight before setting the style to prevent a layout bug
 229      // in IE 9 which causes the elemnt to continue to take up space even
 230      // after it is removed from the DOM (#8026)
 231      div.offsetHeight;
 232  
 233      $.extend( div.style, {
 234          minHeight: "100px",
 235          height: "auto",
 236          padding: 0,
 237          borderWidth: 0
 238      });
 239  
 240      $.support.minHeight = div.offsetHeight === 100;
 241      $.support.selectstart = "onselectstart" in div;
 242  
 243      // set display to none to avoid a layout bug in IE
 244      // http://dev.jquery.com/ticket/4014
 245      body.removeChild( div ).style.display = "none";
 246  });
 247  
 248  
 249  
 250  
 251  
 252  // deprecated
 253  $.extend( $.ui, {
 254      // $.ui.plugin is deprecated.  Use the proxy pattern instead.
 255      plugin: {
 256          add: function( module, option, set ) {
 257              var proto = $.ui[ module ].prototype;
 258              for ( var i in set ) {
 259                  proto.plugins[ i ] = proto.plugins[ i ] || [];
 260                  proto.plugins[ i ].push( [ option, set[ i ] ] );
 261              }
 262          },
 263          call: function( instance, name, args ) {
 264              var set = instance.plugins[ name ];
 265              if ( !set || !instance.element[ 0 ].parentNode ) {
 266                  return;
 267              }
 268      
 269              for ( var i = 0; i < set.length; i++ ) {
 270                  if ( instance.options[ set[ i ][ 0 ] ] ) {
 271                      set[ i ][ 1 ].apply( instance.element, args );
 272                  }
 273              }
 274          }
 275      },
 276      
 277      // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
 278      contains: function( a, b ) {
 279          return document.compareDocumentPosition ?
 280              a.compareDocumentPosition( b ) & 16 :
 281              a !== b && a.contains( b );
 282      },
 283      
 284      // only used by resizable
 285      hasScroll: function( el, a ) {
 286      
 287          //If overflow is hidden, the element might have extra content, but the user wants to hide it
 288          if ( $( el ).css( "overflow" ) === "hidden") {
 289              return false;
 290          }
 291      
 292          var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
 293              has = false;
 294      
 295          if ( el[ scroll ] > 0 ) {
 296              return true;
 297          }
 298      
 299          // TODO: determine which cases actually cause this to happen
 300          // if the element doesn't have the scroll set, see if it's possible to
 301          // set the scroll
 302          el[ scroll ] = 1;
 303          has = ( el[ scroll ] > 0 );
 304          el[ scroll ] = 0;
 305          return has;
 306      },
 307      
 308      // these are odd functions, fix the API or move into individual plugins
 309      isOverAxis: function( x, reference, size ) {
 310          //Determines when x coordinate is over "b" element axis
 311          return ( x > reference ) && ( x < ( reference + size ) );
 312      },
 313      isOver: function( y, x, top, left, height, width ) {
 314          //Determines when x, y coordinates is over "b" element
 315          return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
 316      }
 317  });
 318  
 319  })( jQuery );
 320  /*!
 321   * jQuery UI Widget 1.8.18
 322   *
 323   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 324   * Dual licensed under the MIT or GPL Version 2 licenses.
 325   * http://jquery.org/license
 326   *
 327   * http://docs.jquery.com/UI/Widget
 328   */
 329  (function( $, undefined ) {
 330  
 331  // jQuery 1.4+
 332  if ( $.cleanData ) {
 333      var _cleanData = $.cleanData;
 334      $.cleanData = function( elems ) {
 335          for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
 336              try {
 337                  $( elem ).triggerHandler( "remove" );
 338              // http://bugs.jquery.com/ticket/8235
 339              } catch( e ) {}
 340          }
 341          _cleanData( elems );
 342      };
 343  } else {
 344      var _remove = $.fn.remove;
 345      $.fn.remove = function( selector, keepData ) {
 346          return this.each(function() {
 347              if ( !keepData ) {
 348                  if ( !selector || $.filter( selector, [ this ] ).length ) {
 349                      $( "*", this ).add( [ this ] ).each(function() {
 350                          try {
 351                              $( this ).triggerHandler( "remove" );
 352                          // http://bugs.jquery.com/ticket/8235
 353                          } catch( e ) {}
 354                      });
 355                  }
 356              }
 357              return _remove.call( $(this), selector, keepData );
 358          });
 359      };
 360  }
 361  
 362  $.widget = function( name, base, prototype ) {
 363      var namespace = name.split( "." )[ 0 ],
 364          fullName;
 365      name = name.split( "." )[ 1 ];
 366      fullName = namespace + "-" + name;
 367  
 368      if ( !prototype ) {
 369          prototype = base;
 370          base = $.Widget;
 371      }
 372  
 373      // create selector for plugin
 374      $.expr[ ":" ][ fullName ] = function( elem ) {
 375          return !!$.data( elem, name );
 376      };
 377  
 378      $[ namespace ] = $[ namespace ] || {};
 379      $[ namespace ][ name ] = function( options, element ) {
 380          // allow instantiation without initializing for simple inheritance
 381          if ( arguments.length ) {
 382              this._createWidget( options, element );
 383          }
 384      };
 385  
 386      var basePrototype = new base();
 387      // we need to make the options hash a property directly on the new instance
 388      // otherwise we'll modify the options hash on the prototype that we're
 389      // inheriting from
 390  //    $.each( basePrototype, function( key, val ) {
 391  //        if ( $.isPlainObject(val) ) {
 392  //            basePrototype[ key ] = $.extend( {}, val );
 393  //        }
 394  //    });
 395      basePrototype.options = $.extend( true, {}, basePrototype.options );
 396      $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
 397          namespace: namespace,
 398          widgetName: name,
 399          widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
 400          widgetBaseClass: fullName
 401      }, prototype );
 402  
 403      $.widget.bridge( name, $[ namespace ][ name ] );
 404  };
 405  
 406  $.widget.bridge = function( name, object ) {
 407      $.fn[ name ] = function( options ) {
 408          var isMethodCall = typeof options === "string",
 409              args = Array.prototype.slice.call( arguments, 1 ),
 410              returnValue = this;
 411  
 412          // allow multiple hashes to be passed on init
 413          options = !isMethodCall && args.length ?
 414              $.extend.apply( null, [ true, options ].concat(args) ) :
 415              options;
 416  
 417          // prevent calls to internal methods
 418          if ( isMethodCall && options.charAt( 0 ) === "_" ) {
 419              return returnValue;
 420          }
 421  
 422          if ( isMethodCall ) {
 423              this.each(function() {
 424                  var instance = $.data( this, name ),
 425                      methodValue = instance && $.isFunction( instance[options] ) ?
 426                          instance[ options ].apply( instance, args ) :
 427                          instance;
 428                  // TODO: add this back in 1.9 and use $.error() (see #5972)
 429  //                if ( !instance ) {
 430  //                    throw "cannot call methods on " + name + " prior to initialization; " +
 431  //                        "attempted to call method '" + options + "'";
 432  //                }
 433  //                if ( !$.isFunction( instance[options] ) ) {
 434  //                    throw "no such method '" + options + "' for " + name + " widget instance";
 435  //                }
 436  //                var methodValue = instance[ options ].apply( instance, args );
 437                  if ( methodValue !== instance && methodValue !== undefined ) {
 438                      returnValue = methodValue;
 439                      return false;
 440                  }
 441              });
 442          } else {
 443              this.each(function() {
 444                  var instance = $.data( this, name );
 445                  if ( instance ) {
 446                      instance.option( options || {} )._init();
 447                  } else {
 448                      $.data( this, name, new object( options, this ) );
 449                  }
 450              });
 451          }
 452  
 453          return returnValue;
 454      };
 455  };
 456  
 457  $.Widget = function( options, element ) {
 458      // allow instantiation without initializing for simple inheritance
 459      if ( arguments.length ) {
 460          this._createWidget( options, element );
 461      }
 462  };
 463  
 464  $.Widget.prototype = {
 465      widgetName: "widget",
 466      widgetEventPrefix: "",
 467      options: {
 468          disabled: false
 469      },
 470      _createWidget: function( options, element ) {
 471          // $.widget.bridge stores the plugin instance, but we do it anyway
 472          // so that it's stored even before the _create function runs
 473          $.data( element, this.widgetName, this );
 474          this.element = $( element );
 475          this.options = $.extend( true, {},
 476              this.options,
 477              this._getCreateOptions(),
 478              options );
 479  
 480          var self = this;
 481          this.element.bind( "remove." + this.widgetName, function() {
 482              self.destroy();
 483          });
 484  
 485          this._create();
 486          this._trigger( "create" );
 487          this._init();
 488      },
 489      _getCreateOptions: function() {
 490          return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
 491      },
 492      _create: function() {},
 493      _init: function() {},
 494  
 495      destroy: function() {
 496          this.element
 497              .unbind( "." + this.widgetName )
 498              .removeData( this.widgetName );
 499          this.widget()
 500              .unbind( "." + this.widgetName )
 501              .removeAttr( "aria-disabled" )
 502              .removeClass(
 503                  this.widgetBaseClass + "-disabled " +
 504                  "ui-state-disabled" );
 505      },
 506  
 507      widget: function() {
 508          return this.element;
 509      },
 510  
 511      option: function( key, value ) {
 512          var options = key;
 513  
 514          if ( arguments.length === 0 ) {
 515              // don't return a reference to the internal hash
 516              return $.extend( {}, this.options );
 517          }
 518  
 519          if  (typeof key === "string" ) {
 520              if ( value === undefined ) {
 521                  return this.options[ key ];
 522              }
 523              options = {};
 524              options[ key ] = value;
 525          }
 526  
 527          this._setOptions( options );
 528  
 529          return this;
 530      },
 531      _setOptions: function( options ) {
 532          var self = this;
 533          $.each( options, function( key, value ) {
 534              self._setOption( key, value );
 535          });
 536  
 537          return this;
 538      },
 539      _setOption: function( key, value ) {
 540          this.options[ key ] = value;
 541  
 542          if ( key === "disabled" ) {
 543              this.widget()
 544                  [ value ? "addClass" : "removeClass"](
 545                      this.widgetBaseClass + "-disabled" + " " +
 546                      "ui-state-disabled" )
 547                  .attr( "aria-disabled", value );
 548          }
 549  
 550          return this;
 551      },
 552  
 553      enable: function() {
 554          return this._setOption( "disabled", false );
 555      },
 556      disable: function() {
 557          return this._setOption( "disabled", true );
 558      },
 559  
 560      _trigger: function( type, event, data ) {
 561          var prop, orig,
 562              callback = this.options[ type ];
 563  
 564          data = data || {};
 565          event = $.Event( event );
 566          event.type = ( type === this.widgetEventPrefix ?
 567              type :
 568              this.widgetEventPrefix + type ).toLowerCase();
 569          // the original event may come from any element
 570          // so we need to reset the target on the new event
 571          event.target = this.element[ 0 ];
 572  
 573          // copy original event properties over to the new event
 574          orig = event.originalEvent;
 575          if ( orig ) {
 576              for ( prop in orig ) {
 577                  if ( !( prop in event ) ) {
 578                      event[ prop ] = orig[ prop ];
 579                  }
 580              }
 581          }
 582  
 583          this.element.trigger( event, data );
 584  
 585          return !( $.isFunction(callback) &&
 586              callback.call( this.element[0], event, data ) === false ||
 587              event.isDefaultPrevented() );
 588      }
 589  };
 590  
 591  })( jQuery );
 592  /*!
 593   * jQuery UI Mouse 1.8.18
 594   *
 595   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 596   * Dual licensed under the MIT or GPL Version 2 licenses.
 597   * http://jquery.org/license
 598   *
 599   * http://docs.jquery.com/UI/Mouse
 600   *
 601   * Depends:
 602   *    jquery.ui.widget.js
 603   */
 604  (function( $, undefined ) {
 605  
 606  var mouseHandled = false;
 607  $( document ).mouseup( function( e ) {
 608      mouseHandled = false;
 609  });
 610  
 611  $.widget("ui.mouse", {
 612      options: {
 613          cancel: ':input,option',
 614          distance: 1,
 615          delay: 0
 616      },
 617      _mouseInit: function() {
 618          var self = this;
 619  
 620          this.element
 621              .bind('mousedown.'+this.widgetName, function(event) {
 622                  return self._mouseDown(event);
 623              })
 624              .bind('click.'+this.widgetName, function(event) {
 625                  if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
 626                      $.removeData(event.target, self.widgetName + '.preventClickEvent');
 627                      event.stopImmediatePropagation();
 628                      return false;
 629                  }
 630              });
 631  
 632          this.started = false;
 633      },
 634  
 635      // TODO: make sure destroying one instance of mouse doesn't mess with
 636      // other instances of mouse
 637      _mouseDestroy: function() {
 638          this.element.unbind('.'+this.widgetName);
 639      },
 640  
 641      _mouseDown: function(event) {
 642          // don't let more than one widget handle mouseStart
 643          if( mouseHandled ) { return };
 644  
 645          // we may have missed mouseup (out of window)
 646          (this._mouseStarted && this._mouseUp(event));
 647  
 648          this._mouseDownEvent = event;
 649  
 650          var self = this,
 651              btnIsLeft = (event.which == 1),
 652              // event.target.nodeName works around a bug in IE 8 with
 653              // disabled inputs (#7620)
 654              elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
 655          if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 656              return true;
 657          }
 658  
 659          this.mouseDelayMet = !this.options.delay;
 660          if (!this.mouseDelayMet) {
 661              this._mouseDelayTimer = setTimeout(function() {
 662                  self.mouseDelayMet = true;
 663              }, this.options.delay);
 664          }
 665  
 666          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 667              this._mouseStarted = (this._mouseStart(event) !== false);
 668              if (!this._mouseStarted) {
 669                  event.preventDefault();
 670                  return true;
 671              }
 672          }
 673  
 674          // Click event may never have fired (Gecko & Opera)
 675          if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
 676              $.removeData(event.target, this.widgetName + '.preventClickEvent');
 677          }
 678  
 679          // these delegates are required to keep context
 680          this._mouseMoveDelegate = function(event) {
 681              return self._mouseMove(event);
 682          };
 683          this._mouseUpDelegate = function(event) {
 684              return self._mouseUp(event);
 685          };
 686          $(document)
 687              .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 688              .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 689  
 690          event.preventDefault();
 691          
 692          mouseHandled = true;
 693          return true;
 694      },
 695  
 696      _mouseMove: function(event) {
 697          // IE mouseup check - mouseup happened when mouse was out of window
 698          if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
 699              return this._mouseUp(event);
 700          }
 701  
 702          if (this._mouseStarted) {
 703              this._mouseDrag(event);
 704              return event.preventDefault();
 705          }
 706  
 707          if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 708              this._mouseStarted =
 709                  (this._mouseStart(this._mouseDownEvent, event) !== false);
 710              (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
 711          }
 712  
 713          return !this._mouseStarted;
 714      },
 715  
 716      _mouseUp: function(event) {
 717          $(document)
 718              .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
 719              .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
 720  
 721          if (this._mouseStarted) {
 722              this._mouseStarted = false;
 723  
 724              if (event.target == this._mouseDownEvent.target) {
 725                  $.data(event.target, this.widgetName + '.preventClickEvent', true);
 726              }
 727  
 728              this._mouseStop(event);
 729          }
 730  
 731          return false;
 732      },
 733  
 734      _mouseDistanceMet: function(event) {
 735          return (Math.max(
 736                  Math.abs(this._mouseDownEvent.pageX - event.pageX),
 737                  Math.abs(this._mouseDownEvent.pageY - event.pageY)
 738              ) >= this.options.distance
 739          );
 740      },
 741  
 742      _mouseDelayMet: function(event) {
 743          return this.mouseDelayMet;
 744      },
 745  
 746      // These are placeholder methods, to be overriden by extending plugin
 747      _mouseStart: function(event) {},
 748      _mouseDrag: function(event) {},
 749      _mouseStop: function(event) {},
 750      _mouseCapture: function(event) { return true; }
 751  });
 752  
 753  })(jQuery);
 754  /*
 755   * jQuery UI Position 1.8.18
 756   *
 757   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 758   * Dual licensed under the MIT or GPL Version 2 licenses.
 759   * http://jquery.org/license
 760   *
 761   * http://docs.jquery.com/UI/Position
 762   */
 763  (function( $, undefined ) {
 764  
 765  $.ui = $.ui || {};
 766  
 767  var horizontalPositions = /left|center|right/,
 768      verticalPositions = /top|center|bottom/,
 769      center = "center",
 770      support = {},
 771      _position = $.fn.position,
 772      _offset = $.fn.offset;
 773  
 774  $.fn.position = function( options ) {
 775      if ( !options || !options.of ) {
 776          return _position.apply( this, arguments );
 777      }
 778  
 779      // make a copy, we don't want to modify arguments
 780      options = $.extend( {}, options );
 781  
 782      var target = $( options.of ),
 783          targetElem = target[0],
 784          collision = ( options.collision || "flip" ).split( " " ),
 785          offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
 786          targetWidth,
 787          targetHeight,
 788          basePosition;
 789  
 790      if ( targetElem.nodeType === 9 ) {
 791          targetWidth = target.width();
 792          targetHeight = target.height();
 793          basePosition = { top: 0, left: 0 };
 794      // TODO: use $.isWindow() in 1.9
 795      } else if ( targetElem.setTimeout ) {
 796          targetWidth = target.width();
 797          targetHeight = target.height();
 798          basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
 799      } else if ( targetElem.preventDefault ) {
 800          // force left top to allow flipping
 801          options.at = "left top";
 802          targetWidth = targetHeight = 0;
 803          basePosition = { top: options.of.pageY, left: options.of.pageX };
 804      } else {
 805          targetWidth = target.outerWidth();
 806          targetHeight = target.outerHeight();
 807          basePosition = target.offset();
 808      }
 809  
 810      // force my and at to have valid horizontal and veritcal positions
 811      // if a value is missing or invalid, it will be converted to center 
 812      $.each( [ "my", "at" ], function() {
 813          var pos = ( options[this] || "" ).split( " " );
 814          if ( pos.length === 1) {
 815              pos = horizontalPositions.test( pos[0] ) ?
 816                  pos.concat( [center] ) :
 817                  verticalPositions.test( pos[0] ) ?
 818                      [ center ].concat( pos ) :
 819                      [ center, center ];
 820          }
 821          pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
 822          pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
 823          options[ this ] = pos;
 824      });
 825  
 826      // normalize collision option
 827      if ( collision.length === 1 ) {
 828          collision[ 1 ] = collision[ 0 ];
 829      }
 830  
 831      // normalize offset option
 832      offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
 833      if ( offset.length === 1 ) {
 834          offset[ 1 ] = offset[ 0 ];
 835      }
 836      offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
 837  
 838      if ( options.at[0] === "right" ) {
 839          basePosition.left += targetWidth;
 840      } else if ( options.at[0] === center ) {
 841          basePosition.left += targetWidth / 2;
 842      }
 843  
 844      if ( options.at[1] === "bottom" ) {
 845          basePosition.top += targetHeight;
 846      } else if ( options.at[1] === center ) {
 847          basePosition.top += targetHeight / 2;
 848      }
 849  
 850      basePosition.left += offset[ 0 ];
 851      basePosition.top += offset[ 1 ];
 852  
 853      return this.each(function() {
 854          var elem = $( this ),
 855              elemWidth = elem.outerWidth(),
 856              elemHeight = elem.outerHeight(),
 857              marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
 858              marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
 859              collisionWidth = elemWidth + marginLeft +
 860                  ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
 861              collisionHeight = elemHeight + marginTop +
 862                  ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
 863              position = $.extend( {}, basePosition ),
 864              collisionPosition;
 865  
 866          if ( options.my[0] === "right" ) {
 867              position.left -= elemWidth;
 868          } else if ( options.my[0] === center ) {
 869              position.left -= elemWidth / 2;
 870          }
 871  
 872          if ( options.my[1] === "bottom" ) {
 873              position.top -= elemHeight;
 874          } else if ( options.my[1] === center ) {
 875              position.top -= elemHeight / 2;
 876          }
 877  
 878          // prevent fractions if jQuery version doesn't support them (see #5280)
 879          if ( !support.fractions ) {
 880              position.left = Math.round( position.left );
 881              position.top = Math.round( position.top );
 882          }
 883  
 884          collisionPosition = {
 885              left: position.left - marginLeft,
 886              top: position.top - marginTop
 887          };
 888  
 889          $.each( [ "left", "top" ], function( i, dir ) {
 890              if ( $.ui.position[ collision[i] ] ) {
 891                  $.ui.position[ collision[i] ][ dir ]( position, {
 892                      targetWidth: targetWidth,
 893                      targetHeight: targetHeight,
 894                      elemWidth: elemWidth,
 895                      elemHeight: elemHeight,
 896                      collisionPosition: collisionPosition,
 897                      collisionWidth: collisionWidth,
 898                      collisionHeight: collisionHeight,
 899                      offset: offset,
 900                      my: options.my,
 901                      at: options.at
 902                  });
 903              }
 904          });
 905  
 906          if ( $.fn.bgiframe ) {
 907              elem.bgiframe();
 908          }
 909          elem.offset( $.extend( position, { using: options.using } ) );
 910      });
 911  };
 912  
 913  $.ui.position = {
 914      fit: {
 915          left: function( position, data ) {
 916              var win = $( window ),
 917                  over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
 918              position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
 919          },
 920          top: function( position, data ) {
 921              var win = $( window ),
 922                  over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
 923              position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
 924          }
 925      },
 926  
 927      flip: {
 928          left: function( position, data ) {
 929              if ( data.at[0] === center ) {
 930                  return;
 931              }
 932              var win = $( window ),
 933                  over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
 934                  myOffset = data.my[ 0 ] === "left" ?
 935                      -data.elemWidth :
 936                      data.my[ 0 ] === "right" ?
 937                          data.elemWidth :
 938                          0,
 939                  atOffset = data.at[ 0 ] === "left" ?
 940                      data.targetWidth :
 941                      -data.targetWidth,
 942                  offset = -2 * data.offset[ 0 ];
 943              position.left += data.collisionPosition.left < 0 ?
 944                  myOffset + atOffset + offset :
 945                  over > 0 ?
 946                      myOffset + atOffset + offset :
 947                      0;
 948          },
 949          top: function( position, data ) {
 950              if ( data.at[1] === center ) {
 951                  return;
 952              }
 953              var win = $( window ),
 954                  over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
 955                  myOffset = data.my[ 1 ] === "top" ?
 956                      -data.elemHeight :
 957                      data.my[ 1 ] === "bottom" ?
 958                          data.elemHeight :
 959                          0,
 960                  atOffset = data.at[ 1 ] === "top" ?
 961                      data.targetHeight :
 962                      -data.targetHeight,
 963                  offset = -2 * data.offset[ 1 ];
 964              position.top += data.collisionPosition.top < 0 ?
 965                  myOffset + atOffset + offset :
 966                  over > 0 ?
 967                      myOffset + atOffset + offset :
 968                      0;
 969          }
 970      }
 971  };
 972  
 973  // offset setter from jQuery 1.4
 974  if ( !$.offset.setOffset ) {
 975      $.offset.setOffset = function( elem, options ) {
 976          // set position first, in-case top/left are set even on static elem
 977          if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
 978              elem.style.position = "relative";
 979          }
 980          var curElem   = $( elem ),
 981              curOffset = curElem.offset(),
 982              curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
 983              curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
 984              props     = {
 985                  top:  (options.top  - curOffset.top)  + curTop,
 986                  left: (options.left - curOffset.left) + curLeft
 987              };
 988          
 989          if ( 'using' in options ) {
 990              options.using.call( elem, props );
 991          } else {
 992              curElem.css( props );
 993          }
 994      };
 995  
 996      $.fn.offset = function( options ) {
 997          var elem = this[ 0 ];
 998          if ( !elem || !elem.ownerDocument ) { return null; }
 999          if ( options ) { 
1000              return this.each(function() {
1001                  $.offset.setOffset( this, options );
1002              });
1003          }
1004          return _offset.call( this );
1005      };
1006  }
1007  
1008  // fraction support test (older versions of jQuery don't support fractions)
1009  (function () {
1010      var body = document.getElementsByTagName( "body" )[ 0 ], 
1011          div = document.createElement( "div" ),
1012          testElement, testElementParent, testElementStyle, offset, offsetTotal;
1013  
1014      //Create a "fake body" for testing based on method used in jQuery.support
1015      testElement = document.createElement( body ? "div" : "body" );
1016      testElementStyle = {
1017          visibility: "hidden",
1018          width: 0,
1019          height: 0,
1020          border: 0,
1021          margin: 0,
1022          background: "none"
1023      };
1024      if ( body ) {
1025          $.extend( testElementStyle, {
1026              position: "absolute",
1027              left: "-1000px",
1028              top: "-1000px"
1029          });
1030      }
1031      for ( var i in testElementStyle ) {
1032          testElement.style[ i ] = testElementStyle[ i ];
1033      }
1034      testElement.appendChild( div );
1035      testElementParent = body || document.documentElement;
1036      testElementParent.insertBefore( testElement, testElementParent.firstChild );
1037  
1038      div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
1039  
1040      offset = $( div ).offset( function( _, offset ) {
1041          return offset;
1042      }).offset();
1043  
1044      testElement.innerHTML = "";
1045      testElementParent.removeChild( testElement );
1046  
1047      offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 );
1048      support.fractions = offsetTotal > 21 && offsetTotal < 22;
1049  })();
1050  
1051  }( jQuery ));
1052  /*
1053   * jQuery UI Draggable 1.8.18
1054   *
1055   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1056   * Dual licensed under the MIT or GPL Version 2 licenses.
1057   * http://jquery.org/license
1058   *
1059   * http://docs.jquery.com/UI/Draggables
1060   *
1061   * Depends:
1062   *    jquery.ui.core.js
1063   *    jquery.ui.mouse.js
1064   *    jquery.ui.widget.js
1065   */
1066  (function( $, undefined ) {
1067  
1068  $.widget("ui.draggable", $.ui.mouse, {
1069      widgetEventPrefix: "drag",
1070      options: {
1071          addClasses: true,
1072          appendTo: "parent",
1073          axis: false,
1074          connectToSortable: false,
1075          containment: false,
1076          cursor: "auto",
1077          cursorAt: false,
1078          grid: false,
1079          handle: false,
1080          helper: "original",
1081          iframeFix: false,
1082          opacity: false,
1083          refreshPositions: false,
1084          revert: false,
1085          revertDuration: 500,
1086          scope: "default",
1087          scroll: true,
1088          scrollSensitivity: 20,
1089          scrollSpeed: 20,
1090          snap: false,
1091          snapMode: "both",
1092          snapTolerance: 20,
1093          stack: false,
1094          zIndex: false
1095      },
1096      _create: function() {
1097  
1098          if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
1099              this.element[0].style.position = 'relative';
1100  
1101          (this.options.addClasses && this.element.addClass("ui-draggable"));
1102          (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
1103  
1104          this._mouseInit();
1105  
1106      },
1107  
1108      destroy: function() {
1109          if(!this.element.data('draggable')) return;
1110          this.element
1111              .removeData("draggable")
1112              .unbind(".draggable")
1113              .removeClass("ui-draggable"
1114                  + " ui-draggable-dragging"
1115                  + " ui-draggable-disabled");
1116          this._mouseDestroy();
1117  
1118          return this;
1119      },
1120  
1121      _mouseCapture: function(event) {
1122  
1123          var o = this.options;
1124  
1125          // among others, prevent a drag on a resizable-handle
1126          if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
1127              return false;
1128  
1129          //Quit if we're not on a valid handle
1130          this.handle = this._getHandle(event);
1131          if (!this.handle)
1132              return false;
1133          
1134          if ( o.iframeFix ) {
1135              $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1136                  $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1137                  .css({
1138                      width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1139                      position: "absolute", opacity: "0.001", zIndex: 1000
1140                  })
1141                  .css($(this).offset())
1142                  .appendTo("body");
1143              });
1144          }
1145  
1146          return true;
1147  
1148      },
1149  
1150      _mouseStart: function(event) {
1151  
1152          var o = this.options;
1153  
1154          //Create and append the visible helper
1155          this.helper = this._createHelper(event);
1156  
1157          //Cache the helper size
1158          this._cacheHelperProportions();
1159  
1160          //If ddmanager is used for droppables, set the global draggable
1161          if($.ui.ddmanager)
1162              $.ui.ddmanager.current = this;
1163  
1164          /*
1165           * - Position generation -
1166           * This block generates everything position related - it's the core of draggables.
1167           */
1168  
1169          //Cache the margins of the original element
1170          this._cacheMargins();
1171  
1172          //Store the helper's css position
1173          this.cssPosition = this.helper.css("position");
1174          this.scrollParent = this.helper.scrollParent();
1175  
1176          //The element's absolute position on the page minus margins
1177          this.offset = this.positionAbs = this.element.offset();
1178          this.offset = {
1179              top: this.offset.top - this.margins.top,
1180              left: this.offset.left - this.margins.left
1181          };
1182  
1183          $.extend(this.offset, {
1184              click: { //Where the click happened, relative to the element
1185                  left: event.pageX - this.offset.left,
1186                  top: event.pageY - this.offset.top
1187              },
1188              parent: this._getParentOffset(),
1189              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1190          });
1191  
1192          //Generate the original position
1193          this.originalPosition = this.position = this._generatePosition(event);
1194          this.originalPageX = event.pageX;
1195          this.originalPageY = event.pageY;
1196  
1197          //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1198          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1199  
1200          //Set a containment if given in the options
1201          if(o.containment)
1202              this._setContainment();
1203  
1204          //Trigger event + callbacks
1205          if(this._trigger("start", event) === false) {
1206              this._clear();
1207              return false;
1208          }
1209  
1210          //Recache the helper size
1211          this._cacheHelperProportions();
1212  
1213          //Prepare the droppable offsets
1214          if ($.ui.ddmanager && !o.dropBehaviour)
1215              $.ui.ddmanager.prepareOffsets(this, event);
1216  
1217          this.helper.addClass("ui-draggable-dragging");
1218          this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1219          
1220          //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1221          if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
1222          
1223          return true;
1224      },
1225  
1226      _mouseDrag: function(event, noPropagation) {
1227  
1228          //Compute the helpers position
1229          this.position = this._generatePosition(event);
1230          this.positionAbs = this._convertPositionTo("absolute");
1231  
1232          //Call plugins and callbacks and use the resulting position if something is returned
1233          if (!noPropagation) {
1234              var ui = this._uiHash();
1235              if(this._trigger('drag', event, ui) === false) {
1236                  this._mouseUp({});
1237                  return false;
1238              }
1239              this.position = ui.position;
1240          }
1241  
1242          if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
1243          if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
1244          if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
1245  
1246          return false;
1247      },
1248  
1249      _mouseStop: function(event) {
1250  
1251          //If we are using droppables, inform the manager about the drop
1252          var dropped = false;
1253          if ($.ui.ddmanager && !this.options.dropBehaviour)
1254              dropped = $.ui.ddmanager.drop(this, event);
1255  
1256          //if a drop comes from outside (a sortable)
1257          if(this.dropped) {
1258              dropped = this.dropped;
1259              this.dropped = false;
1260          }
1261          
1262          //if the original element is removed, don't bother to continue if helper is set to "original"
1263          if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
1264              return false;
1265  
1266          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))) {
1267              var self = this;
1268              $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1269                  if(self._trigger("stop", event) !== false) {
1270                      self._clear();
1271                  }
1272              });
1273          } else {
1274              if(this._trigger("stop", event) !== false) {
1275                  this._clear();
1276              }
1277          }
1278  
1279          return false;
1280      },
1281      
1282      _mouseUp: function(event) {
1283          if (this.options.iframeFix === true) {
1284              $("div.ui-draggable-iframeFix").each(function() { 
1285                  this.parentNode.removeChild(this); 
1286              }); //Remove frame helpers
1287          }
1288          
1289          //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1290          if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
1291          
1292          return $.ui.mouse.prototype._mouseUp.call(this, event);
1293      },
1294      
1295      cancel: function() {
1296          
1297          if(this.helper.is(".ui-draggable-dragging")) {
1298              this._mouseUp({});
1299          } else {
1300              this._clear();
1301          }
1302          
1303          return this;
1304          
1305      },
1306  
1307      _getHandle: function(event) {
1308  
1309          var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1310          $(this.options.handle, this.element)
1311              .find("*")
1312              .andSelf()
1313              .each(function() {
1314                  if(this == event.target) handle = true;
1315              });
1316  
1317          return handle;
1318  
1319      },
1320  
1321      _createHelper: function(event) {
1322  
1323          var o = this.options;
1324          var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1325  
1326          if(!helper.parents('body').length)
1327              helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1328  
1329          if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1330              helper.css("position", "absolute");
1331  
1332          return helper;
1333  
1334      },
1335  
1336      _adjustOffsetFromHelper: function(obj) {
1337          if (typeof obj == 'string') {
1338              obj = obj.split(' ');
1339          }
1340          if ($.isArray(obj)) {
1341              obj = {left: +obj[0], top: +obj[1] || 0};
1342          }
1343          if ('left' in obj) {
1344              this.offset.click.left = obj.left + this.margins.left;
1345          }
1346          if ('right' in obj) {
1347              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1348          }
1349          if ('top' in obj) {
1350              this.offset.click.top = obj.top + this.margins.top;
1351          }
1352          if ('bottom' in obj) {
1353              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1354          }
1355      },
1356  
1357      _getParentOffset: function() {
1358  
1359          //Get the offsetParent and cache its position
1360          this.offsetParent = this.helper.offsetParent();
1361          var po = this.offsetParent.offset();
1362  
1363          // This is a special case where we need to modify a offset calculated on start, since the following happened:
1364          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1365          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1366          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1367          if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1368              po.left += this.scrollParent.scrollLeft();
1369              po.top += this.scrollParent.scrollTop();
1370          }
1371  
1372          if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1373          || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1374              po = { top: 0, left: 0 };
1375  
1376          return {
1377              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1378              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1379          };
1380  
1381      },
1382  
1383      _getRelativeOffset: function() {
1384  
1385          if(this.cssPosition == "relative") {
1386              var p = this.element.position();
1387              return {
1388                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1389                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1390              };
1391          } else {
1392              return { top: 0, left: 0 };
1393          }
1394  
1395      },
1396  
1397      _cacheMargins: function() {
1398          this.margins = {
1399              left: (parseInt(this.element.css("marginLeft"),10) || 0),
1400              top: (parseInt(this.element.css("marginTop"),10) || 0),
1401              right: (parseInt(this.element.css("marginRight"),10) || 0),
1402              bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1403          };
1404      },
1405  
1406      _cacheHelperProportions: function() {
1407          this.helperProportions = {
1408              width: this.helper.outerWidth(),
1409              height: this.helper.outerHeight()
1410          };
1411      },
1412  
1413      _setContainment: function() {
1414  
1415          var o = this.options;
1416          if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1417          if(o.containment == 'document' || o.containment == 'window') this.containment = [
1418              o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1419              o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1420              (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1421              (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1422          ];
1423  
1424          if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1425                  var c = $(o.containment);
1426              var ce = c[0]; if(!ce) return;
1427              var co = c.offset();
1428              var over = ($(ce).css("overflow") != 'hidden');
1429  
1430              this.containment = [
1431                  (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1432                  (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1433                  (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 - this.margins.right,
1434                  (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  - this.margins.bottom
1435              ];
1436              this.relative_container = c;
1437  
1438          } else if(o.containment.constructor == Array) {
1439              this.containment = o.containment;
1440          }
1441  
1442      },
1443  
1444      _convertPositionTo: function(d, pos) {
1445  
1446          if(!pos) pos = this.position;
1447          var mod = d == "absolute" ? 1 : -1;
1448          var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1449  
1450          return {
1451              top: (
1452                  pos.top                                                                    // The absolute mouse position
1453                  + this.offset.relative.top * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
1454                  + this.offset.parent.top * mod                                            // The offsetParent's offset without borders (offset + border)
1455                  - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1456              ),
1457              left: (
1458                  pos.left                                                                // The absolute mouse position
1459                  + this.offset.relative.left * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
1460                  + this.offset.parent.left * mod                                            // The offsetParent's offset without borders (offset + border)
1461                  - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1462              )
1463          };
1464  
1465      },
1466  
1467      _generatePosition: function(event) {
1468  
1469          var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1470          var pageX = event.pageX;
1471          var pageY = event.pageY;
1472  
1473          /*
1474           * - Position constraining -
1475           * Constrain the position to a mix of grid, containment.
1476           */
1477  
1478          if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1479                   var containment;
1480                   if(this.containment) {
1481                   if (this.relative_container){
1482                       var co = this.relative_container.offset();
1483                       containment = [ this.containment[0] + co.left,
1484                               this.containment[1] + co.top,
1485                               this.containment[2] + co.left,
1486                               this.containment[3] + co.top ];
1487                   }
1488                   else {
1489                       containment = this.containment;
1490                   }
1491  
1492                  if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1493                  if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1494                  if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1495                  if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1496              }
1497  
1498              if(o.grid) {
1499                  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1500                  var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1501                  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;
1502  
1503                  var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1504                  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;
1505              }
1506  
1507          }
1508  
1509          return {
1510              top: (
1511                  pageY                                                                // The absolute mouse position
1512                  - this.offset.click.top                                                    // Click offset (relative to the element)
1513                  - this.offset.relative.top                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1514                  - this.offset.parent.top                                                // The offsetParent's offset without borders (offset + border)
1515                  + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1516              ),
1517              left: (
1518                  pageX                                                                // The absolute mouse position
1519                  - this.offset.click.left                                                // Click offset (relative to the element)
1520                  - this.offset.relative.left                                                // Only for relative positioned nodes: Relative offset from element to offset parent
1521                  - this.offset.parent.left                                                // The offsetParent's offset without borders (offset + border)
1522                  + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1523              )
1524          };
1525  
1526      },
1527  
1528      _clear: function() {
1529          this.helper.removeClass("ui-draggable-dragging");
1530          if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1531          //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1532          this.helper = null;
1533          this.cancelHelperRemoval = false;
1534      },
1535  
1536      // From now on bulk stuff - mainly helpers
1537  
1538      _trigger: function(type, event, ui) {
1539          ui = ui || this._uiHash();
1540          $.ui.plugin.call(this, type, [event, ui]);
1541          if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1542          return $.Widget.prototype._trigger.call(this, type, event, ui);
1543      },
1544  
1545      plugins: {},
1546  
1547      _uiHash: function(event) {
1548          return {
1549              helper: this.helper,
1550              position: this.position,
1551              originalPosition: this.originalPosition,
1552              offset: this.positionAbs
1553          };
1554      }
1555  
1556  });
1557  
1558  $.extend($.ui.draggable, {
1559      version: "1.8.18"
1560  });
1561  
1562  $.ui.plugin.add("draggable", "connectToSortable", {
1563      start: function(event, ui) {
1564  
1565          var inst = $(this).data("draggable"), o = inst.options,
1566              uiSortable = $.extend({}, ui, { item: inst.element });
1567          inst.sortables = [];
1568          $(o.connectToSortable).each(function() {
1569              var sortable = $.data(this, 'sortable');
1570              if (sortable && !sortable.options.disabled) {
1571                  inst.sortables.push({
1572                      instance: sortable,
1573                      shouldRevert: sortable.options.revert
1574                  });
1575                  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).
1576                  sortable._trigger("activate", event, uiSortable);
1577              }
1578          });
1579  
1580      },
1581      stop: function(event, ui) {
1582  
1583          //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1584          var inst = $(this).data("draggable"),
1585              uiSortable = $.extend({}, ui, { item: inst.element });
1586  
1587          $.each(inst.sortables, function() {
1588              if(this.instance.isOver) {
1589  
1590                  this.instance.isOver = 0;
1591  
1592                  inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1593                  this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1594  
1595                  //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1596                  if(this.shouldRevert) this.instance.options.revert = true;
1597  
1598                  //Trigger the stop of the sortable
1599                  this.instance._mouseStop(event);
1600  
1601                  this.instance.options.helper = this.instance.options._helper;
1602  
1603                  //If the helper has been the original item, restore properties in the sortable
1604                  if(inst.options.helper == 'original')
1605                      this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1606  
1607              } else {
1608                  this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1609                  this.instance._trigger("deactivate", event, uiSortable);
1610              }
1611  
1612          });
1613  
1614      },
1615      drag: function(event, ui) {
1616  
1617          var inst = $(this).data("draggable"), self = this;
1618  
1619          var checkPos = function(o) {
1620              var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1621              var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1622              var itemHeight = o.height, itemWidth = o.width;
1623              var itemTop = o.top, itemLeft = o.left;
1624  
1625              return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1626          };
1627  
1628          $.each(inst.sortables, function(i) {
1629              
1630              //Copy over some variables to allow calling the sortable's native _intersectsWith
1631              this.instance.positionAbs = inst.positionAbs;
1632              this.instance.helperProportions = inst.helperProportions;
1633              this.instance.offset.click = inst.offset.click;
1634              
1635              if(this.instance._intersectsWith(this.instance.containerCache)) {
1636  
1637                  //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1638                  if(!this.instance.isOver) {
1639  
1640                      this.instance.isOver = 1;
1641                      //Now we fake the start of dragging for the sortable instance,
1642                      //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1643                      //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)
1644                      this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1645                      this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1646                      this.instance.options.helper = function() { return ui.helper[0]; };
1647  
1648                      event.target = this.instance.currentItem[0];
1649                      this.instance._mouseCapture(event, true);
1650                      this.instance._mouseStart(event, true, true);
1651  
1652                      //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1653                      this.instance.offset.click.top = inst.offset.click.top;
1654                      this.instance.offset.click.left = inst.offset.click.left;
1655                      this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1656                      this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1657  
1658                      inst._trigger("toSortable", event);
1659                      inst.dropped = this.instance.element; //draggable revert needs that
1660                      //hack so receive/update callbacks work (mostly)
1661                      inst.currentItem = inst.element;
1662                      this.instance.fromOutside = inst;
1663  
1664                  }
1665  
1666                  //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
1667                  if(this.instance.currentItem) this.instance._mouseDrag(event);
1668  
1669              } else {
1670  
1671                  //If it doesn't intersect with the sortable, and it intersected before,
1672                  //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1673                  if(this.instance.isOver) {
1674  
1675                      this.instance.isOver = 0;
1676                      this.instance.cancelHelperRemoval = true;
1677                      
1678                      //Prevent reverting on this forced stop
1679                      this.instance.options.revert = false;
1680                      
1681                      // The out event needs to be triggered independently
1682                      this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1683                      
1684                      this.instance._mouseStop(event, true);
1685                      this.instance.options.helper = this.instance.options._helper;
1686  
1687                      //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1688                      this.instance.currentItem.remove();
1689                      if(this.instance.placeholder) this.instance.placeholder.remove();
1690  
1691                      inst._trigger("fromSortable", event);
1692                      inst.dropped = false; //draggable revert needs that
1693                  }
1694  
1695              };
1696  
1697          });
1698  
1699      }
1700  });
1701  
1702  $.ui.plugin.add("draggable", "cursor", {
1703      start: function(event, ui) {
1704          var t = $('body'), o = $(this).data('draggable').options;
1705          if (t.css("cursor")) o._cursor = t.css("cursor");
1706          t.css("cursor", o.cursor);
1707      },
1708      stop: function(event, ui) {
1709          var o = $(this).data('draggable').options;
1710          if (o._cursor) $('body').css("cursor", o._cursor);
1711      }
1712  });
1713  
1714  $.ui.plugin.add("draggable", "opacity", {
1715      start: function(event, ui) {
1716          var t = $(ui.helper), o = $(this).data('draggable').options;
1717          if(t.css("opacity")) o._opacity = t.css("opacity");
1718          t.css('opacity', o.opacity);
1719      },
1720      stop: function(event, ui) {
1721          var o = $(this).data('draggable').options;
1722          if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1723      }
1724  });
1725  
1726  $.ui.plugin.add("draggable", "scroll", {
1727      start: function(event, ui) {
1728          var i = $(this).data("draggable");
1729          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1730      },
1731      drag: function(event, ui) {
1732  
1733          var i = $(this).data("draggable"), o = i.options, scrolled = false;
1734  
1735          if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1736  
1737              if(!o.axis || o.axis != 'x') {
1738                  if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1739                      i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1740                  else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1741                      i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1742              }
1743  
1744              if(!o.axis || o.axis != 'y') {
1745                  if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1746                      i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1747                  else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1748                      i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1749              }
1750  
1751          } else {
1752  
1753              if(!o.axis || o.axis != 'x') {
1754                  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1755                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1756                  else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1757                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1758              }
1759  
1760              if(!o.axis || o.axis != 'y') {
1761                  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1762                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1763                  else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1764                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1765              }
1766  
1767          }
1768  
1769          if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1770              $.ui.ddmanager.prepareOffsets(i, event);
1771  
1772      }
1773  });
1774  
1775  $.ui.plugin.add("draggable", "snap", {
1776      start: function(event, ui) {
1777  
1778          var i = $(this).data("draggable"), o = i.options;
1779          i.snapElements = [];
1780  
1781          $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1782              var $t = $(this); var $o = $t.offset();
1783              if(this != i.element[0]) i.snapElements.push({
1784                  item: this,
1785                  width: $t.outerWidth(), height: $t.outerHeight(),
1786                  top: $o.top, left: $o.left
1787              });
1788          });
1789  
1790      },
1791      drag: function(event, ui) {
1792  
1793          var inst = $(this).data("draggable"), o = inst.options;
1794          var d = o.snapTolerance;
1795  
1796          var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1797              y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1798  
1799          for (var i = inst.snapElements.length - 1; i >= 0; i--){
1800  
1801              var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1802                  t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1803  
1804              //Yes, I know, this is insane ;)
1805              if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1806                  if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1807                  inst.snapElements[i].snapping = false;
1808                  continue;
1809              }
1810  
1811              if(o.snapMode != 'inner') {
1812                  var ts = Math.abs(t - y2) <= d;
1813                  var bs = Math.abs(b - y1) <= d;
1814                  var ls = Math.abs(l - x2) <= d;
1815                  var rs = Math.abs(r - x1) <= d;
1816                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1817                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1818                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1819                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1820              }
1821  
1822              var first = (ts || bs || ls || rs);
1823  
1824              if(o.snapMode != 'outer') {
1825                  var ts = Math.abs(t - y1) <= d;
1826                  var bs = Math.abs(b - y2) <= d;
1827                  var ls = Math.abs(l - x1) <= d;
1828                  var rs = Math.abs(r - x2) <= d;
1829                  if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1830                  if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1831                  if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1832                  if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1833              }
1834  
1835              if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1836                  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1837              inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1838  
1839          };
1840  
1841      }
1842  });
1843  
1844  $.ui.plugin.add("draggable", "stack", {
1845      start: function(event, ui) {
1846  
1847          var o = $(this).data("draggable").options;
1848  
1849          var group = $.makeArray($(o.stack)).sort(function(a,b) {
1850              return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1851          });
1852          if (!group.length) { return; }
1853          
1854          var min = parseInt(group[0].style.zIndex) || 0;
1855          $(group).each(function(i) {
1856              this.style.zIndex = min + i;
1857          });
1858  
1859          this[0].style.zIndex = min + group.length;
1860  
1861      }
1862  });
1863  
1864  $.ui.plugin.add("draggable", "zIndex", {
1865      start: function(event, ui) {
1866          var t = $(ui.helper), o = $(this).data("draggable").options;
1867          if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1868          t.css('zIndex', o.zIndex);
1869      },
1870      stop: function(event, ui) {
1871          var o = $(this).data("draggable").options;
1872          if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1873      }
1874  });
1875  
1876  })(jQuery);
1877  /*
1878   * jQuery UI Droppable 1.8.18
1879   *
1880   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1881   * Dual licensed under the MIT or GPL Version 2 licenses.
1882   * http://jquery.org/license
1883   *
1884   * http://docs.jquery.com/UI/Droppables
1885   *
1886   * Depends:
1887   *    jquery.ui.core.js
1888   *    jquery.ui.widget.js
1889   *    jquery.ui.mouse.js
1890   *    jquery.ui.draggable.js
1891   */
1892  (function( $, undefined ) {
1893  
1894  $.widget("ui.droppable", {
1895      widgetEventPrefix: "drop",
1896      options: {
1897          accept: '*',
1898          activeClass: false,
1899          addClasses: true,
1900          greedy: false,
1901          hoverClass: false,
1902          scope: 'default',
1903          tolerance: 'intersect'
1904      },
1905      _create: function() {
1906  
1907          var o = this.options, accept = o.accept;
1908          this.isover = 0; this.isout = 1;
1909  
1910          this.accept = $.isFunction(accept) ? accept : function(d) {
1911              return d.is(accept);
1912          };
1913  
1914          //Store the droppable's proportions
1915          this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1916  
1917          // Add the reference and positions to the manager
1918          $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1919          $.ui.ddmanager.droppables[o.scope].push(this);
1920  
1921          (o.addClasses && this.element.addClass("ui-droppable"));
1922  
1923      },
1924  
1925      destroy: function() {
1926          var drop = $.ui.ddmanager.droppables[this.options.scope];
1927          for ( var i = 0; i < drop.length; i++ )
1928              if ( drop[i] == this )
1929                  drop.splice(i, 1);
1930  
1931          this.element
1932              .removeClass("ui-droppable ui-droppable-disabled")
1933              .removeData("droppable")
1934              .unbind(".droppable");
1935  
1936          return this;
1937      },
1938  
1939      _setOption: function(key, value) {
1940  
1941          if(key == 'accept') {
1942              this.accept = $.isFunction(value) ? value : function(d) {
1943                  return d.is(value);
1944              };
1945          }
1946          $.Widget.prototype._setOption.apply(this, arguments);
1947      },
1948  
1949      _activate: function(event) {
1950          var draggable = $.ui.ddmanager.current;
1951          if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1952          (draggable && this._trigger('activate', event, this.ui(draggable)));
1953      },
1954  
1955      _deactivate: function(event) {
1956          var draggable = $.ui.ddmanager.current;
1957          if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1958          (draggable && this._trigger('deactivate', event, this.ui(draggable)));
1959      },
1960  
1961      _over: function(event) {
1962  
1963          var draggable = $.ui.ddmanager.current;
1964          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1965  
1966          if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1967              if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1968              this._trigger('over', event, this.ui(draggable));
1969          }
1970  
1971      },
1972  
1973      _out: function(event) {
1974  
1975          var draggable = $.ui.ddmanager.current;
1976          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1977  
1978          if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1979              if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1980              this._trigger('out', event, this.ui(draggable));
1981          }
1982  
1983      },
1984  
1985      _drop: function(event,custom) {
1986  
1987          var draggable = custom || $.ui.ddmanager.current;
1988          if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1989  
1990          var childrenIntersection = false;
1991          this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1992              var inst = $.data(this, 'droppable');
1993              if(
1994                  inst.options.greedy
1995                  && !inst.options.disabled
1996                  && inst.options.scope == draggable.options.scope
1997                  && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1998                  && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1999              ) { childrenIntersection = true; return false; }
2000          });
2001          if(childrenIntersection) return false;
2002  
2003          if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2004              if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
2005              if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
2006              this._trigger('drop', event, this.ui(draggable));
2007              return this.element;
2008          }
2009  
2010          return false;
2011  
2012      },
2013  
2014      ui: function(c) {
2015          return {
2016              draggable: (c.currentItem || c.element),
2017              helper: c.helper,
2018              position: c.position,
2019              offset: c.positionAbs
2020          };
2021      }
2022  
2023  });
2024  
2025  $.extend($.ui.droppable, {
2026      version: "1.8.18"
2027  });
2028  
2029  $.ui.intersect = function(draggable, droppable, toleranceMode) {
2030  
2031      if (!droppable.offset) return false;
2032  
2033      var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2034          y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
2035      var l = droppable.offset.left, r = l + droppable.proportions.width,
2036          t = droppable.offset.top, b = t + droppable.proportions.height;
2037  
2038      switch (toleranceMode) {
2039          case 'fit':
2040              return (l <= x1 && x2 <= r
2041                  && t <= y1 && y2 <= b);
2042              break;
2043          case 'intersect':
2044              return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
2045                  && x2 - (draggable.helperProportions.width / 2) < r // Left Half
2046                  && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
2047                  && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2048              break;
2049          case 'pointer':
2050              var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
2051                  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
2052                  isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
2053              return isOver;
2054              break;
2055          case 'touch':
2056              return (
2057                      (y1 >= t && y1 <= b) ||    // Top edge touching
2058                      (y2 >= t && y2 <= b) ||    // Bottom edge touching
2059                      (y1 < t && y2 > b)        // Surrounded vertically
2060                  ) && (
2061                      (x1 >= l && x1 <= r) ||    // Left edge touching
2062                      (x2 >= l && x2 <= r) ||    // Right edge touching
2063                      (x1 < l && x2 > r)        // Surrounded horizontally
2064                  );
2065              break;
2066          default:
2067              return false;
2068              break;
2069          }
2070  
2071  };
2072  
2073  /*
2074      This manager tracks offsets of draggables and droppables
2075  */
2076  $.ui.ddmanager = {
2077      current: null,
2078      droppables: { 'default': [] },
2079      prepareOffsets: function(t, event) {
2080  
2081          var m = $.ui.ddmanager.droppables[t.options.scope] || [];
2082          var type = event ? event.type : null; // workaround for #2317
2083          var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
2084  
2085          droppablesLoop: for (var i = 0; i < m.length; i++) {
2086  
2087              if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;    //No disabled and non-accepted
2088              for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
2089              m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                     //If the element is not visible, continue
2090  
2091              if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
2092  
2093              m[i].offset = m[i].element.offset();
2094              m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2095  
2096          }
2097  
2098      },
2099      drop: function(draggable, event) {
2100  
2101          var dropped = false;
2102          $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2103  
2104              if(!this.options) return;
2105              if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
2106                  dropped = this._drop.call(this, event) || dropped;
2107  
2108              if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2109                  this.isout = 1; this.isover = 0;
2110                  this._deactivate.call(this, event);
2111              }
2112  
2113          });
2114          return dropped;
2115  
2116      },
2117      dragStart: function( draggable, event ) {
2118          //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2119          draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
2120              if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2121          });
2122      },
2123      drag: function(draggable, event) {
2124  
2125          //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2126          if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
2127  
2128          //Run through all droppables and check their positions based on specific tolerance options
2129          $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2130  
2131              if(this.options.disabled || this.greedyChild || !this.visible) return;
2132              var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
2133  
2134              var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
2135              if(!c) return;
2136  
2137              var parentInstance;
2138              if (this.options.greedy) {
2139                  var parent = this.element.parents(':data(droppable):eq(0)');
2140                  if (parent.length) {
2141                      parentInstance = $.data(parent[0], 'droppable');
2142                      parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
2143                  }
2144              }
2145  
2146              // we just moved into a greedy child
2147              if (parentInstance && c == 'isover') {
2148                  parentInstance['isover'] = 0;
2149                  parentInstance['isout'] = 1;
2150                  parentInstance._out.call(parentInstance, event);
2151              }
2152  
2153              this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
2154              this[c == "isover" ? "_over" : "_out"].call(this, event);
2155  
2156              // we just moved out of a greedy child
2157              if (parentInstance && c == 'isout') {
2158                  parentInstance['isout'] = 0;
2159                  parentInstance['isover'] = 1;
2160                  parentInstance._over.call(parentInstance, event);
2161              }
2162          });
2163  
2164      },
2165      dragStop: function( draggable, event ) {
2166          draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
2167          //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2168          if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
2169      }
2170  };
2171  
2172  })(jQuery);
2173  /*
2174   * jQuery UI Resizable 1.8.18
2175   *
2176   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2177   * Dual licensed under the MIT or GPL Version 2 licenses.
2178   * http://jquery.org/license
2179   *
2180   * http://docs.jquery.com/UI/Resizables
2181   *
2182   * Depends:
2183   *    jquery.ui.core.js
2184   *    jquery.ui.mouse.js
2185   *    jquery.ui.widget.js
2186   */
2187  (function( $, undefined ) {
2188  
2189  $.widget("ui.resizable", $.ui.mouse, {
2190      widgetEventPrefix: "resize",
2191      options: {
2192          alsoResize: false,
2193          animate: false,
2194          animateDuration: "slow",
2195          animateEasing: "swing",
2196          aspectRatio: false,
2197          autoHide: false,
2198          containment: false,
2199          ghost: false,
2200          grid: false,
2201          handles: "e,s,se",
2202          helper: false,
2203          maxHeight: null,
2204          maxWidth: null,
2205          minHeight: 10,
2206          minWidth: 10,
2207          zIndex: 1000
2208      },
2209      _create: function() {
2210  
2211          var self = this, o = this.options;
2212          this.element.addClass("ui-resizable");
2213  
2214          $.extend(this, {
2215              _aspectRatio: !!(o.aspectRatio),
2216              aspectRatio: o.aspectRatio,
2217              originalElement: this.element,
2218              _proportionallyResizeElements: [],
2219              _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
2220          });
2221  
2222          //Wrap the element if it cannot hold child nodes
2223          if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2224  
2225              //Create a wrapper element and set the wrapper to the new current internal element
2226              this.element.wrap(
2227                  $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2228                      position: this.element.css('position'),
2229                      width: this.element.outerWidth(),
2230                      height: this.element.outerHeight(),
2231                      top: this.element.css('top'),
2232                      left: this.element.css('left')
2233                  })
2234              );
2235  
2236              //Overwrite the original this.element
2237              this.element = this.element.parent().data(
2238                  "resizable", this.element.data('resizable')
2239              );
2240  
2241              this.elementIsWrapper = true;
2242  
2243              //Move margins to the wrapper
2244              this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2245              this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2246  
2247              //Prevent Safari textarea resize
2248              this.originalResizeStyle = this.originalElement.css('resize');
2249              this.originalElement.css('resize', 'none');
2250  
2251              //Push the actual element to our proportionallyResize internal array
2252              this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
2253  
2254              // avoid IE jump (hard set the margin)
2255              this.originalElement.css({ margin: this.originalElement.css('margin') });
2256  
2257              // fix handlers offset
2258              this._proportionallyResize();
2259  
2260          }
2261  
2262          this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
2263          if(this.handles.constructor == String) {
2264  
2265              if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
2266              var n = this.handles.split(","); this.handles = {};
2267  
2268              for(var i = 0; i < n.length; i++) {
2269  
2270                  var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
2271                  var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
2272  
2273                  // increase zIndex of sw, se, ne, nw axis
2274                  //TODO : this modifies original option
2275                  if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
2276  
2277                  //TODO : What's going on here?
2278                  if ('se' == handle) {
2279                      axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2280                  };
2281  
2282                  //Insert into internal handles object and append to element
2283                  this.handles[handle] = '.ui-resizable-'+handle;
2284                  this.element.append(axis);
2285              }
2286  
2287          }
2288  
2289          this._renderAxis = function(target) {
2290  
2291              target = target || this.element;
2292  
2293              for(var i in this.handles) {
2294  
2295                  if(this.handles[i].constructor == String)
2296                      this.handles[i] = $(this.handles[i], this.element).show();
2297  
2298                  //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2299                  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2300  
2301                      var axis = $(this.handles[i], this.element), padWrapper = 0;
2302  
2303                      //Checking the correct pad and border
2304                      padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2305  
2306                      //The padding type i have to apply...
2307                      var padPos = [ 'padding',
2308                          /ne|nw|n/.test(i) ? 'Top' :
2309                          /se|sw|s/.test(i) ? 'Bottom' :
2310                          /^e$/.test(i) ? 'Right' : 'Left' ].join("");
2311  
2312                      target.css(padPos, padWrapper);
2313  
2314                      this._proportionallyResize();
2315  
2316                  }
2317  
2318                  //TODO: What's that good for? There's not anything to be executed left
2319                  if(!$(this.handles[i]).length)
2320                      continue;
2321  
2322              }
2323          };
2324  
2325          //TODO: make renderAxis a prototype function
2326          this._renderAxis(this.element);
2327  
2328          this._handles = $('.ui-resizable-handle', this.element)
2329              .disableSelection();
2330  
2331          //Matching axis name
2332          this._handles.mouseover(function() {
2333              if (!self.resizing) {
2334                  if (this.className)
2335                      var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2336                  //Axis, default = se
2337                  self.axis = axis && axis[1] ? axis[1] : 'se';
2338              }
2339          });
2340  
2341          //If we want to auto hide the elements
2342          if (o.autoHide) {
2343              this._handles.hide();
2344              $(this.element)
2345                  .addClass("ui-resizable-autohide")
2346                  .hover(function() {
2347                      if (o.disabled) return;
2348                      $(this).removeClass("ui-resizable-autohide");
2349                      self._handles.show();
2350                  },
2351                  function(){
2352                      if (o.disabled) return;
2353                      if (!self.resizing) {
2354                          $(this).addClass("ui-resizable-autohide");
2355                          self._handles.hide();
2356                      }
2357                  });
2358          }
2359  
2360          //Initialize the mouse interaction
2361          this._mouseInit();
2362  
2363      },
2364  
2365      destroy: function() {
2366  
2367          this._mouseDestroy();
2368  
2369          var _destroy = function(exp) {
2370              $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2371                  .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2372          };
2373  
2374          //TODO: Unwrap at same DOM position
2375          if (this.elementIsWrapper) {
2376              _destroy(this.element);
2377              var wrapper = this.element;
2378              wrapper.after(
2379                  this.originalElement.css({
2380                      position: wrapper.css('position'),
2381                      width: wrapper.outerWidth(),
2382                      height: wrapper.outerHeight(),
2383                      top: wrapper.css('top'),
2384                      left: wrapper.css('left')
2385                  })
2386              ).remove();
2387          }
2388  
2389          this.originalElement.css('resize', this.originalResizeStyle);
2390          _destroy(this.originalElement);
2391  
2392          return this;
2393      },
2394  
2395      _mouseCapture: function(event) {
2396          var handle = false;
2397          for (var i in this.handles) {
2398              if ($(this.handles[i])[0] == event.target) {
2399                  handle = true;
2400              }
2401          }
2402  
2403          return !this.options.disabled && handle;
2404      },
2405  
2406      _mouseStart: function(event) {
2407  
2408          var o = this.options, iniPos = this.element.position(), el = this.element;
2409  
2410          this.resizing = true;
2411          this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2412  
2413          // bugfix for http://dev.jquery.com/ticket/1749
2414          if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2415              el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2416          }
2417  
2418          this._renderProxy();
2419  
2420          var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2421  
2422          if (o.containment) {
2423              curleft += $(o.containment).scrollLeft() || 0;
2424              curtop += $(o.containment).scrollTop() || 0;
2425          }
2426  
2427          //Store needed variables
2428          this.offset = this.helper.offset();
2429          this.position = { left: curleft, top: curtop };
2430          this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2431          this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2432          this.originalPosition = { left: curleft, top: curtop };
2433          this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2434          this.originalMousePosition = { left: event.pageX, top: event.pageY };
2435  
2436          //Aspect Ratio
2437          this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2438  
2439          var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2440          $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2441  
2442          el.addClass("ui-resizable-resizing");
2443          this._propagate("start", event);
2444          return true;
2445      },
2446  
2447      _mouseDrag: function(event) {
2448  
2449          //Increase performance, avoid regex
2450          var el = this.helper, o = this.options, props = {},
2451              self = this, smp = this.originalMousePosition, a = this.axis;
2452  
2453          var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2454          var trigger = this._change[a];
2455          if (!trigger) return false;
2456  
2457          // Calculate the attrs that will be change
2458          var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2459  
2460          // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2461          this._updateVirtualBoundaries(event.shiftKey);
2462          if (this._aspectRatio || event.shiftKey)
2463              data = this._updateRatio(data, event);
2464  
2465          data = this._respectSize(data, event);
2466  
2467          // plugins callbacks need to be called first
2468          this._propagate("resize", event);
2469  
2470          el.css({
2471              top: this.position.top + "px", left: this.position.left + "px",
2472              width: this.size.width + "px", height: this.size.height + "px"
2473          });
2474  
2475          if (!this._helper && this._proportionallyResizeElements.length)
2476              this._proportionallyResize();
2477  
2478          this._updateCache(data);
2479  
2480          // calling the user callback at the end
2481          this._trigger('resize', event, this.ui());
2482  
2483          return false;
2484      },
2485  
2486      _mouseStop: function(event) {
2487  
2488          this.resizing = false;
2489          var o = this.options, self = this;
2490  
2491          if(this._helper) {
2492              var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2493                  soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2494                  soffsetw = ista ? 0 : self.sizeDiff.width;
2495  
2496              var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
2497                  left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2498                  top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2499  
2500              if (!o.animate)
2501                  this.element.css($.extend(s, { top: top, left: left }));
2502  
2503              self.helper.height(self.size.height);
2504              self.helper.width(self.size.width);
2505  
2506              if (this._helper && !o.animate) this._proportionallyResize();
2507          }
2508  
2509          $('body').css('cursor', 'auto');
2510  
2511          this.element.removeClass("ui-resizable-resizing");
2512  
2513          this._propagate("stop", event);
2514  
2515          if (this._helper) this.helper.remove();
2516          return false;
2517  
2518      },
2519  
2520      _updateVirtualBoundaries: function(forceAspectRatio) {
2521          var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2522  
2523          b = {
2524              minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2525              maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2526              minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2527              maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2528          };
2529  
2530          if(this._aspectRatio || forceAspectRatio) {
2531              // We want to create an enclosing box whose aspect ration is the requested one
2532              // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2533              pMinWidth = b.minHeight * this.aspectRatio;
2534              pMinHeight = b.minWidth / this.aspectRatio;
2535              pMaxWidth = b.maxHeight * this.aspectRatio;
2536              pMaxHeight = b.maxWidth / this.aspectRatio;
2537  
2538              if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2539              if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2540              if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2541              if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2542          }
2543          this._vBoundaries = b;
2544      },
2545  
2546      _updateCache: function(data) {
2547          var o = this.options;
2548          this.offset = this.helper.offset();
2549          if (isNumber(data.left)) this.position.left = data.left;
2550          if (isNumber(data.top)) this.position.top = data.top;
2551          if (isNumber(data.height)) this.size.height = data.height;
2552          if (isNumber(data.width)) this.size.width = data.width;
2553      },
2554  
2555      _updateRatio: function(data, event) {
2556  
2557          var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2558  
2559          if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2560          else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2561  
2562          if (a == 'sw') {
2563              data.left = cpos.left + (csize.width - data.width);
2564              data.top = null;
2565          }
2566          if (a == 'nw') {
2567              data.top = cpos.top + (csize.height - data.height);
2568              data.left = cpos.left + (csize.width - data.width);
2569          }
2570  
2571          return data;
2572      },
2573  
2574      _respectSize: function(data, event) {
2575  
2576          var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2577                  ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2578                      isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2579  
2580          if (isminw) data.width = o.minWidth;
2581          if (isminh) data.height = o.minHeight;
2582          if (ismaxw) data.width = o.maxWidth;
2583          if (ismaxh) data.height = o.maxHeight;
2584  
2585          var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2586          var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2587  
2588          if (isminw && cw) data.left = dw - o.minWidth;
2589          if (ismaxw && cw) data.left = dw - o.maxWidth;
2590          if (isminh && ch)    data.top = dh - o.minHeight;
2591          if (ismaxh && ch)    data.top = dh - o.maxHeight;
2592  
2593          // fixing jump error on top/left - bug #2330
2594          var isNotwh = !data.width && !data.height;
2595          if (isNotwh && !data.left && data.top) data.top = null;
2596          else if (isNotwh && !data.top && data.left) data.left = null;
2597  
2598          return data;
2599      },
2600  
2601      _proportionallyResize: function() {
2602  
2603          var o = this.options;
2604          if (!this._proportionallyResizeElements.length) return;
2605          var element = this.helper || this.element;
2606  
2607          for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2608  
2609              var prel = this._proportionallyResizeElements[i];
2610  
2611              if (!this.borderDif) {
2612                  var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2613                      p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2614  
2615                  this.borderDif = $.map(b, function(v, i) {
2616                      var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2617                      return border + padding;
2618                  });
2619              }
2620  
2621              if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2622                  continue;
2623  
2624              prel.css({
2625                  height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2626                  width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2627              });
2628  
2629          };
2630  
2631      },
2632  
2633      _renderProxy: function() {
2634  
2635          var el = this.element, o = this.options;
2636          this.elementOffset = el.offset();
2637  
2638          if(this._helper) {
2639  
2640              this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2641  
2642              // fix ie6 offset TODO: This seems broken
2643              var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2644              pxyoffset = ( ie6 ? 2 : -1 );
2645  
2646              this.helper.addClass(this._helper).css({
2647                  width: this.element.outerWidth() + pxyoffset,
2648                  height: this.element.outerHeight() + pxyoffset,
2649                  position: 'absolute',
2650                  left: this.elementOffset.left - ie6offset +'px',
2651                  top: this.elementOffset.top - ie6offset +'px',
2652                  zIndex: ++o.zIndex //TODO: Don't modify option
2653              });
2654  
2655              this.helper
2656                  .appendTo("body")
2657                  .disableSelection();
2658  
2659          } else {
2660              this.helper = this.element;
2661          }
2662  
2663      },
2664  
2665      _change: {
2666          e: function(event, dx, dy) {
2667              return { width: this.originalSize.width + dx };
2668          },
2669          w: function(event, dx, dy) {
2670              var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2671              return { left: sp.left + dx, width: cs.width - dx };
2672          },
2673          n: function(event, dx, dy) {
2674              var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2675              return { top: sp.top + dy, height: cs.height - dy };
2676          },
2677          s: function(event, dx, dy) {
2678              return { height: this.originalSize.height + dy };
2679          },
2680          se: function(event, dx, dy) {
2681              return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2682          },
2683          sw: function(event, dx, dy) {
2684              return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2685          },
2686          ne: function(event, dx, dy) {
2687              return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2688          },
2689          nw: function(event, dx, dy) {
2690              return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2691          }
2692      },
2693  
2694      _propagate: function(n, event) {
2695          $.ui.plugin.call(this, n, [event, this.ui()]);
2696          (n != "resize" && this._trigger(n, event, this.ui()));
2697      },
2698  
2699      plugins: {},
2700  
2701      ui: function() {
2702          return {
2703              originalElement: this.originalElement,
2704              element: this.element,
2705              helper: this.helper,
2706              position: this.position,
2707              size: this.size,
2708              originalSize: this.originalSize,
2709              originalPosition: this.originalPosition
2710          };
2711      }
2712  
2713  });
2714  
2715  $.extend($.ui.resizable, {
2716      version: "1.8.18"
2717  });
2718  
2719  /*
2720   * Resizable Extensions
2721   */
2722  
2723  $.ui.plugin.add("resizable", "alsoResize", {
2724  
2725      start: function (event, ui) {
2726          var self = $(this).data("resizable"), o = self.options;
2727  
2728          var _store = function (exp) {
2729              $(exp).each(function() {
2730                  var el = $(this);
2731                  el.data("resizable-alsoresize", {
2732                      width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2733                      left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2734                  });
2735              });
2736          };
2737  
2738          if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2739              if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2740              else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2741          }else{
2742              _store(o.alsoResize);
2743          }
2744      },
2745  
2746      resize: function (event, ui) {
2747          var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2748  
2749          var delta = {
2750              height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2751              top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2752          },
2753  
2754          _alsoResize = function (exp, c) {
2755              $(exp).each(function() {
2756                  var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
2757                      css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2758  
2759                  $.each(css, function (i, prop) {
2760                      var sum = (start[prop]||0) + (delta[prop]||0);
2761                      if (sum && sum >= 0)
2762                          style[prop] = sum || null;
2763                  });
2764  
2765                  el.css(style);
2766              });
2767          };
2768  
2769          if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2770              $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2771          }else{
2772              _alsoResize(o.alsoResize);
2773          }
2774      },
2775  
2776      stop: function (event, ui) {
2777          $(this).removeData("resizable-alsoresize");
2778      }
2779  });
2780  
2781  $.ui.plugin.add("resizable", "animate", {
2782  
2783      stop: function(event, ui) {
2784          var self = $(this).data("resizable"), o = self.options;
2785  
2786          var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2787                      soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2788                          soffsetw = ista ? 0 : self.sizeDiff.width;
2789  
2790          var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2791                      left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2792                          top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2793  
2794          self.element.animate(
2795              $.extend(style, top && left ? { top: top, left: left } : {}), {
2796                  duration: o.animateDuration,
2797                  easing: o.animateEasing,
2798                  step: function() {
2799  
2800                      var data = {
2801                          width: parseInt(self.element.css('width'), 10),
2802                          height: parseInt(self.element.css('height'), 10),
2803                          top: parseInt(self.element.css('top'), 10),
2804                          left: parseInt(self.element.css('left'), 10)
2805                      };
2806  
2807                      if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2808  
2809                      // propagating resize, and updating values for each animation step
2810                      self._updateCache(data);
2811                      self._propagate("resize", event);
2812  
2813                  }
2814              }
2815          );
2816      }
2817  
2818  });
2819  
2820  $.ui.plugin.add("resizable", "containment", {
2821  
2822      start: function(event, ui) {
2823          var self = $(this).data("resizable"), o = self.options, el = self.element;
2824          var oc = o.containment,    ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2825          if (!ce) return;
2826  
2827          self.containerElement = $(ce);
2828  
2829          if (/document/.test(oc) || oc == document) {
2830              self.containerOffset = { left: 0, top: 0 };
2831              self.containerPosition = { left: 0, top: 0 };
2832  
2833              self.parentData = {
2834                  element: $(document), left: 0, top: 0,
2835                  width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2836              };
2837          }
2838  
2839          // i'm a node, so compute top, left, right, bottom
2840          else {
2841              var element = $(ce), p = [];
2842              $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2843  
2844              self.containerOffset = element.offset();
2845              self.containerPosition = element.position();
2846              self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2847  
2848              var co = self.containerOffset, ch = self.containerSize.height,    cw = self.containerSize.width,
2849                          width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2850  
2851              self.parentData = {
2852                  element: ce, left: co.left, top: co.top, width: width, height: height
2853              };
2854          }
2855      },
2856  
2857      resize: function(event, ui) {
2858          var self = $(this).data("resizable"), o = self.options,
2859                  ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2860                  pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2861  
2862          if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2863  
2864          if (cp.left < (self._helper ? co.left : 0)) {
2865              self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2866              if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2867              self.position.left = o.helper ? co.left : 0;
2868          }
2869  
2870          if (cp.top < (self._helper ? co.top : 0)) {
2871              self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2872              if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2873              self.position.top = self._helper ? co.top : 0;
2874          }
2875  
2876          self.offset.left = self.parentData.left+self.position.left;
2877          self.offset.top = self.parentData.top+self.position.top;
2878  
2879          var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2880                      hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2881  
2882          var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2883              isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2884  
2885          if(isParent && isOffsetRelative) woset -= self.parentData.left;
2886  
2887          if (woset + self.size.width >= self.parentData.width) {
2888              self.size.width = self.parentData.width - woset;
2889              if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2890          }
2891  
2892          if (hoset + self.size.height >= self.parentData.height) {
2893              self.size.height = self.parentData.height - hoset;
2894              if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2895          }
2896      },
2897  
2898      stop: function(event, ui){
2899          var self = $(this).data("resizable"), o = self.options, cp = self.position,
2900                  co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2901  
2902          var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2903  
2904          if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2905              $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2906  
2907          if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2908              $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2909  
2910      }
2911  });
2912  
2913  $.ui.plugin.add("resizable", "ghost", {
2914  
2915      start: function(event, ui) {
2916  
2917          var self = $(this).data("resizable"), o = self.options, cs = self.size;
2918  
2919          self.ghost = self.originalElement.clone();
2920          self.ghost
2921              .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2922              .addClass('ui-resizable-ghost')
2923              .addClass(typeof o.ghost == 'string' ? o.ghost : '');
2924  
2925          self.ghost.appendTo(self.helper);
2926  
2927      },
2928  
2929      resize: function(event, ui){
2930          var self = $(this).data("resizable"), o = self.options;
2931          if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2932      },
2933  
2934      stop: function(event, ui){
2935          var self = $(this).data("resizable"), o = self.options;
2936          if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2937      }
2938  
2939  });
2940  
2941  $.ui.plugin.add("resizable", "grid", {
2942  
2943      resize: function(event, ui) {
2944          var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2945          o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2946          var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2947  
2948          if (/^(se|s|e)$/.test(a)) {
2949              self.size.width = os.width + ox;
2950              self.size.height = os.height + oy;
2951          }
2952          else if (/^(ne)$/.test(a)) {
2953              self.size.width = os.width + ox;
2954              self.size.height = os.height + oy;
2955              self.position.top = op.top - oy;
2956          }
2957          else if (/^(sw)$/.test(a)) {
2958              self.size.width = os.width + ox;
2959              self.size.height = os.height + oy;
2960              self.position.left = op.left - ox;
2961          }
2962          else {
2963              self.size.width = os.width + ox;
2964              self.size.height = os.height + oy;
2965              self.position.top = op.top - oy;
2966              self.position.left = op.left - ox;
2967          }
2968      }
2969  
2970  });
2971  
2972  var num = function(v) {
2973      return parseInt(v, 10) || 0;
2974  };
2975  
2976  var isNumber = function(value) {
2977      return !isNaN(parseInt(value, 10));
2978  };
2979  
2980  })(jQuery);
2981  /*
2982   * jQuery UI Selectable 1.8.18
2983   *
2984   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2985   * Dual licensed under the MIT or GPL Version 2 licenses.
2986   * http://jquery.org/license
2987   *
2988   * http://docs.jquery.com/UI/Selectables
2989   *
2990   * Depends:
2991   *    jquery.ui.core.js
2992   *    jquery.ui.mouse.js
2993   *    jquery.ui.widget.js
2994   */
2995  (function( $, undefined ) {
2996  
2997  $.widget("ui.selectable", $.ui.mouse, {
2998      options: {
2999          appendTo: 'body',
3000          autoRefresh: true,
3001          distance: 0,
3002          filter: '*',
3003          tolerance: 'touch'
3004      },
3005      _create: function() {
3006          var self = this;
3007  
3008          this.element.addClass("ui-selectable");
3009  
3010          this.dragged = false;
3011  
3012          // cache selectee children based on filter
3013          var selectees;
3014          this.refresh = function() {
3015              selectees = $(self.options.filter, self.element[0]);
3016              selectees.addClass("ui-selectee");
3017              selectees.each(function() {
3018                  var $this = $(this);
3019                  var pos = $this.offset();
3020                  $.data(this, "selectable-item", {
3021                      element: this,
3022                      $element: $this,
3023                      left: pos.left,
3024                      top: pos.top,
3025                      right: pos.left + $this.outerWidth(),
3026                      bottom: pos.top + $this.outerHeight(),
3027                      startselected: false,
3028                      selected: $this.hasClass('ui-selected'),
3029                      selecting: $this.hasClass('ui-selecting'),
3030                      unselecting: $this.hasClass('ui-unselecting')
3031                  });
3032              });
3033          };
3034          this.refresh();
3035  
3036          this.selectees = selectees.addClass("ui-selectee");
3037  
3038          this._mouseInit();
3039  
3040          this.helper = $("<div class='ui-selectable-helper'></div>");
3041      },
3042  
3043      destroy: function() {
3044          this.selectees
3045              .removeClass("ui-selectee")
3046              .removeData("selectable-item");
3047          this.element
3048              .removeClass("ui-selectable ui-selectable-disabled")
3049              .removeData("selectable")
3050              .unbind(".selectable");
3051          this._mouseDestroy();
3052  
3053          return this;
3054      },
3055  
3056      _mouseStart: function(event) {
3057          var self = this;
3058  
3059          this.opos = [event.pageX, event.pageY];
3060  
3061          if (this.options.disabled)
3062              return;
3063  
3064          var options = this.options;
3065  
3066          this.selectees = $(options.filter, this.element[0]);
3067  
3068          this._trigger("start", event);
3069  
3070          $(options.appendTo).append(this.helper);
3071          // position helper (lasso)
3072          this.helper.css({
3073              "left": event.clientX,
3074              "top": event.clientY,
3075              "width": 0,
3076              "height": 0
3077          });
3078  
3079          if (options.autoRefresh) {
3080              this.refresh();
3081          }
3082  
3083          this.selectees.filter('.ui-selected').each(function() {
3084              var selectee = $.data(this, "selectable-item");
3085              selectee.startselected = true;
3086              if (!event.metaKey && !event.ctrlKey) {
3087                  selectee.$element.removeClass('ui-selected');
3088                  selectee.selected = false;
3089                  selectee.$element.addClass('ui-unselecting');
3090                  selectee.unselecting = true;
3091                  // selectable UNSELECTING callback
3092                  self._trigger("unselecting", event, {
3093                      unselecting: selectee.element
3094                  });
3095              }
3096          });
3097  
3098          $(event.target).parents().andSelf().each(function() {
3099              var selectee = $.data(this, "selectable-item");
3100              if (selectee) {
3101                  var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
3102                  selectee.$element
3103                      .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3104                      .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3105                  selectee.unselecting = !doSelect;
3106                  selectee.selecting = doSelect;
3107                  selectee.selected = doSelect;
3108                  // selectable (UN)SELECTING callback
3109                  if (doSelect) {
3110                      self._trigger("selecting", event, {
3111                          selecting: selectee.element
3112                      });
3113                  } else {
3114                      self._trigger("unselecting", event, {
3115                          unselecting: selectee.element
3116                      });
3117                  }
3118                  return false;
3119              }
3120          });
3121  
3122      },
3123  
3124      _mouseDrag: function(event) {
3125          var self = this;
3126          this.dragged = true;
3127  
3128          if (this.options.disabled)
3129              return;
3130  
3131          var options = this.options;
3132  
3133          var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
3134          if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
3135          if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
3136          this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3137  
3138          this.selectees.each(function() {
3139              var selectee = $.data(this, "selectable-item");
3140              //prevent helper from being selected if appendTo: selectable
3141              if (!selectee || selectee.element == self.element[0])
3142                  return;
3143              var hit = false;
3144              if (options.tolerance == 'touch') {
3145                  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3146              } else if (options.tolerance == 'fit') {
3147                  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3148              }
3149  
3150              if (hit) {
3151                  // SELECT
3152                  if (selectee.selected) {
3153                      selectee.$element.removeClass('ui-selected');
3154                      selectee.selected = false;
3155                  }
3156                  if (selectee.unselecting) {
3157                      selectee.$element.removeClass('ui-unselecting');
3158                      selectee.unselecting = false;
3159                  }
3160                  if (!selectee.selecting) {
3161                      selectee.$element.addClass('ui-selecting');
3162                      selectee.selecting = true;
3163                      // selectable SELECTING callback
3164                      self._trigger("selecting", event, {
3165                          selecting: selectee.element
3166                      });
3167                  }
3168              } else {
3169                  // UNSELECT
3170                  if (selectee.selecting) {
3171                      if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3172                          selectee.$element.removeClass('ui-selecting');
3173                          selectee.selecting = false;
3174                          selectee.$element.addClass('ui-selected');
3175                          selectee.selected = true;
3176                      } else {
3177                          selectee.$element.removeClass('ui-selecting');
3178                          selectee.selecting = false;
3179                          if (selectee.startselected) {
3180                              selectee.$element.addClass('ui-unselecting');
3181                              selectee.unselecting = true;
3182                          }
3183                          // selectable UNSELECTING callback
3184                          self._trigger("unselecting", event, {
3185                              unselecting: selectee.element
3186                          });
3187                      }
3188                  }
3189                  if (selectee.selected) {
3190                      if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3191                          selectee.$element.removeClass('ui-selected');
3192                          selectee.selected = false;
3193  
3194                          selectee.$element.addClass('ui-unselecting');
3195                          selectee.unselecting = true;
3196                          // selectable UNSELECTING callback
3197                          self._trigger("unselecting", event, {
3198                              unselecting: selectee.element
3199                          });
3200                      }
3201                  }
3202              }
3203          });
3204  
3205          return false;
3206      },
3207  
3208      _mouseStop: function(event) {
3209          var self = this;
3210  
3211          this.dragged = false;
3212  
3213          var options = this.options;
3214  
3215          $('.ui-unselecting', this.element[0]).each(function() {
3216              var selectee = $.data(this, "selectable-item");
3217              selectee.$element.removeClass('ui-unselecting');
3218              selectee.unselecting = false;
3219              selectee.startselected = false;
3220              self._trigger("unselected", event, {
3221                  unselected: selectee.element
3222              });
3223          });
3224          $('.ui-selecting', this.element[0]).each(function() {
3225              var selectee = $.data(this, "selectable-item");
3226              selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
3227              selectee.selecting = false;
3228              selectee.selected = true;
3229              selectee.startselected = true;
3230              self._trigger("selected", event, {
3231                  selected: selectee.element
3232              });
3233          });
3234          this._trigger("stop", event);
3235  
3236          this.helper.remove();
3237  
3238          return false;
3239      }
3240  
3241  });
3242  
3243  $.extend($.ui.selectable, {
3244      version: "1.8.18"
3245  });
3246  
3247  })(jQuery);
3248  /*
3249   * jQuery UI Sortable 1.8.18
3250   *
3251   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
3252   * Dual licensed under the MIT or GPL Version 2 licenses.
3253   * http://jquery.org/license
3254   *
3255   * http://docs.jquery.com/UI/Sortables
3256   *
3257   * Depends:
3258   *    jquery.ui.core.js
3259   *    jquery.ui.mouse.js
3260   *    jquery.ui.widget.js
3261   */
3262  (function( $, undefined ) {
3263  
3264  $.widget("ui.sortable", $.ui.mouse, {
3265      widgetEventPrefix: "sort",
3266      ready: false,
3267      options: {
3268          appendTo: "parent",
3269          axis: false,
3270          connectWith: false,
3271          containment: false,
3272          cursor: 'auto',
3273          cursorAt: false,
3274          dropOnEmpty: true,
3275          forcePlaceholderSize: false,
3276          forceHelperSize: false,
3277          grid: false,
3278          handle: false,
3279          helper: "original",
3280          items: '> *',
3281          opacity: false,
3282          placeholder: false,
3283          revert: false,
3284          scroll: true,
3285          scrollSensitivity: 20,
3286          scrollSpeed: 20,
3287          scope: "default",
3288          tolerance: "intersect",
3289          zIndex: 1000
3290      },
3291      _create: function() {
3292  
3293          var o = this.options;
3294          this.containerCache = {};
3295          this.element.addClass("ui-sortable");
3296  
3297          //Get the items
3298          this.refresh();
3299  
3300          //Let's determine if the items are being displayed horizontally
3301          this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3302  
3303          //Let's determine the parent's offset
3304          this.offset = this.element.offset();
3305  
3306          //Initialize mouse events for interaction
3307          this._mouseInit();
3308          
3309          //We're ready to go
3310          this.ready = true
3311  
3312      },
3313  
3314      destroy: function() {
3315          $.Widget.prototype.destroy.call( this );
3316          this.element
3317              .removeClass("ui-sortable ui-sortable-disabled");
3318          this._mouseDestroy();
3319  
3320          for ( var i = this.items.length - 1; i >= 0; i-- )
3321              this.items[i].item.removeData(this.widgetName + "-item");
3322  
3323          return this;
3324      },
3325  
3326      _setOption: function(key, value){
3327          if ( key === "disabled" ) {
3328              this.options[ key ] = value;
3329      
3330              this.widget()
3331                  [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3332          } else {
3333              // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3334              $.Widget.prototype._setOption.apply(this, arguments);
3335          }
3336      },
3337  
3338      _mouseCapture: function(event, overrideHandle) {
3339          var that = this;
3340  
3341          if (this.reverting) {
3342              return false;
3343          }
3344  
3345          if(this.options.disabled || this.options.type == 'static') return false;
3346  
3347          //We have to refresh the items data once first
3348          this._refreshItems(event);
3349  
3350          //Find out if the clicked node (or one of its parents) is a actual item in this.items
3351          var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3352              if($.data(this, that.widgetName + '-item') == self) {
3353                  currentItem = $(this);
3354                  return false;
3355              }
3356          });
3357          if($.data(event.target, that.widgetName + '-item') == self) currentItem = $(event.target);
3358  
3359          if(!currentItem) return false;
3360          if(this.options.handle && !overrideHandle) {
3361              var validHandle = false;
3362  
3363              $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3364              if(!validHandle) return false;
3365          }
3366  
3367          this.currentItem = currentItem;
3368          this._removeCurrentsFromItems();
3369          return true;
3370  
3371      },
3372  
3373      _mouseStart: function(event, overrideHandle, noActivation) {
3374  
3375          var o = this.options, self = this;
3376          this.currentContainer = this;
3377  
3378          //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3379          this.refreshPositions();
3380  
3381          //Create and append the visible helper
3382          this.helper = this._createHelper(event);
3383  
3384          //Cache the helper size
3385          this._cacheHelperProportions();
3386  
3387          /*
3388           * - Position generation -
3389           * This block generates everything position related - it's the core of draggables.
3390           */
3391  
3392          //Cache the margins of the original element
3393          this._cacheMargins();
3394  
3395          //Get the next scrolling parent
3396          this.scrollParent = this.helper.scrollParent();
3397  
3398          //The element's absolute position on the page minus margins
3399          this.offset = this.currentItem.offset();
3400          this.offset = {
3401              top: this.offset.top - this.margins.top,
3402              left: this.offset.left - this.margins.left
3403          };
3404  
3405          // Only after we got the offset, we can change the helper's position to absolute
3406          // TODO: Still need to figure out a way to make relative sorting possible
3407          this.helper.css("position", "absolute");
3408          this.cssPosition = this.helper.css("position");
3409  
3410          $.extend(this.offset, {
3411              click: { //Where the click happened, relative to the element
3412                  left: event.pageX - this.offset.left,
3413                  top: event.pageY - this.offset.top
3414              },
3415              parent: this._getParentOffset(),
3416              relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3417          });
3418  
3419          //Generate the original position
3420          this.originalPosition = this._generatePosition(event);
3421          this.originalPageX = event.pageX;
3422          this.originalPageY = event.pageY;
3423  
3424          //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3425          (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3426  
3427          //Cache the former DOM position
3428          this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3429  
3430          //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
3431          if(this.helper[0] != this.currentItem[0]) {
3432              this.currentItem.hide();
3433          }
3434  
3435          //Create the placeholder
3436          this._createPlaceholder();
3437  
3438          //Set a containment if given in the options
3439          if(o.containment)
3440              this._setContainment();
3441  
3442          if(o.cursor) { // cursor option
3443              if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3444              $('body').css("cursor", o.cursor);
3445          }
3446  
3447          if(o.opacity) { // opacity option
3448              if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3449              this.helper.css("opacity", o.opacity);
3450          }
3451  
3452          if(o.zIndex) { // zIndex option
3453              if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3454              this.helper.css("zIndex", o.zIndex);
3455          }
3456  
3457          //Prepare scrolling
3458          if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3459              this.overflowOffset = this.scrollParent.offset();
3460  
3461          //Call callbacks
3462          this._trigger("start", event, this._uiHash());
3463  
3464          //Recache the helper size
3465          if(!this._preserveHelperProportions)
3466              this._cacheHelperProportions();
3467  
3468  
3469          //Post 'activate' events to possible containers
3470          if(!noActivation) {
3471               for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3472          }
3473  
3474          //Prepare possible droppables
3475          if($.ui.ddmanager)
3476              $.ui.ddmanager.current = this;
3477  
3478          if ($.ui.ddmanager && !o.dropBehaviour)
3479              $.ui.ddmanager.prepareOffsets(this, event);
3480  
3481          this.dragging = true;
3482  
3483          this.helper.addClass("ui-sortable-helper");
3484          this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3485          return true;
3486  
3487      },
3488  
3489      _mouseDrag: function(event) {
3490  
3491          //Compute the helpers position
3492          this.position = this._generatePosition(event);
3493          this.positionAbs = this._convertPositionTo("absolute");
3494  
3495          if (!this.lastPositionAbs) {
3496              this.lastPositionAbs = this.positionAbs;
3497          }
3498  
3499          //Do scrolling
3500          if(this.options.scroll) {
3501              var o = this.options, scrolled = false;
3502              if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3503  
3504                  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3505                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3506                  else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3507                      this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3508  
3509                  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3510                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3511                  else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3512                      this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3513  
3514              } else {
3515  
3516                  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3517                      scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3518                  else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3519                      scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3520  
3521                  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3522                      scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3523                  else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3524                      scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3525  
3526              }
3527  
3528              if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3529                  $.ui.ddmanager.prepareOffsets(this, event);
3530          }
3531  
3532          //Regenerate the absolute position used for position checks
3533          this.positionAbs = this._convertPositionTo("absolute");
3534  
3535          //Set the helper position
3536          if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3537          if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3538  
3539          //Rearrange
3540          for (var i = this.items.length - 1; i >= 0; i--) {
3541  
3542              //Cache variables and intersection, continue if no intersection
3543              var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3544              if (!intersection) continue;
3545  
3546              if(itemElement != this.currentItem[0] //cannot intersect with itself
3547                  &&    this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3548                  &&    !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3549                  && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3550                  //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3551              ) {
3552  
3553                  this.direction = intersection == 1 ? "down" : "up";
3554  
3555                  if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3556                      this._rearrange(event, item);
3557                  } else {
3558                      break;
3559                  }
3560  
3561                  this._trigger("change", event, this._uiHash());
3562                  break;
3563              }
3564          }
3565  
3566          //Post events to containers
3567          this._contactContainers(event);
3568  
3569          //Interconnect with droppables
3570          if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3571  
3572          //Call callbacks
3573          this._trigger('sort', event, this._uiHash());
3574  
3575          this.lastPositionAbs = this.positionAbs;
3576          return false;
3577  
3578      },
3579  
3580      _mouseStop: function(event, noPropagation) {
3581  
3582          if(!event) return;
3583  
3584          //If we are using droppables, inform the manager about the drop
3585          if ($.ui.ddmanager && !this.options.dropBehaviour)
3586              $.ui.ddmanager.drop(this, event);
3587  
3588          if(this.options.revert) {
3589              var self = this;
3590              var cur = self.placeholder.offset();
3591  
3592              self.reverting = true;
3593  
3594              $(this.helper).animate({
3595                  left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3596                  top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3597              }, parseInt(this.options.revert, 10) || 500, function() {
3598                  self._clear(event);
3599              });
3600          } else {
3601              this._clear(event, noPropagation);
3602          }
3603  
3604          return false;
3605  
3606      },
3607  
3608      cancel: function() {
3609  
3610          var self = this;
3611  
3612          if(this.dragging) {
3613  
3614              this._mouseUp({ target: null });
3615  
3616              if(this.options.helper == "original")
3617                  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3618              else
3619                  this.currentItem.show();
3620  
3621              //Post deactivating events to containers
3622              for (var i = this.containers.length - 1; i >= 0; i--){
3623                  this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3624                  if(this.containers[i].containerCache.over) {
3625                      this.containers[i]._trigger("out", null, self._uiHash(this));
3626                      this.containers[i].containerCache.over = 0;
3627                  }
3628              }
3629  
3630          }
3631  
3632          if (this.placeholder) {
3633              //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3634              if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3635              if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3636  
3637              $.extend(this, {
3638                  helper: null,
3639                  dragging: false,
3640                  reverting: false,
3641                  _noFinalSort: null
3642              });
3643  
3644              if(this.domPosition.prev) {
3645                  $(this.domPosition.prev).after(this.currentItem);
3646              } else {
3647                  $(this.domPosition.parent).prepend(this.currentItem);
3648              }
3649          }
3650  
3651          return this;
3652  
3653      },
3654  
3655      serialize: function(o) {
3656  
3657          var items = this._getItemsAsjQuery(o && o.connected);
3658          var str = []; o = o || {};
3659  
3660          $(items).each(function() {
3661              var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3662              if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3663          });
3664  
3665          if(!str.length && o.key) {
3666              str.push(o.key + '=');
3667          }
3668  
3669          return str.join('&');
3670  
3671      },
3672  
3673      toArray: function(o) {
3674  
3675          var items = this._getItemsAsjQuery(o && o.connected);
3676          var ret = []; o = o || {};
3677  
3678          items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3679          return ret;
3680  
3681      },
3682  
3683      /* Be careful with the following core functions */
3684      _intersectsWith: function(item) {
3685  
3686          var x1 = this.positionAbs.left,
3687              x2 = x1 + this.helperProportions.width,
3688              y1 = this.positionAbs.top,
3689              y2 = y1 + this.helperProportions.height;
3690  
3691          var l = item.left,
3692              r = l + item.width,
3693              t = item.top,
3694              b = t + item.height;
3695  
3696          var dyClick = this.offset.click.top,
3697              dxClick = this.offset.click.left;
3698  
3699          var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3700  
3701          if(       this.options.tolerance == "pointer"
3702              || this.options.forcePointerForContainers
3703              || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3704          ) {
3705              return isOverElement;
3706          } else {
3707  
3708              return (l < x1 + (this.helperProportions.width / 2) // Right Half
3709                  && x2 - (this.helperProportions.width / 2) < r // Left Half
3710                  && t < y1 + (this.helperProportions.height / 2) // Bottom Half
3711                  && y2 - (this.helperProportions.height / 2) < b ); // Top Half
3712  
3713          }
3714      },
3715  
3716      _intersectsWithPointer: function(item) {
3717  
3718          var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3719              isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3720              isOverElement = isOverElementHeight && isOverElementWidth,
3721              verticalDirection = this._getDragVerticalDirection(),
3722              horizontalDirection = this._getDragHorizontalDirection();
3723  
3724          if (!isOverElement)
3725              return false;
3726  
3727          return this.floating ?
3728              ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3729              : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3730  
3731      },
3732  
3733      _intersectsWithSides: function(item) {
3734  
3735          var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3736              isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3737              verticalDirection = this._getDragVerticalDirection(),
3738              horizontalDirection = this._getDragHorizontalDirection();
3739  
3740          if (this.floating && horizontalDirection) {
3741              return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3742          } else {
3743              return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3744          }
3745  
3746      },
3747  
3748      _getDragVerticalDirection: function() {
3749          var delta = this.positionAbs.top - this.lastPositionAbs.top;
3750          return delta != 0 && (delta > 0 ? "down" : "up");
3751      },
3752  
3753      _getDragHorizontalDirection: function() {
3754          var delta = this.positionAbs.left - this.lastPositionAbs.left;
3755          return delta != 0 && (delta > 0 ? "right" : "left");
3756      },
3757  
3758      refresh: function(event) {
3759          this._refreshItems(event);
3760          this.refreshPositions();
3761          return this;
3762      },
3763  
3764      _connectWith: function() {
3765          var options = this.options;
3766          return options.connectWith.constructor == String
3767              ? [options.connectWith]
3768              : options.connectWith;
3769      },
3770      
3771      _getItemsAsjQuery: function(connected) {
3772  
3773          var self = this;
3774          var items = [];
3775          var queries = [];
3776          var connectWith = this._connectWith();
3777  
3778          if(connectWith && connected) {
3779              for (var i = connectWith.length - 1; i >= 0; i--){
3780                  var cur = $(connectWith[i]);
3781                  for (var j = cur.length - 1; j >= 0; j--){
3782                      var inst = $.data(cur[j], this.widgetName);
3783                      if(inst && inst != this && !inst.options.disabled) {
3784                          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]);
3785                      }
3786                  };
3787              };
3788          }
3789  
3790          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]);
3791  
3792          for (var i = queries.length - 1; i >= 0; i--){
3793              queries[i][0].each(function() {
3794                  items.push(this);
3795              });
3796          };
3797  
3798          return $(items);
3799  
3800      },
3801  
3802      _removeCurrentsFromItems: function() {
3803  
3804          var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3805  
3806          for (var i=0; i < this.items.length; i++) {
3807  
3808              for (var j=0; j < list.length; j++) {
3809                  if(list[j] == this.items[i].item[0])
3810                      this.items.splice(i,1);
3811              };
3812  
3813          };
3814  
3815      },
3816  
3817      _refreshItems: function(event) {
3818  
3819          this.items = [];
3820          this.containers = [this];
3821          var items = this.items;
3822          var self = this;
3823          var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3824          var connectWith = this._connectWith();
3825  
3826          if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3827              for (var i = connectWith.length - 1; i >= 0; i--){
3828                  var cur = $(connectWith[i]);
3829                  for (var j = cur.length - 1; j >= 0; j--){
3830                      var inst = $.data(cur[j], this.widgetName);
3831                      if(inst && inst != this && !inst.options.disabled) {
3832                          queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3833                          this.containers.push(inst);
3834                      }
3835                  };
3836              };
3837          }
3838  
3839          for (var i = queries.length - 1; i >= 0; i--) {
3840              var targetData = queries[i][1];
3841              var _queries = queries[i][0];
3842  
3843              for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3844                  var item = $(_queries[j]);
3845  
3846                  item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3847  
3848                  items.push({
3849                      item: item,
3850                      instance: targetData,
3851                      width: 0, height: 0,
3852                      left: 0, top: 0
3853                  });
3854              };
3855          };
3856  
3857      },
3858  
3859      refreshPositions: function(fast) {
3860  
3861          //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3862          if(this.offsetParent && this.helper) {
3863              this.offset.parent = this._getParentOffset();
3864          }
3865  
3866          for (var i = this.items.length - 1; i >= 0; i--){
3867              var item = this.items[i];
3868  
3869              //We ignore calculating positions of all connected containers when we're not over them
3870              if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3871                  continue;
3872  
3873              var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3874  
3875              if (!fast) {
3876                  item.width = t.outerWidth();
3877                  item.height = t.outerHeight();
3878              }
3879  
3880              var p = t.offset();
3881              item.left = p.left;
3882              item.top = p.top;
3883          };
3884  
3885          if(this.options.custom && this.options.custom.refreshContainers) {
3886              this.options.custom.refreshContainers.call(this);
3887          } else {
3888              for (var i = this.containers.length - 1; i >= 0; i--){
3889                  var p = this.containers[i].element.offset();
3890                  this.containers[i].containerCache.left = p.left;
3891                  this.containers[i].containerCache.top = p.top;
3892                  this.containers[i].containerCache.width    = this.containers[i].element.outerWidth();
3893                  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3894              };
3895          }
3896  
3897          return this;
3898      },
3899  
3900      _createPlaceholder: function(that) {
3901  
3902          var self = that || this, o = self.options;
3903  
3904          if(!o.placeholder || o.placeholder.constructor == String) {
3905              var className = o.placeholder;
3906              o.placeholder = {
3907                  element: function() {
3908  
3909                      var el = $(document.createElement(self.currentItem[0].nodeName))
3910                          .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3911                          .removeClass("ui-sortable-helper")[0];
3912  
3913                      if(!className)
3914                          el.style.visibility = "hidden";
3915  
3916                      return el;
3917                  },
3918                  update: function(container, p) {
3919  
3920                      // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3921                      // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3922                      if(className && !o.forcePlaceholderSize) return;
3923  
3924                      //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
3925                      if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3926                      if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3927                  }
3928              };
3929          }
3930  
3931          //Create the placeholder
3932          self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3933  
3934          //Append it after the actual current item
3935          self.currentItem.after(self.placeholder);
3936  
3937          //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3938          o.placeholder.update(self, self.placeholder);
3939  
3940      },
3941  
3942      _contactContainers: function(event) {
3943          
3944          // get innermost container that intersects with item 
3945          var innermostContainer = null, innermostIndex = null;        
3946          
3947          
3948          for (var i = this.containers.length - 1; i >= 0; i--){
3949  
3950              // never consider a container that's located within the item itself 
3951              if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3952                  continue;
3953  
3954              if(this._intersectsWith(this.containers[i].containerCache)) {
3955  
3956                  // if we've already found a container and it's more "inner" than this, then continue 
3957                  if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3958                      continue;
3959  
3960                  innermostContainer = this.containers[i]; 
3961                  innermostIndex = i;
3962                      
3963              } else {
3964                  // container doesn't intersect. trigger "out" event if necessary 
3965                  if(this.containers[i].containerCache.over) {
3966                      this.containers[i]._trigger("out", event, this._uiHash(this));
3967                      this.containers[i].containerCache.over = 0;
3968                  }
3969              }
3970  
3971          }
3972          
3973          // if no intersecting containers found, return 
3974          if(!innermostContainer) return; 
3975  
3976          // move the item into the container if it's not there already
3977          if(this.containers.length === 1) {
3978              this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3979              this.containers[innermostIndex].containerCache.over = 1;
3980          } else if(this.currentContainer != this.containers[innermostIndex]) { 
3981  
3982              //When entering a new container, we will find the item with the least distance and append our item near it 
3983              var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
3984              for (var j = this.items.length - 1; j >= 0; j--) { 
3985                  if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
3986                  var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
3987                  if(Math.abs(cur - base) < dist) { 
3988                      dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
3989                  } 
3990              } 
3991  
3992              if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
3993                  return; 
3994  
3995              this.currentContainer = this.containers[innermostIndex]; 
3996              itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
3997              this._trigger("change", event, this._uiHash()); 
3998              this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
3999  
4000              //Update the placeholder 
4001              this.options.placeholder.update(this.currentContainer, this.placeholder); 
4002          
4003              this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
4004              this.containers[innermostIndex].containerCache.over = 1;
4005          } 
4006      
4007          
4008      },
4009  
4010      _createHelper: function(event) {
4011  
4012          var o = this.options;
4013          var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
4014  
4015          if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
4016              $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4017  
4018          if(helper[0] == this.currentItem[0])
4019              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") };
4020  
4021          if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
4022          if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
4023  
4024          return helper;
4025  
4026      },
4027  
4028      _adjustOffsetFromHelper: function(obj) {
4029          if (typeof obj == 'string') {
4030              obj = obj.split(' ');
4031          }
4032          if ($.isArray(obj)) {
4033              obj = {left: +obj[0], top: +obj[1] || 0};
4034          }
4035          if ('left' in obj) {
4036              this.offset.click.left = obj.left + this.margins.left;
4037          }
4038          if ('right' in obj) {
4039              this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4040          }
4041          if ('top' in obj) {
4042              this.offset.click.top = obj.top + this.margins.top;
4043          }
4044          if ('bottom' in obj) {
4045              this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4046          }
4047      },
4048  
4049      _getParentOffset: function() {
4050  
4051  
4052          //Get the offsetParent and cache its position
4053          this.offsetParent = this.helper.offsetParent();
4054          var po = this.offsetParent.offset();
4055  
4056          // This is a special case where we need to modify a offset calculated on start, since the following happened:
4057          // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4058          // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4059          //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4060          if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
4061              po.left += this.scrollParent.scrollLeft();
4062              po.top += this.scrollParent.scrollTop();
4063          }
4064  
4065          if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4066          || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
4067              po = { top: 0, left: 0 };
4068  
4069          return {
4070              top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4071              left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4072          };
4073  
4074      },
4075  
4076      _getRelativeOffset: function() {
4077  
4078          if(this.cssPosition == "relative") {
4079              var p = this.currentItem.position();
4080              return {
4081                  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4082                  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4083              };
4084          } else {
4085              return { top: 0, left: 0 };
4086          }
4087  
4088      },
4089  
4090      _cacheMargins: function() {
4091          this.margins = {
4092              left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4093              top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4094          };
4095      },
4096  
4097      _cacheHelperProportions: function() {
4098          this.helperProportions = {
4099              width: this.helper.outerWidth(),
4100              height: this.helper.outerHeight()
4101          };
4102      },
4103  
4104      _setContainment: function() {
4105  
4106          var o = this.options;
4107          if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
4108          if(o.containment == 'document' || o.containment == 'window') this.containment = [
4109              0 - this.offset.relative.left - this.offset.parent.left,
4110              0 - this.offset.relative.top - this.offset.parent.top,
4111              $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
4112              ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4113          ];
4114  
4115          if(!(/^(document|window|parent)$/).test(o.containment)) {
4116              var ce = $(o.containment)[0];
4117              var co = $(o.containment).offset();
4118              var over = ($(ce).css("overflow") != 'hidden');
4119  
4120              this.containment = [
4121                  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4122                  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4123                  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,
4124                  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
4125              ];
4126          }
4127  
4128      },
4129  
4130      _convertPositionTo: function(d, pos) {
4131  
4132          if(!pos) pos = this.position;
4133          var mod = d == "absolute" ? 1 : -1;
4134          var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4135  
4136          return {
4137              top: (
4138                  pos.top                                                                    // The absolute mouse position
4139                  + this.offset.relative.top * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
4140                  + this.offset.parent.top * mod                                            // The offsetParent's offset without borders (offset + border)
4141                  - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4142              ),
4143              left: (
4144                  pos.left                                                                // The absolute mouse position
4145                  + this.offset.relative.left * mod                                        // Only for relative positioned nodes: Relative offset from element to offset parent
4146                  + this.offset.parent.left * mod                                            // The offsetParent's offset without borders (offset + border)
4147                  - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4148              )
4149          };
4150  
4151      },
4152  
4153      _generatePosition: function(event) {
4154  
4155          var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4156  
4157          // This is another very weird special case that only happens for relative elements:
4158          // 1. If the css position is relative
4159          // 2. and the scroll parent is the document or similar to the offset parent
4160          // we have to refresh the relative offset during the scroll so there are no jumps
4161          if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
4162              this.offset.relative = this._getRelativeOffset();
4163          }
4164  
4165          var pageX = event.pageX;
4166          var pageY = event.pageY;
4167  
4168          /*
4169           * - Position constraining -
4170           * Constrain the position to a mix of grid, containment.
4171           */
4172  
4173          if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4174  
4175              if(this.containment) {
4176                  if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
4177                  if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
4178                  if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
4179                  if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
4180              }
4181  
4182              if(o.grid) {
4183                  var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4184                  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;
4185  
4186                  var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4187                  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;
4188              }
4189  
4190          }
4191  
4192          return {
4193              top: (
4194                  pageY                                                                // The absolute mouse position
4195                  - this.offset.click.top                                                    // Click offset (relative to the element)
4196                  - this.offset.relative.top                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4197                  - this.offset.parent.top                                                // The offsetParent's offset without borders (offset + border)
4198                  + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4199              ),
4200              left: (
4201                  pageX                                                                // The absolute mouse position
4202                  - this.offset.click.left                                                // Click offset (relative to the element)
4203                  - this.offset.relative.left                                                // Only for relative positioned nodes: Relative offset from element to offset parent
4204                  - this.offset.parent.left                                                // The offsetParent's offset without borders (offset + border)
4205                  + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4206              )
4207          };
4208  
4209      },
4210  
4211      _rearrange: function(event, i, a, hardRefresh) {
4212  
4213          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));
4214  
4215          //Various things done here to improve the performance:
4216          // 1. we create a setTimeout, that calls refreshPositions
4217          // 2. on the instance, we have a counter variable, that get's higher after every append
4218          // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4219          // 4. this lets only the last addition to the timeout stack through
4220          this.counter = this.counter ? ++this.counter : 1;
4221          var self = this, counter = this.counter;
4222  
4223          window.setTimeout(function() {
4224              if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4225          },0);
4226  
4227      },
4228  
4229      _clear: function(event, noPropagation) {
4230  
4231          this.reverting = false;
4232          // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4233          // everything else normalized again
4234          var delayedTriggers = [], self = this;
4235  
4236          // We first have to update the dom position of the actual currentItem
4237          // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4238          if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
4239          this._noFinalSort = null;
4240  
4241          if(this.helper[0] == this.currentItem[0]) {
4242              for(var i in this._storedCSS) {
4243                  if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
4244              }
4245              this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4246          } else {
4247              this.currentItem.show();
4248          }
4249  
4250          if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4251          if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4252          if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
4253              if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4254              for (var i = this.containers.length - 1; i >= 0; i--){
4255                  if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
4256                      delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4257                      delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
4258                  }
4259              };
4260          };
4261  
4262          //Post events to containers
4263          for (var i = this.containers.length - 1; i >= 0; i--){
4264              if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4265              if(this.containers[i].containerCache.over) {
4266                  delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
4267                  this.containers[i].containerCache.over = 0;
4268              }
4269          }
4270  
4271          //Do what was originally in plugins
4272          if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
4273          if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
4274          if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
4275  
4276          this.dragging = false;
4277          if(this.cancelHelperRemoval) {
4278              if(!noPropagation) {
4279                  this._trigger("beforeStop", event, this._uiHash());
4280                  for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4281                  this._trigger("stop", event, this._uiHash());
4282              }
4283              return false;
4284          }
4285  
4286          if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
4287  
4288          //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4289          this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4290  
4291          if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
4292  
4293          if(!noPropagation) {
4294              for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
4295              this._trigger("stop", event, this._uiHash());
4296          }
4297  
4298          this.fromOutside = false;
4299          return true;
4300  
4301      },
4302  
4303      _trigger: function() {
4304          if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4305              this.cancel();
4306          }
4307      },
4308  
4309      _uiHash: function(inst) {
4310          var self = inst || this;
4311          return {
4312              helper: self.helper,
4313              placeholder: self.placeholder || $([]),
4314              position: self.position,
4315              originalPosition: self.originalPosition,
4316              offset: self.positionAbs,
4317              item: self.currentItem,
4318              sender: inst ? inst.element : null
4319          };
4320      }
4321  
4322  });
4323  
4324  $.extend($.ui.sortable, {
4325      version: "1.8.18"
4326  });
4327  
4328  })(jQuery);
4329  /*
4330   * jQuery UI Accordion 1.8.18
4331   *
4332   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4333   * Dual licensed under the MIT or GPL Version 2 licenses.
4334   * http://jquery.org/license
4335   *
4336   * http://docs.jquery.com/UI/Accordion
4337   *
4338   * Depends:
4339   *    jquery.ui.core.js
4340   *    jquery.ui.widget.js
4341   */
4342  (function( $, undefined ) {
4343  
4344  $.widget( "ui.accordion", {
4345      options: {
4346          active: 0,
4347          animated: "slide",
4348          autoHeight: true,
4349          clearStyle: false,
4350          collapsible: false,
4351          event: "click",
4352          fillSpace: false,
4353          header: "> li > :first-child,> :not(li):even",
4354          icons: {
4355              header: "ui-icon-triangle-1-e",
4356              headerSelected: "ui-icon-triangle-1-s"
4357          },
4358          navigation: false,
4359          navigationFilter: function() {
4360              return this.href.toLowerCase() === location.href.toLowerCase();
4361          }
4362      },
4363  
4364      _create: function() {
4365          var self = this,
4366              options = self.options;
4367  
4368          self.running = 0;
4369  
4370          self.element
4371              .addClass( "ui-accordion ui-widget ui-helper-reset" )
4372              // in lack of child-selectors in CSS
4373              // we need to mark top-LIs in a UL-accordion for some IE-fix
4374              .children( "li" )
4375                  .addClass( "ui-accordion-li-fix" );
4376  
4377          self.headers = self.element.find( options.header )
4378              .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4379              .bind( "mouseenter.accordion", function() {
4380                  if ( options.disabled ) {
4381                      return;
4382                  }
4383                  $( this ).addClass( "ui-state-hover" );
4384              })
4385              .bind( "mouseleave.accordion", function() {
4386                  if ( options.disabled ) {
4387                      return;
4388                  }
4389                  $( this ).removeClass( "ui-state-hover" );
4390              })
4391              .bind( "focus.accordion", function() {
4392                  if ( options.disabled ) {
4393                      return;
4394                  }
4395                  $( this ).addClass( "ui-state-focus" );
4396              })
4397              .bind( "blur.accordion", function() {
4398                  if ( options.disabled ) {
4399                      return;
4400                  }
4401                  $( this ).removeClass( "ui-state-focus" );
4402              });
4403  
4404          self.headers.next()
4405              .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4406  
4407          if ( options.navigation ) {
4408              var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
4409              if ( current.length ) {
4410                  var header = current.closest( ".ui-accordion-header" );
4411                  if ( header.length ) {
4412                      // anchor within header
4413                      self.active = header;
4414                  } else {
4415                      // anchor within content
4416                      self.active = current.closest( ".ui-accordion-content" ).prev();
4417                  }
4418              }
4419          }
4420  
4421          self.active = self._findActive( self.active || options.active )
4422              .addClass( "ui-state-default ui-state-active" )
4423              .toggleClass( "ui-corner-all" )
4424              .toggleClass( "ui-corner-top" );
4425          self.active.next().addClass( "ui-accordion-content-active" );
4426  
4427          self._createIcons();
4428          self.resize();
4429          
4430          // ARIA
4431          self.element.attr( "role", "tablist" );
4432  
4433          self.headers
4434              .attr( "role", "tab" )
4435              .bind( "keydown.accordion", function( event ) {
4436                  return self._keydown( event );
4437              })
4438              .next()
4439                  .attr( "role", "tabpanel" );
4440  
4441          self.headers
4442              .not( self.active || "" )
4443              .attr({
4444                  "aria-expanded": "false",
4445                  "aria-selected": "false",
4446                  tabIndex: -1
4447              })
4448              .next()
4449                  .hide();
4450  
4451          // make sure at least one header is in the tab order
4452          if ( !self.active.length ) {
4453              self.headers.eq( 0 ).attr( "tabIndex", 0 );
4454          } else {
4455              self.active
4456                  .attr({
4457                      "aria-expanded": "true",
4458                      "aria-selected": "true",
4459                      tabIndex: 0
4460                  });
4461          }
4462  
4463          // only need links in tab order for Safari
4464          if ( !$.browser.safari ) {
4465              self.headers.find( "a" ).attr( "tabIndex", -1 );
4466          }
4467  
4468          if ( options.event ) {
4469              self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
4470                  self._clickHandler.call( self, event, this );
4471                  event.preventDefault();
4472              });
4473          }
4474      },
4475  
4476      _createIcons: function() {
4477          var options = this.options;
4478          if ( options.icons ) {
4479              $( "<span></span>" )
4480                  .addClass( "ui-icon " + options.icons.header )
4481                  .prependTo( this.headers );
4482              this.active.children( ".ui-icon" )
4483                  .toggleClass(options.icons.header)
4484                  .toggleClass(options.icons.headerSelected);
4485              this.element.addClass( "ui-accordion-icons" );
4486          }
4487      },
4488  
4489      _destroyIcons: function() {
4490          this.headers.children( ".ui-icon" ).remove();
4491          this.element.removeClass( "ui-accordion-icons" );
4492      },
4493  
4494      destroy: function() {
4495          var options = this.options;
4496  
4497          this.element
4498              .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4499              .removeAttr( "role" );
4500  
4501          this.headers
4502              .unbind( ".accordion" )
4503              .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
4504              .removeAttr( "role" )
4505              .removeAttr( "aria-expanded" )
4506              .removeAttr( "aria-selected" )
4507              .removeAttr( "tabIndex" );
4508  
4509          this.headers.find( "a" ).removeAttr( "tabIndex" );
4510          this._destroyIcons();
4511          var contents = this.headers.next()
4512              .css( "display", "" )
4513              .removeAttr( "role" )
4514              .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4515          if ( options.autoHeight || options.fillHeight ) {
4516              contents.css( "height", "" );
4517          }
4518  
4519          return $.Widget.prototype.destroy.call( this );
4520      },
4521  
4522      _setOption: function( key, value ) {
4523          $.Widget.prototype._setOption.apply( this, arguments );
4524              
4525          if ( key == "active" ) {
4526              this.activate( value );
4527          }
4528          if ( key == "icons" ) {
4529              this._destroyIcons();
4530              if ( value ) {
4531                  this._createIcons();
4532              }
4533          }
4534          // #5332 - opacity doesn't cascade to positioned elements in IE
4535          // so we need to add the disabled class to the headers and panels
4536          if ( key == "disabled" ) {
4537              this.headers.add(this.headers.next())
4538                  [ value ? "addClass" : "removeClass" ](
4539                      "ui-accordion-disabled ui-state-disabled" );
4540          }
4541      },
4542  
4543      _keydown: function( event ) {
4544          if ( this.options.disabled || event.altKey || event.ctrlKey ) {
4545              return;
4546          }
4547  
4548          var keyCode = $.ui.keyCode,
4549              length = this.headers.length,
4550              currentIndex = this.headers.index( event.target ),
4551              toFocus = false;
4552  
4553          switch ( event.keyCode ) {
4554              case keyCode.RIGHT:
4555              case keyCode.DOWN:
4556                  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4557                  break;
4558              case keyCode.LEFT:
4559              case keyCode.UP:
4560                  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4561                  break;
4562              case keyCode.SPACE:
4563              case keyCode.ENTER:
4564                  this._clickHandler( { target: event.target }, event.target );
4565                  event.preventDefault();
4566          }
4567  
4568          if ( toFocus ) {
4569              $( event.target ).attr( "tabIndex", -1 );
4570              $( toFocus ).attr( "tabIndex", 0 );
4571              toFocus.focus();
4572              return false;
4573          }
4574  
4575          return true;
4576      },
4577  
4578      resize: function() {
4579          var options = this.options,
4580              maxHeight;
4581  
4582          if ( options.fillSpace ) {
4583              if ( $.browser.msie ) {
4584                  var defOverflow = this.element.parent().css( "overflow" );
4585                  this.element.parent().css( "overflow", "hidden");
4586              }
4587              maxHeight = this.element.parent().height();
4588              if ($.browser.msie) {
4589                  this.element.parent().css( "overflow", defOverflow );
4590              }
4591  
4592              this.headers.each(function() {
4593                  maxHeight -= $( this ).outerHeight( true );
4594              });
4595  
4596              this.headers.next()
4597                  .each(function() {
4598                      $( this ).height( Math.max( 0, maxHeight -
4599                          $( this ).innerHeight() + $( this ).height() ) );
4600                  })
4601                  .css( "overflow", "auto" );
4602          } else if ( options.autoHeight ) {
4603              maxHeight = 0;
4604              this.headers.next()
4605                  .each(function() {
4606                      maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
4607                  })
4608                  .height( maxHeight );
4609          }
4610  
4611          return this;
4612      },
4613  
4614      activate: function( index ) {
4615          // TODO this gets called on init, changing the option without an explicit call for that
4616          this.options.active = index;
4617          // call clickHandler with custom event
4618          var active = this._findActive( index )[ 0 ];
4619          this._clickHandler( { target: active }, active );
4620  
4621          return this;
4622      },
4623  
4624      _findActive: function( selector ) {
4625          return selector
4626              ? typeof selector === "number"
4627                  ? this.headers.filter( ":eq(" + selector + ")" )
4628                  : this.headers.not( this.headers.not( selector ) )
4629              : selector === false
4630                  ? $( [] )
4631                  : this.headers.filter( ":eq(0)" );
4632      },
4633  
4634      // TODO isn't event.target enough? why the separate target argument?
4635      _clickHandler: function( event, target ) {
4636          var options = this.options;
4637          if ( options.disabled ) {
4638              return;
4639          }
4640  
4641          // called only when using activate(false) to close all parts programmatically
4642          if ( !event.target ) {
4643              if ( !options.collapsible ) {
4644                  return;
4645              }
4646              this.active
4647                  .removeClass( "ui-state-active ui-corner-top" )
4648                  .addClass( "ui-state-default ui-corner-all" )
4649                  .children( ".ui-icon" )
4650                      .removeClass( options.icons.headerSelected )
4651                      .addClass( options.icons.header );
4652              this.active.next().addClass( "ui-accordion-content-active" );
4653              var toHide = this.active.next(),
4654                  data = {
4655                      options: options,
4656                      newHeader: $( [] ),
4657                      oldHeader: options.active,
4658                      newContent: $( [] ),
4659                      oldContent: toHide
4660                  },
4661                  toShow = ( this.active = $( [] ) );
4662              this._toggle( toShow, toHide, data );
4663              return;
4664          }
4665  
4666          // get the click target
4667          var clicked = $( event.currentTarget || target ),
4668              clickedIsActive = clicked[0] === this.active[0];
4669  
4670          // TODO the option is changed, is that correct?
4671          // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4672          options.active = options.collapsible && clickedIsActive ?
4673              false :
4674              this.headers.index( clicked );
4675  
4676          // if animations are still active, or the active header is the target, ignore click
4677          if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
4678              return;
4679          }
4680  
4681          // find elements to show and hide
4682          var active = this.active,
4683              toShow = clicked.next(),
4684              toHide = this.active.next(),
4685              data = {
4686                  options: options,
4687                  newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
4688                  oldHeader: this.active,
4689                  newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
4690                  oldContent: toHide
4691              },
4692              down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
4693  
4694          // when the call to ._toggle() comes after the class changes
4695          // it causes a very odd bug in IE 8 (see #6720)
4696          this.active = clickedIsActive ? $([]) : clicked;
4697          this._toggle( toShow, toHide, data, clickedIsActive, down );
4698  
4699          // switch classes
4700          active
4701              .removeClass( "ui-state-active ui-corner-top" )
4702              .addClass( "ui-state-default ui-corner-all" )
4703              .children( ".ui-icon" )
4704                  .removeClass( options.icons.headerSelected )
4705                  .addClass( options.icons.header );
4706          if ( !clickedIsActive ) {
4707              clicked
4708                  .removeClass( "ui-state-default ui-corner-all" )
4709                  .addClass( "ui-state-active ui-corner-top" )
4710                  .children( ".ui-icon" )
4711                      .removeClass( options.icons.header )
4712                      .addClass( options.icons.headerSelected );
4713              clicked
4714                  .next()
4715                  .addClass( "ui-accordion-content-active" );
4716          }
4717  
4718          return;
4719      },
4720  
4721      _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
4722          var self = this,
4723              options = self.options;
4724  
4725          self.toShow = toShow;
4726          self.toHide = toHide;
4727          self.data = data;
4728  
4729          var complete = function() {
4730              if ( !self ) {
4731                  return;
4732              }
4733              return self._completed.apply( self, arguments );
4734          };
4735  
4736          // trigger changestart event
4737          self._trigger( "changestart", null, self.data );
4738  
4739          // count elements to animate
4740          self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
4741  
4742          if ( options.animated ) {
4743              var animOptions = {};
4744  
4745              if ( options.collapsible && clickedIsActive ) {
4746                  animOptions = {
4747                      toShow: $( [] ),
4748                      toHide: toHide,
4749                      complete: complete,
4750                      down: down,
4751                      autoHeight: options.autoHeight || options.fillSpace
4752                  };
4753              } else {
4754                  animOptions = {
4755                      toShow: toShow,
4756                      toHide: toHide,
4757                      complete: complete,
4758                      down: down,
4759                      autoHeight: options.autoHeight || options.fillSpace
4760                  };
4761              }
4762  
4763              if ( !options.proxied ) {
4764                  options.proxied = options.animated;
4765              }
4766  
4767              if ( !options.proxiedDuration ) {
4768                  options.proxiedDuration = options.duration;
4769              }
4770  
4771              options.animated = $.isFunction( options.proxied ) ?
4772                  options.proxied( animOptions ) :
4773                  options.proxied;
4774  
4775              options.duration = $.isFunction( options.proxiedDuration ) ?
4776                  options.proxiedDuration( animOptions ) :
4777                  options.proxiedDuration;
4778  
4779              var animations = $.ui.accordion.animations,
4780                  duration = options.duration,
4781                  easing = options.animated;
4782  
4783              if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
4784                  easing = "slide";
4785              }
4786              if ( !animations[ easing ] ) {
4787                  animations[ easing ] = function( options ) {
4788                      this.slide( options, {
4789                          easing: easing,
4790                          duration: duration || 700
4791                      });
4792                  };
4793              }
4794  
4795              animations[ easing ]( animOptions );
4796          } else {
4797              if ( options.collapsible && clickedIsActive ) {
4798                  toShow.toggle();
4799              } else {
4800                  toHide.hide();
4801                  toShow.show();
4802              }
4803  
4804              complete( true );
4805          }
4806  
4807          // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4808          toHide.prev()
4809              .attr({
4810                  "aria-expanded": "false",
4811                  "aria-selected": "false",
4812                  tabIndex: -1
4813              })
4814              .blur();
4815          toShow.prev()
4816              .attr({
4817                  "aria-expanded": "true",
4818                  "aria-selected": "true",
4819                  tabIndex: 0
4820              })
4821              .focus();
4822      },
4823  
4824      _completed: function( cancel ) {
4825          this.running = cancel ? 0 : --this.running;
4826          if ( this.running ) {
4827              return;
4828          }
4829  
4830          if ( this.options.clearStyle ) {
4831              this.toShow.add( this.toHide ).css({
4832                  height: "",
4833                  overflow: ""
4834              });
4835          }
4836  
4837          // other classes are removed before the animation; this one needs to stay until completed
4838          this.toHide.removeClass( "ui-accordion-content-active" );
4839          // Work around for rendering bug in IE (#5421)
4840          if ( this.toHide.length ) {
4841              this.toHide.parent()[0].className = this.toHide.parent()[0].className;
4842          }
4843  
4844          this._trigger( "change", null, this.data );
4845      }
4846  });
4847  
4848  $.extend( $.ui.accordion, {
4849      version: "1.8.18",
4850      animations: {
4851          slide: function( options, additions ) {
4852              options = $.extend({
4853                  easing: "swing",
4854                  duration: 300
4855              }, options, additions );
4856              if ( !options.toHide.size() ) {
4857                  options.toShow.animate({
4858                      height: "show",
4859                      paddingTop: "show",
4860                      paddingBottom: "show"
4861                  }, options );
4862                  return;
4863              }
4864              if ( !options.toShow.size() ) {
4865                  options.toHide.animate({
4866                      height: "hide",
4867                      paddingTop: "hide",
4868                      paddingBottom: "hide"
4869                  }, options );
4870                  return;
4871              }
4872              var overflow = options.toShow.css( "overflow" ),
4873                  percentDone = 0,
4874                  showProps = {},
4875                  hideProps = {},
4876                  fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
4877                  originalWidth;
4878              // fix width before calculating height of hidden element
4879              var s = options.toShow;
4880              originalWidth = s[0].style.width;
4881              s.width( s.parent().width()
4882                  - parseFloat( s.css( "paddingLeft" ) )
4883                  - parseFloat( s.css( "paddingRight" ) )
4884                  - ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
4885                  - ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
4886  
4887              $.each( fxAttrs, function( i, prop ) {
4888                  hideProps[ prop ] = "hide";
4889  
4890                  var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
4891                  showProps[ prop ] = {
4892                      value: parts[ 1 ],
4893                      unit: parts[ 2 ] || "px"
4894                  };
4895              });
4896              options.toShow.css({ height: 0, overflow: "hidden" }).show();
4897              options.toHide
4898                  .filter( ":hidden" )
4899                      .each( options.complete )
4900                  .end()
4901                  .filter( ":visible" )
4902                  .animate( hideProps, {
4903                  step: function( now, settings ) {
4904                      // only calculate the percent when animating height
4905                      // IE gets very inconsistent results when animating elements
4906                      // with small values, which is common for padding
4907                      if ( settings.prop == "height" ) {
4908                          percentDone = ( settings.end - settings.start === 0 ) ? 0 :
4909                              ( settings.now - settings.start ) / ( settings.end - settings.start );
4910                      }
4911  
4912                      options.toShow[ 0 ].style[ settings.prop ] =
4913                          ( percentDone * showProps[ settings.prop ].value )
4914                          + showProps[ settings.prop ].unit;
4915                  },
4916                  duration: options.duration,
4917                  easing: options.easing,
4918                  complete: function() {
4919                      if ( !options.autoHeight ) {
4920                          options.toShow.css( "height", "" );
4921                      }
4922                      options.toShow.css({
4923                          width: originalWidth,
4924                          overflow: overflow
4925                      });
4926                      options.complete();
4927                  }
4928              });
4929          },
4930          bounceslide: function( options ) {
4931              this.slide( options, {
4932                  easing: options.down ? "easeOutBounce" : "swing",
4933                  duration: options.down ? 1000 : 200
4934              });
4935          }
4936      }
4937  });
4938  
4939  })( jQuery );
4940  /*
4941   * jQuery UI Autocomplete 1.8.18
4942   *
4943   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4944   * Dual licensed under the MIT or GPL Version 2 licenses.
4945   * http://jquery.org/license
4946   *
4947   * http://docs.jquery.com/UI/Autocomplete
4948   *
4949   * Depends:
4950   *    jquery.ui.core.js
4951   *    jquery.ui.widget.js
4952   *    jquery.ui.position.js
4953   */
4954  (function( $, undefined ) {
4955  
4956  // used to prevent race conditions with remote data sources
4957  var requestIndex = 0;
4958  
4959  $.widget( "ui.autocomplete", {
4960      options: {
4961          appendTo: "body",
4962          autoFocus: false,
4963          delay: 300,
4964          minLength: 1,
4965          position: {
4966              my: "left top",
4967              at: "left bottom",
4968              collision: "none"
4969          },
4970          source: null
4971      },
4972  
4973      pending: 0,
4974  
4975      _create: function() {
4976          var self = this,
4977              doc = this.element[ 0 ].ownerDocument,
4978              suppressKeyPress;
4979  
4980          this.element
4981              .addClass( "ui-autocomplete-input" )
4982              .attr( "autocomplete", "off" )
4983              // TODO verify these actually work as intended
4984              .attr({
4985                  role: "textbox",
4986                  "aria-autocomplete": "list",
4987                  "aria-haspopup": "true"
4988              })
4989              .bind( "keydown.autocomplete", function( event ) {
4990                  if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
4991                      return;
4992                  }
4993  
4994                  suppressKeyPress = false;
4995                  var keyCode = $.ui.keyCode;
4996                  switch( event.keyCode ) {
4997                  case keyCode.PAGE_UP:
4998                      self._move( "previousPage", event );
4999                      break;
5000                  case keyCode.PAGE_DOWN:
5001                      self._move( "nextPage", event );
5002                      break;
5003                  case keyCode.UP:
5004                      self._move( "previous", event );
5005                      // prevent moving cursor to beginning of text field in some browsers
5006                      event.preventDefault();
5007                      break;
5008                  case keyCode.DOWN:
5009                      self._move( "next", event );
5010                      // prevent moving cursor to end of text field in some browsers
5011                      event.preventDefault();
5012                      break;
5013                  case keyCode.ENTER:
5014                  case keyCode.NUMPAD_ENTER:
5015                      // when menu is open and has focus
5016                      if ( self.menu.active ) {
5017                          // #6055 - Opera still allows the keypress to occur
5018                          // which causes forms to submit
5019                          suppressKeyPress = true;
5020                          event.preventDefault();
5021                      }
5022                      //passthrough - ENTER and TAB both select the current element
5023                  case keyCode.TAB:
5024                      if ( !self.menu.active ) {
5025                          return;
5026                      }
5027                      self.menu.select( event );
5028                      break;
5029                  case keyCode.ESCAPE:
5030                      self.element.val( self.term );
5031                      self.close( event );
5032                      break;
5033                  default:
5034                      // keypress is triggered before the input value is changed
5035                      clearTimeout( self.searching );
5036                      self.searching = setTimeout(function() {
5037                          // only search if the value has changed
5038                          if ( self.term != self.element.val() ) {
5039                              self.selectedItem = null;
5040                              self.search( null, event );
5041                          }
5042                      }, self.options.delay );
5043                      break;
5044                  }
5045              })
5046              .bind( "keypress.autocomplete", function( event ) {
5047                  if ( suppressKeyPress ) {
5048                      suppressKeyPress = false;
5049                      event.preventDefault();
5050                  }
5051              })
5052              .bind( "focus.autocomplete", function() {
5053                  if ( self.options.disabled ) {
5054                      return;
5055                  }
5056  
5057                  self.selectedItem = null;
5058                  self.previous = self.element.val();
5059              })
5060              .bind( "blur.autocomplete", function( event ) {
5061                  if ( self.options.disabled ) {
5062                      return;
5063                  }
5064  
5065                  clearTimeout( self.searching );
5066                  // clicks on the menu (or a button to trigger a search) will cause a blur event
5067                  self.closing = setTimeout(function() {
5068                      self.close( event );
5069                      self._change( event );
5070                  }, 150 );
5071              });
5072          this._initSource();
5073          this.response = function() {
5074              return self._response.apply( self, arguments );
5075          };
5076          this.menu = $( "<ul></ul>" )
5077              .addClass( "ui-autocomplete" )
5078              .appendTo( $( this.options.appendTo || "body", doc )[0] )
5079              // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5080              .mousedown(function( event ) {
5081                  // clicking on the scrollbar causes focus to shift to the body
5082                  // but we can't detect a mouseup or a click immediately afterward
5083                  // so we have to track the next mousedown and close the menu if
5084                  // the user clicks somewhere outside of the autocomplete
5085                  var menuElement = self.menu.element[ 0 ];
5086                  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
5087                      setTimeout(function() {
5088                          $( document ).one( 'mousedown', function( event ) {
5089                              if ( event.target !== self.element[ 0 ] &&
5090                                  event.target !== menuElement &&
5091                                  !$.ui.contains( menuElement, event.target ) ) {
5092                                  self.close();
5093                              }
5094                          });
5095                      }, 1 );
5096                  }
5097  
5098                  // use another timeout to make sure the blur-event-handler on the input was already triggered
5099                  setTimeout(function() {
5100                      clearTimeout( self.closing );
5101                  }, 13);
5102              })
5103              .menu({
5104                  focus: function( event, ui ) {
5105                      var item = ui.item.data( "item.autocomplete" );
5106                      if ( false !== self._trigger( "focus", event, { item: item } ) ) {
5107                          // use value to match what will end up in the input, if it was a key event
5108                          if ( /^key/.test(event.originalEvent.type) ) {
5109                              self.element.val( item.value );
5110                          }
5111                      }
5112                  },
5113                  selected: function( event, ui ) {
5114                      var item = ui.item.data( "item.autocomplete" ),
5115                          previous = self.previous;
5116  
5117                      // only trigger when focus was lost (click on menu)
5118                      if ( self.element[0] !== doc.activeElement ) {
5119                          self.element.focus();
5120                          self.previous = previous;
5121                          // #6109 - IE triggers two focus events and the second
5122                          // is asynchronous, so we need to reset the previous
5123                          // term synchronously and asynchronously :-(
5124                          setTimeout(function() {
5125                              self.previous = previous;
5126                              self.selectedItem = item;
5127                          }, 1);
5128                      }
5129  
5130                      if ( false !== self._trigger( "select", event, { item: item } ) ) {
5131                          self.element.val( item.value );
5132                      }
5133                      // reset the term after the select event
5134                      // this allows custom select handling to work properly
5135                      self.term = self.element.val();
5136  
5137                      self.close( event );
5138                      self.selectedItem = item;
5139                  },
5140                  blur: function( event, ui ) {
5141                      // don't set the value of the text field if it's already correct
5142                      // this prevents moving the cursor unnecessarily
5143                      if ( self.menu.element.is(":visible") &&
5144                          ( self.element.val() !== self.term ) ) {
5145                          self.element.val( self.term );
5146                      }
5147                  }
5148              })
5149              .zIndex( this.element.zIndex() + 1 )
5150              // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5151              .css({ top: 0, left: 0 })
5152              .hide()
5153              .data( "menu" );
5154          if ( $.fn.bgiframe ) {
5155               this.menu.element.bgiframe();
5156          }
5157          // turning off autocomplete prevents the browser from remembering the
5158          // value when navigating through history, so we re-enable autocomplete
5159          // if the page is unloaded before the widget is destroyed. #7790
5160          self.beforeunloadHandler = function() {
5161              self.element.removeAttr( "autocomplete" );
5162          };
5163          $( window ).bind( "beforeunload", self.beforeunloadHandler );
5164      },
5165  
5166      destroy: function() {
5167          this.element
5168              .removeClass( "ui-autocomplete-input" )
5169              .removeAttr( "autocomplete" )
5170              .removeAttr( "role" )
5171              .removeAttr( "aria-autocomplete" )
5172              .removeAttr( "aria-haspopup" );
5173          this.menu.element.remove();
5174          $( window ).unbind( "beforeunload", this.beforeunloadHandler );
5175          $.Widget.prototype.destroy.call( this );
5176      },
5177  
5178      _setOption: function( key, value ) {
5179          $.Widget.prototype._setOption.apply( this, arguments );
5180          if ( key === "source" ) {
5181              this._initSource();
5182          }
5183          if ( key === "appendTo" ) {
5184              this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
5185          }
5186          if ( key === "disabled" && value && this.xhr ) {
5187              this.xhr.abort();
5188          }
5189      },
5190  
5191      _initSource: function() {
5192          var self = this,
5193              array,
5194              url;
5195          if ( $.isArray(this.options.source) ) {
5196              array = this.options.source;
5197              this.source = function( request, response ) {
5198                  response( $.ui.autocomplete.filter(array, request.term) );
5199              };
5200          } else if ( typeof this.options.source === "string" ) {
5201              url = this.options.source;
5202              this.source = function( request, response ) {
5203                  if ( self.xhr ) {
5204                      self.xhr.abort();
5205                  }
5206                  self.xhr = $.ajax({
5207                      url: url,
5208                      data: request,
5209                      dataType: "json",
5210                      context: {
5211                          autocompleteRequest: ++requestIndex
5212                      },
5213                      success: function( data, status ) {
5214                          if ( this.autocompleteRequest === requestIndex ) {
5215                              response( data );
5216                          }
5217                      },
5218                      error: function() {
5219                          if ( this.autocompleteRequest === requestIndex ) {
5220                              response( [] );
5221                          }
5222                      }
5223                  });
5224              };
5225          } else {
5226              this.source = this.options.source;
5227          }
5228      },
5229  
5230      search: function( value, event ) {
5231          value = value != null ? value : this.element.val();
5232  
5233          // always save the actual value, not the one passed as an argument
5234          this.term = this.element.val();
5235  
5236          if ( value.length < this.options.minLength ) {
5237              return this.close( event );
5238          }
5239  
5240          clearTimeout( this.closing );
5241          if ( this._trigger( "search", event ) === false ) {
5242              return;
5243          }
5244  
5245          return this._search( value );
5246      },
5247  
5248      _search: function( value ) {
5249          this.pending++;
5250          this.element.addClass( "ui-autocomplete-loading" );
5251  
5252          this.source( { term: value }, this.response );
5253      },
5254  
5255      _response: function( content ) {
5256          if ( !this.options.disabled && content && content.length ) {
5257              content = this._normalize( content );
5258              this._suggest( content );
5259              this._trigger( "open" );
5260          } else {
5261              this.close();
5262          }
5263          this.pending--;
5264          if ( !this.pending ) {
5265              this.element.removeClass( "ui-autocomplete-loading" );
5266          }
5267      },
5268  
5269      close: function( event ) {
5270          clearTimeout( this.closing );
5271          if ( this.menu.element.is(":visible") ) {
5272              this.menu.element.hide();
5273              this.menu.deactivate();
5274              this._trigger( "close", event );
5275          }
5276      },
5277      
5278      _change: function( event ) {
5279          if ( this.previous !== this.element.val() ) {
5280              this._trigger( "change", event, { item: this.selectedItem } );
5281          }
5282      },
5283  
5284      _normalize: function( items ) {
5285          // assume all items have the right format when the first item is complete
5286          if ( items.length && items[0].label && items[0].value ) {
5287              return items;
5288          }
5289          return $.map( items, function(item) {
5290              if ( typeof item === "string" ) {
5291                  return {
5292                      label: item,
5293                      value: item
5294                  };
5295              }
5296              return $.extend({
5297                  label: item.label || item.value,
5298                  value: item.value || item.label
5299              }, item );
5300          });
5301      },
5302  
5303      _suggest: function( items ) {
5304          var ul = this.menu.element
5305              .empty()
5306              .zIndex( this.element.zIndex() + 1 );
5307          this._renderMenu( ul, items );
5308          // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5309          this.menu.deactivate();
5310          this.menu.refresh();
5311  
5312          // size and position menu
5313          ul.show();
5314          this._resizeMenu();
5315          ul.position( $.extend({
5316              of: this.element
5317          }, this.options.position ));
5318  
5319          if ( this.options.autoFocus ) {
5320              this.menu.next( new $.Event("mouseover") );
5321          }
5322      },
5323  
5324      _resizeMenu: function() {
5325          var ul = this.menu.element;
5326          ul.outerWidth( Math.max(
5327              // Firefox wraps long text (possibly a rounding bug)
5328              // so we add 1px to avoid the wrapping (#7513)
5329              ul.width( "" ).outerWidth() + 1,
5330              this.element.outerWidth()
5331          ) );
5332      },
5333  
5334      _renderMenu: function( ul, items ) {
5335          var self = this;
5336          $.each( items, function( index, item ) {
5337              self._renderItem( ul, item );
5338          });
5339      },
5340  
5341      _renderItem: function( ul, item) {
5342          return $( "<li></li>" )
5343              .data( "item.autocomplete", item )
5344              .append( $( "<a></a>" ).text( item.label ) )
5345              .appendTo( ul );
5346      },
5347  
5348      _move: function( direction, event ) {
5349          if ( !this.menu.element.is(":visible") ) {
5350              this.search( null, event );
5351              return;
5352          }
5353          if ( this.menu.first() && /^previous/.test(direction) ||
5354                  this.menu.last() && /^next/.test(direction) ) {
5355              this.element.val( this.term );
5356              this.menu.deactivate();
5357              return;
5358          }
5359          this.menu[ direction ]( event );
5360      },
5361  
5362      widget: function() {
5363          return this.menu.element;
5364      }
5365  });
5366  
5367  $.extend( $.ui.autocomplete, {
5368      escapeRegex: function( value ) {
5369          return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5370      },
5371      filter: function(array, term) {
5372          var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
5373          return $.grep( array, function(value) {
5374              return matcher.test( value.label || value.value || value );
5375          });
5376      }
5377  });
5378  
5379  }( jQuery ));
5380  
5381  /*
5382   * jQuery UI Menu (not officially released)
5383   * 
5384   * This widget isn't yet finished and the API is subject to change. We plan to finish
5385   * it for the next release. You're welcome to give it a try anyway and give us feedback,
5386   * as long as you're okay with migrating your code later on. We can help with that, too.
5387   *
5388   * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5389   * Dual licensed under the MIT or GPL Version 2 licenses.
5390   * http://jquery.org/license
5391   *
5392   * http://docs.jquery.com/UI/Menu
5393   *
5394   * Depends:
5395   *    jquery.ui.core.js
5396   *  jquery.ui.widget.js
5397   */
5398  (function($) {
5399  
5400  $.widget("ui.menu", {
5401      _create: function() {
5402          var self = this;
5403          this.element
5404              .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5405              .attr({
5406                  role: "listbox",
5407                  "aria-activedescendant": "ui-active-menuitem"
5408              })
5409              .click(function( event ) {
5410                  if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
5411                      return;
5412                  }
5413                  // temporary
5414                  event.preventDefault();
5415                  self.select( event );
5416              });
5417          this.refresh();
5418      },
5419      
5420      refresh: function() {
5421          var self = this;
5422  
5423          // don't refresh list items that are already adapted
5424          var items = this.element.children("li:not(.ui-menu-item):has(a)")
5425              .addClass("ui-menu-item")
5426              .attr("role", "menuitem");
5427          
5428          items.children("a")
5429              .addClass("ui-corner-all")
5430              .attr("tabindex", -1)
5431              // mouseenter doesn't work with event delegation
5432              .mouseenter(function( event ) {
5433                  self.activate( event, $(this).parent() );
5434              })
5435              .mouseleave(function() {
5436                  self.deactivate();
5437              });
5438      },
5439  
5440      activate: function( event, item ) {
5441          this.deactivate();
5442          if (this.hasScroll()) {
5443              var offset = item.offset().top - this.element.offset().top,
5444                  scroll = this.element.scrollTop(),
5445                  elementHeight = this.element.height();
5446              if (offset < 0) {
5447                  this.element.scrollTop( scroll + offset);
5448              } else if (offset >= elementHeight) {
5449                  this.element.scrollTop( scroll + offset - elementHeight + item.height());
5450              }
5451          }
5452          this.active = item.eq(0)
5453              .children("a")
5454                  .addClass("ui-state-hover")
5455                  .attr("id", "ui-active-menuitem")
5456              .end();
5457          this._trigger("focus", event, { item: item });
5458      },
5459  
5460      deactivate: function() {
5461          if (!this.active) { return; }
5462  
5463          this.active.children("a")
5464              .removeClass("ui-state-hover")
5465              .removeAttr("id");
5466          this._trigger("blur");
5467          this.active = null;
5468      },
5469  
5470      next: function(event) {
5471          this.move("next", ".ui-menu-item:first", event);
5472      },
5473  
5474      previous: function(event) {
5475          this.move("prev", ".ui-menu-item:last", event);
5476      },
5477  
5478      first: function() {
5479          return this.active && !this.active.prevAll(".ui-menu-item").length;
5480      },
5481  
5482      last: function() {
5483          return this.active && !this.active.nextAll(".ui-menu-item").length;
5484      },
5485  
5486      move: function(direction, edge, event) {
5487          if (!this.active) {
5488              this.activate(event, this.element.children(edge));
5489              return;
5490          }
5491          var next = this.active[direction + "All"](".ui-menu-item").eq(0);
5492          if (next.length) {
5493              this.activate(event, next);
5494          } else {
5495              this.activate(event, this.element.children(edge));
5496          }
5497      },
5498  
5499      // TODO merge with previousPage
5500      nextPage: function(event) {
5501          if (this.hasScroll()) {
5502              // TODO merge with no-scroll-else
5503              if (!this.active || this.last()) {
5504                  this.activate(event, this.element.children(".ui-menu-item:first"));
5505                  return;
5506              }
5507              var base = this.active.offset().top,
5508                  height = this.element.height(),
5509                  result = this.element.children(".ui-menu-item").filter(function() {
5510                      var close = $(this).offset().top - base - height + $(this).height();
5511                      // TODO improve approximation
5512                      return close < 10 && close > -10;
5513                  });
5514  
5515              // TODO try to catch this earlier when scrollTop indicates the last page anyway
5516              if (!result.length) {
5517                  result = this.element.children(".ui-menu-item:last");
5518              }
5519              this.activate(event, result);
5520          } else {
5521              this.activate(event, this.element.children(".ui-menu-item")
5522                  .filter(!this.active || this.last() ? ":first" : ":last"));
5523          }
5524      },
5525  
5526      // TODO merge with nextPage
5527      previousPage: function(event) {
5528          if (this.hasScroll()) {
5529              // TODO merge with no-scroll-else
5530              if (!this.active || this.first()) {
5531                  this.activate(event, this.element.children(".ui-menu-item:last"));
5532                  return;
5533              }
5534  
5535              var base = this.active.offset().top,
5536                  height = this.element.height();
5537                  result = this.element.children(".ui-menu-item").filter(function() {
5538                      var close = $(this).offset().top - base + height - $(this).height();
5539                      // TODO improve approximation
5540                      return close < 10 && close > -10;
5541                  });
5542  
5543              // TODO try to catch this earlier when scrollTop indicates the last page anyway
5544              if (!result.length) {
5545                  result = this.element.children(".ui-menu-item:first");
5546              }
5547              this.activate(event, result);
5548          } else {
5549              this.activate(event, this.element.children(".ui-menu-item")
5550                  .filter(!this.active || this.first() ? ":last" : ":first"));
5551          }
5552      },
5553  
5554      hasScroll: function() {
5555          return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
5556      },
5557  
5558      select: function( event ) {
5559          this._trigger("selected", event, { item: this.active });
5560      }
5561  });
5562  
5563  }(jQuery));
5564  /*
5565   * jQuery UI Button 1.8.18
5566   *
5567   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5568   * Dual licensed under the MIT or GPL Version 2 licenses.
5569   * http://jquery.org/license
5570   *
5571   * http://docs.jquery.com/UI/Button
5572   *
5573   * Depends:
5574   *    jquery.ui.core.js
5575   *    jquery.ui.widget.js
5576   */
5577  (function( $, undefined ) {
5578  
5579  var lastActive, startXPos, startYPos, clickDragged,
5580      baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
5581      stateClasses = "ui-state-hover ui-state-active ",
5582      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",
5583      formResetHandler = function() {
5584          var buttons = $( this ).find( ":ui-button" );
5585          setTimeout(function() {
5586              buttons.button( "refresh" );
5587          }, 1 );
5588      },
5589      radioGroup = function( radio ) {
5590          var name = radio.name,
5591              form = radio.form,
5592              radios = $( [] );
5593          if ( name ) {
5594              if ( form ) {
5595                  radios = $( form ).find( "[name='" + name + "']" );
5596              } else {
5597                  radios = $( "[name='" + name + "']", radio.ownerDocument )
5598                      .filter(function() {
5599                          return !this.form;
5600                      });
5601              }
5602          }
5603          return radios;
5604      };
5605  
5606  $.widget( "ui.button", {
5607      options: {
5608          disabled: null,
5609          text: true,
5610          label: null,
5611          icons: {
5612              primary: null,
5613              secondary: null
5614          }
5615      },
5616      _create: function() {
5617          this.element.closest( "form" )
5618              .unbind( "reset.button" )
5619              .bind( "reset.button", formResetHandler );
5620  
5621          if ( typeof this.options.disabled !== "boolean" ) {
5622              this.options.disabled = !!this.element.propAttr( "disabled" );
5623          } else {
5624              this.element.propAttr( "disabled", this.options.disabled );
5625          }
5626  
5627          this._determineButtonType();
5628          this.hasTitle = !!this.buttonElement.attr( "title" );
5629  
5630          var self = this,
5631              options = this.options,
5632              toggleButton = this.type === "checkbox" || this.type === "radio",
5633              hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
5634              focusClass = "ui-state-focus";
5635  
5636          if ( options.label === null ) {
5637              options.label = this.buttonElement.html();
5638          }
5639  
5640          this.buttonElement
5641              .addClass( baseClasses )
5642              .attr( "role", "button" )
5643              .bind( "mouseenter.button", function() {
5644                  if ( options.disabled ) {
5645                      return;
5646                  }
5647                  $( this ).addClass( "ui-state-hover" );
5648                  if ( this === lastActive ) {
5649                      $( this ).addClass( "ui-state-active" );
5650                  }
5651              })
5652              .bind( "mouseleave.button", function() {
5653                  if ( options.disabled ) {
5654                      return;
5655                  }
5656                  $( this ).removeClass( hoverClass );
5657              })
5658              .bind( "click.button", function( event ) {
5659                  if ( options.disabled ) {
5660                      event.preventDefault();
5661                      event.stopImmediatePropagation();
5662                  }
5663              });
5664  
5665          this.element
5666              .bind( "focus.button", function() {
5667                  // no need to check disabled, focus won't be triggered anyway
5668                  self.buttonElement.addClass( focusClass );
5669              })
5670              .bind( "blur.button", function() {
5671                  self.buttonElement.removeClass( focusClass );
5672              });
5673  
5674          if ( toggleButton ) {
5675              this.element.bind( "change.button", function() {
5676                  if ( clickDragged ) {
5677                      return;
5678                  }
5679                  self.refresh();
5680              });
5681              // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5682              // prevents issue where button state changes but checkbox/radio checked state
5683              // does not in Firefox (see ticket #6970)
5684              this.buttonElement
5685                  .bind( "mousedown.button", function( event ) {
5686                      if ( options.disabled ) {
5687                          return;
5688                      }
5689                      clickDragged = false;
5690                      startXPos = event.pageX;
5691                      startYPos = event.pageY;
5692                  })
5693                  .bind( "mouseup.button", function( event ) {
5694                      if ( options.disabled ) {
5695                          return;
5696                      }
5697                      if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
5698                          clickDragged = true;
5699                      }
5700              });
5701          }
5702  
5703          if ( this.type === "checkbox" ) {
5704              this.buttonElement.bind( "click.button", function() {
5705                  if ( options.disabled || clickDragged ) {
5706                      return false;
5707                  }
5708                  $( this ).toggleClass( "ui-state-active" );
5709                  self.buttonElement.attr( "aria-pressed", self.element[0].checked );
5710              });
5711          } else if ( this.type === "radio" ) {
5712              this.buttonElement.bind( "click.button", function() {
5713                  if ( options.disabled || clickDragged ) {
5714                      return false;
5715                  }
5716                  $( this ).addClass( "ui-state-active" );
5717                  self.buttonElement.attr( "aria-pressed", "true" );
5718  
5719                  var radio = self.element[ 0 ];
5720                  radioGroup( radio )
5721                      .not( radio )
5722                      .map(function() {
5723                          return $( this ).button( "widget" )[ 0 ];
5724                      })
5725                      .removeClass( "ui-state-active" )
5726                      .attr( "aria-pressed", "false" );
5727              });
5728          } else {
5729              this.buttonElement
5730                  .bind( "mousedown.button", function() {
5731                      if ( options.disabled ) {
5732                          return false;
5733                      }
5734                      $( this ).addClass( "ui-state-active" );
5735                      lastActive = this;
5736                      $( document ).one( "mouseup", function() {
5737                          lastActive = null;
5738                      });
5739                  })
5740                  .bind( "mouseup.button", function() {
5741                      if ( options.disabled ) {
5742                          return false;
5743                      }
5744                      $( this ).removeClass( "ui-state-active" );
5745                  })
5746                  .bind( "keydown.button", function(event) {
5747                      if ( options.disabled ) {
5748                          return false;
5749                      }
5750                      if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
5751                          $( this ).addClass( "ui-state-active" );
5752                      }
5753                  })
5754                  .bind( "keyup.button", function() {
5755                      $( this ).removeClass( "ui-state-active" );
5756                  });
5757  
5758              if ( this.buttonElement.is("a") ) {
5759                  this.buttonElement.keyup(function(event) {
5760                      if ( event.keyCode === $.ui.keyCode.SPACE ) {
5761                          // TODO pass through original event correctly (just as 2nd argument doesn't work)
5762                          $( this ).click();
5763                      }
5764                  });
5765              }
5766          }
5767  
5768          // TODO: pull out $.Widget's handling for the disabled option into
5769          // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5770          // be overridden by individual plugins
5771          this._setOption( "disabled", options.disabled );
5772          this._resetButton();
5773      },
5774  
5775      _determineButtonType: function() {
5776  
5777          if ( this.element.is(":checkbox") ) {
5778              this.type = "checkbox";
5779          } else if ( this.element.is(":radio") ) {
5780              this.type = "radio";
5781          } else if ( this.element.is("input") ) {
5782              this.type = "input";
5783          } else {
5784              this.type = "button";
5785          }
5786  
5787          if ( this.type === "checkbox" || this.type === "radio" ) {
5788              // we don't search against the document in case the element
5789              // is disconnected from the DOM
5790              var ancestor = this.element.parents().filter(":last"),
5791                  labelSelector = "label[for='" + this.element.attr("id") + "']";
5792              this.buttonElement = ancestor.find( labelSelector );
5793              if ( !this.buttonElement.length ) {
5794                  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
5795                  this.buttonElement = ancestor.filter( labelSelector );
5796                  if ( !this.buttonElement.length ) {
5797                      this.buttonElement = ancestor.find( labelSelector );
5798                  }
5799              }
5800              this.element.addClass( "ui-helper-hidden-accessible" );
5801  
5802              var checked = this.element.is( ":checked" );
5803              if ( checked ) {
5804                  this.buttonElement.addClass( "ui-state-active" );
5805              }
5806              this.buttonElement.attr( "aria-pressed", checked );
5807          } else {
5808              this.buttonElement = this.element;
5809          }
5810      },
5811  
5812      widget: function() {
5813          return this.buttonElement;
5814      },
5815  
5816      destroy: function() {
5817          this.element
5818              .removeClass( "ui-helper-hidden-accessible" );
5819          this.buttonElement
5820              .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
5821              .removeAttr( "role" )
5822              .removeAttr( "aria-pressed" )
5823              .html( this.buttonElement.find(".ui-button-text").html() );
5824  
5825          if ( !this.hasTitle ) {
5826              this.buttonElement.removeAttr( "title" );
5827          }
5828  
5829          $.Widget.prototype.destroy.call( this );
5830      },
5831  
5832      _setOption: function( key, value ) {
5833          $.Widget.prototype._setOption.apply( this, arguments );
5834          if ( key === "disabled" ) {
5835              if ( value ) {
5836                  this.element.propAttr( "disabled", true );
5837              } else {
5838                  this.element.propAttr( "disabled", false );
5839              }
5840              return;
5841          }
5842          this._resetButton();
5843      },
5844  
5845      refresh: function() {
5846          var isDisabled = this.element.is( ":disabled" );
5847          if ( isDisabled !== this.options.disabled ) {
5848              this._setOption( "disabled", isDisabled );
5849          }
5850          if ( this.type === "radio" ) {
5851              radioGroup( this.element[0] ).each(function() {
5852                  if ( $( this ).is( ":checked" ) ) {
5853                      $( this ).button( "widget" )
5854                          .addClass( "ui-state-active" )
5855                          .attr( "aria-pressed", "true" );
5856                  } else {
5857                      $( this ).button( "widget" )
5858                          .removeClass( "ui-state-active" )
5859                          .attr( "aria-pressed", "false" );
5860                  }
5861              });
5862          } else if ( this.type === "checkbox" ) {
5863              if ( this.element.is( ":checked" ) ) {
5864                  this.buttonElement
5865                      .addClass( "ui-state-active" )
5866                      .attr( "aria-pressed", "true" );
5867              } else {
5868                  this.buttonElement
5869                      .removeClass( "ui-state-active" )
5870                      .attr( "aria-pressed", "false" );
5871              }
5872          }
5873      },
5874  
5875      _resetButton: function() {
5876          if ( this.type === "input" ) {
5877              if ( this.options.label ) {
5878                  this.element.val( this.options.label );
5879              }
5880              return;
5881          }
5882          var buttonElement = this.buttonElement.removeClass( typeClasses ),
5883              buttonText = $( "<span></span>", this.element[0].ownerDocument )
5884                  .addClass( "ui-button-text" )
5885                  .html( this.options.label )
5886                  .appendTo( buttonElement.empty() )
5887                  .text(),
5888              icons = this.options.icons,
5889              multipleIcons = icons.primary && icons.secondary,
5890              buttonClasses = [];  
5891  
5892          if ( icons.primary || icons.secondary ) {
5893              if ( this.options.text ) {
5894                  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
5895              }
5896  
5897              if ( icons.primary ) {
5898                  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
5899              }
5900  
5901              if ( icons.secondary ) {
5902                  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
5903              }
5904  
5905              if ( !this.options.text ) {
5906                  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
5907  
5908                  if ( !this.hasTitle ) {
5909                      buttonElement.attr( "title", buttonText );
5910                  }
5911              }
5912          } else {
5913              buttonClasses.push( "ui-button-text-only" );
5914          }
5915          buttonElement.addClass( buttonClasses.join( " " ) );
5916      }
5917  });
5918  
5919  $.widget( "ui.buttonset", {
5920      options: {
5921          items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5922      },
5923  
5924      _create: function() {
5925          this.element.addClass( "ui-buttonset" );
5926      },
5927      
5928      _init: function() {
5929          this.refresh();
5930      },
5931  
5932      _setOption: function( key, value ) {
5933          if ( key === "disabled" ) {
5934              this.buttons.button( "option", key, value );
5935          }
5936  
5937          $.Widget.prototype._setOption.apply( this, arguments );
5938      },
5939      
5940      refresh: function() {
5941          var rtl = this.element.css( "direction" ) === "rtl";
5942          
5943          this.buttons = this.element.find( this.options.items )
5944              .filter( ":ui-button" )
5945                  .button( "refresh" )
5946              .end()
5947              .not( ":ui-button" )
5948                  .button()
5949              .end()
5950              .map(function() {
5951                  return $( this ).button( "widget" )[ 0 ];
5952              })
5953                  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5954                  .filter( ":first" )
5955                      .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
5956                  .end()
5957                  .filter( ":last" )
5958                      .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
5959                  .end()
5960              .end();
5961      },
5962  
5963      destroy: function() {
5964          this.element.removeClass( "ui-buttonset" );
5965          this.buttons
5966              .map(function() {
5967                  return $( this ).button( "widget" )[ 0 ];
5968              })
5969                  .removeClass( "ui-corner-left ui-corner-right" )
5970              .end()
5971              .button( "destroy" );
5972  
5973          $.Widget.prototype.destroy.call( this );
5974      }
5975  });
5976  
5977  }( jQuery ) );
5978  /*
5979   * jQuery UI Dialog 1.8.18
5980   *
5981   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5982   * Dual licensed under the MIT or GPL Version 2 licenses.
5983   * http://jquery.org/license
5984   *
5985   * http://docs.jquery.com/UI/Dialog
5986   *
5987   * Depends:
5988   *    jquery.ui.core.js
5989   *    jquery.ui.widget.js
5990   *  jquery.ui.button.js
5991   *    jquery.ui.draggable.js
5992   *    jquery.ui.mouse.js
5993   *    jquery.ui.position.js
5994   *    jquery.ui.resizable.js
5995   */
5996  (function( $, undefined ) {
5997  
5998  var uiDialogClasses =
5999          'ui-dialog ' +
6000          'ui-widget ' +
6001          'ui-widget-content ' +
6002          'ui-corner-all ',
6003      sizeRelatedOptions = {
6004          buttons: true,
6005          height: true,
6006          maxHeight: true,
6007          maxWidth: true,
6008          minHeight: true,
6009          minWidth: true,
6010          width: true
6011      },
6012      resizableRelatedOptions = {
6013          maxHeight: true,
6014          maxWidth: true,
6015          minHeight: true,
6016          minWidth: true
6017      },
6018      // support for jQuery 1.3.2 - handle common attrFn methods for dialog
6019      attrFn = $.attrFn || {
6020          val: true,
6021          css: true,
6022          html: true,
6023          text: true,
6024          data: true,
6025          width: true,
6026          height: true,
6027          offset: true,
6028          click: true
6029      };
6030  
6031  $.widget("ui.dialog", {
6032      options: {
6033          autoOpen: true,
6034          buttons: {},
6035          closeOnEscape: true,
6036          closeText: 'close',
6037          dialogClass: '',
6038          draggable: true,
6039          hide: null,
6040          height: 'auto',
6041          maxHeight: false,
6042          maxWidth: false,
6043          minHeight: 150,
6044          minWidth: 150,
6045          modal: false,
6046          position: {
6047              my: 'center',
6048              at: 'center',
6049              collision: 'fit',
6050              // ensure that the titlebar is never outside the document
6051              using: function(pos) {
6052                  var topOffset = $(this).css(pos).offset().top;
6053                  if (topOffset < 0) {
6054                      $(this).css('top', pos.top - topOffset);
6055                  }
6056              }
6057          },
6058          resizable: true,
6059          show: null,
6060          stack: true,
6061          title: '',
6062          width: 300,
6063          zIndex: 1000
6064      },
6065  
6066      _create: function() {
6067          this.originalTitle = this.element.attr('title');
6068          // #5742 - .attr() might return a DOMElement
6069          if ( typeof this.originalTitle !== "string" ) {
6070              this.originalTitle = "";
6071          }
6072  
6073          this.options.title = this.options.title || this.originalTitle;
6074          var self = this,
6075              options = self.options,
6076  
6077              title = options.title || '&#160;',
6078              titleId = $.ui.dialog.getTitleId(self.element),
6079  
6080              uiDialog = (self.uiDialog = $('<div></div>'))
6081                  .appendTo(document.body)
6082                  .hide()
6083                  .addClass(uiDialogClasses + options.dialogClass)
6084                  .css({
6085                      zIndex: options.zIndex
6086                  })
6087                  // setting tabIndex makes the div focusable
6088                  // setting outline to 0 prevents a border on focus in Mozilla
6089                  .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
6090                      if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6091                          event.keyCode === $.ui.keyCode.ESCAPE) {
6092                          
6093                          self.close(event);
6094                          event.preventDefault();
6095                      }
6096                  })
6097                  .attr({
6098                      role: 'dialog',
6099                      'aria-labelledby': titleId
6100                  })
6101                  .mousedown(function(event) {
6102                      self.moveToTop(false, event);
6103                  }),
6104  
6105              uiDialogContent = self.element
6106                  .show()
6107                  .removeAttr('title')
6108                  .addClass(
6109                      'ui-dialog-content ' +
6110                      'ui-widget-content')
6111                  .appendTo(uiDialog),
6112  
6113              uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
6114                  .addClass(
6115                      'ui-dialog-titlebar ' +
6116                      'ui-widget-header ' +
6117                      'ui-corner-all ' +
6118                      'ui-helper-clearfix'
6119                  )
6120                  .prependTo(uiDialog),
6121  
6122              uiDialogTitlebarClose = $('<a href="#"></a>')
6123                  .addClass(
6124                      'ui-dialog-titlebar-close ' +
6125                      'ui-corner-all'
6126                  )
6127                  .attr('role', 'button')
6128                  .hover(
6129                      function() {
6130                          uiDialogTitlebarClose.addClass('ui-state-hover');
6131                      },
6132                      function() {
6133                          uiDialogTitlebarClose.removeClass('ui-state-hover');
6134                      }
6135                  )
6136                  .focus(function() {
6137                      uiDialogTitlebarClose.addClass('ui-state-focus');
6138                  })
6139                  .blur(function() {
6140                      uiDialogTitlebarClose.removeClass('ui-state-focus');
6141                  })
6142                  .click(function(event) {
6143                      self.close(event);
6144                      return false;
6145                  })
6146                  .appendTo(uiDialogTitlebar),
6147  
6148              uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
6149                  .addClass(
6150                      'ui-icon ' +
6151                      'ui-icon-closethick'
6152                  )
6153                  .text(options.closeText)
6154                  .appendTo(uiDialogTitlebarClose),
6155  
6156              uiDialogTitle = $('<span></span>')
6157                  .addClass('ui-dialog-title')
6158                  .attr('id', titleId)
6159                  .html(title)
6160                  .prependTo(uiDialogTitlebar);
6161  
6162          //handling of deprecated beforeclose (vs beforeClose) option
6163          //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6164          //TODO: remove in 1.9pre
6165          if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
6166              options.beforeClose = options.beforeclose;
6167          }
6168  
6169          uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
6170  
6171          if (options.draggable && $.fn.draggable) {
6172              self._makeDraggable();
6173          }
6174          if (options.resizable && $.fn.resizable) {
6175              self._makeResizable();
6176          }
6177  
6178          self._createButtons(options.buttons);
6179          self._isOpen = false;
6180  
6181          if ($.fn.bgiframe) {
6182              uiDialog.bgiframe();
6183          }
6184      },
6185  
6186      _init: function() {
6187          if ( this.options.autoOpen ) {
6188              this.open();
6189          }
6190      },
6191  
6192      destroy: function() {
6193          var self = this;
6194          
6195          if (self.overlay) {
6196              self.overlay.destroy();
6197          }
6198          self.uiDialog.hide();
6199          self.element
6200              .unbind('.dialog')
6201              .removeData('dialog')
6202              .removeClass('ui-dialog-content ui-widget-content')
6203              .hide().appendTo('body');
6204          self.uiDialog.remove();
6205  
6206          if (self.originalTitle) {
6207              self.element.attr('title', self.originalTitle);
6208          }
6209  
6210          return self;
6211      },
6212  
6213      widget: function() {
6214          return this.uiDialog;
6215      },
6216  
6217      close: function(event) {
6218          var self = this,
6219              maxZ, thisZ;
6220          
6221          if (false === self._trigger('beforeClose', event)) {
6222              return;
6223          }
6224  
6225          if (self.overlay) {
6226              self.overlay.destroy();
6227          }
6228          self.uiDialog.unbind('keypress.ui-dialog');
6229  
6230          self._isOpen = false;
6231  
6232          if (self.options.hide) {
6233              self.uiDialog.hide(self.options.hide, function() {
6234                  self._trigger('close', event);
6235              });
6236          } else {
6237              self.uiDialog.hide();
6238              self._trigger('close', event);
6239          }
6240  
6241          $.ui.dialog.overlay.resize();
6242  
6243          // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6244          if (self.options.modal) {
6245              maxZ = 0;
6246              $('.ui-dialog').each(function() {
6247                  if (this !== self.uiDialog[0]) {
6248                      thisZ = $(this).css('z-index');
6249                      if(!isNaN(thisZ)) {
6250                          maxZ = Math.max(maxZ, thisZ);
6251                      }
6252                  }
6253              });
6254              $.ui.dialog.maxZ = maxZ;
6255          }
6256  
6257          return self;
6258      },
6259  
6260      isOpen: function() {
6261          return this._isOpen;
6262      },
6263  
6264      // the force parameter allows us to move modal dialogs to their correct
6265      // position on open
6266      moveToTop: function(force, event) {
6267          var self = this,
6268              options = self.options,
6269              saveScroll;
6270  
6271          if ((options.modal && !force) ||
6272              (!options.stack && !options.modal)) {
6273              return self._trigger('focus', event);
6274          }
6275  
6276          if (options.zIndex > $.ui.dialog.maxZ) {
6277              $.ui.dialog.maxZ = options.zIndex;
6278          }
6279          if (self.overlay) {
6280              $.ui.dialog.maxZ += 1;
6281              self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
6282          }
6283  
6284          //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6285          //  http://ui.jquery.com/bugs/ticket/3193
6286          saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
6287          $.ui.dialog.maxZ += 1;
6288          self.uiDialog.css('z-index', $.ui.dialog.maxZ);
6289          self.element.attr(saveScroll);
6290          self._trigger('focus', event);
6291  
6292          return self;
6293      },
6294  
6295      open: function() {
6296          if (this._isOpen) { return; }
6297  
6298          var self = this,
6299              options = self.options,
6300              uiDialog = self.uiDialog;
6301  
6302          self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
6303          self._size();
6304          self._position(options.position);
6305          uiDialog.show(options.show);
6306          self.moveToTop(true);
6307  
6308          // prevent tabbing out of modal dialogs
6309          if ( options.modal ) {
6310              uiDialog.bind( "keydown.ui-dialog", function( event ) {
6311                  if ( event.keyCode !== $.ui.keyCode.TAB ) {
6312                      return;
6313                  }
6314  
6315                  var tabbables = $(':tabbable', this),
6316                      first = tabbables.filter(':first'),
6317                      last  = tabbables.filter(':last');
6318  
6319                  if (event.target === last[0] && !event.shiftKey) {
6320                      first.focus(1);
6321                      return false;
6322                  } else if (event.target === first[0] && event.shiftKey) {
6323                      last.focus(1);
6324                      return false;
6325                  }
6326              });
6327          }
6328  
6329          // set focus to the first tabbable element in the content area or the first button
6330          // if there are no tabbable elements, set focus on the dialog itself
6331          $(self.element.find(':tabbable').get().concat(
6332              uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
6333                  uiDialog.get()))).eq(0).focus();
6334  
6335          self._isOpen = true;
6336          self._trigger('open');
6337  
6338          return self;
6339      },
6340  
6341      _createButtons: function(buttons) {
6342          var self = this,
6343              hasButtons = false,
6344              uiDialogButtonPane = $('<div></div>')
6345                  .addClass(
6346                      'ui-dialog-buttonpane ' +
6347                      'ui-widget-content ' +
6348                      'ui-helper-clearfix'
6349                  ),
6350              uiButtonSet = $( "<div></div>" )
6351                  .addClass( "ui-dialog-buttonset" )
6352                  .appendTo( uiDialogButtonPane );
6353  
6354          // if we already have a button pane, remove it
6355          self.uiDialog.find('.ui-dialog-buttonpane').remove();
6356  
6357          if (typeof buttons === 'object' && buttons !== null) {
6358              $.each(buttons, function() {
6359                  return !(hasButtons = true);
6360              });
6361          }
6362          if (hasButtons) {
6363              $.each(buttons, function(name, props) {
6364                  props = $.isFunction( props ) ?
6365                      { click: props, text: name } :
6366                      props;
6367                  var button = $('<button type="button"></button>')
6368                      .click(function() {
6369                          props.click.apply(self.element[0], arguments);
6370                      })
6371                      .appendTo(uiButtonSet);
6372                  // can't use .attr( props, true ) with jQuery 1.3.2.
6373                  $.each( props, function( key, value ) {
6374                      if ( key === "click" ) {
6375                          return;
6376                      }
6377                      if ( key in attrFn ) {
6378                          button[ key ]( value );
6379                      } else {
6380                          button.attr( key, value );
6381                      }
6382                  });
6383                  if ($.fn.button) {
6384                      button.button();
6385                  }
6386              });
6387              uiDialogButtonPane.appendTo(self.uiDialog);
6388          }
6389      },
6390  
6391      _makeDraggable: function() {
6392          var self = this,
6393              options = self.options,
6394              doc = $(document),
6395              heightBeforeDrag;
6396  
6397  		function filteredUi(ui) {
6398              return {
6399                  position: ui.position,
6400                  offset: ui.offset
6401              };
6402          }
6403  
6404          self.uiDialog.draggable({
6405              cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
6406              handle: '.ui-dialog-titlebar',
6407              containment: 'document',
6408              start: function(event, ui) {
6409                  heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
6410                  $(this).height($(this).height()).addClass("ui-dialog-dragging");
6411                  self._trigger('dragStart', event, filteredUi(ui));
6412              },
6413              drag: function(event, ui) {
6414                  self._trigger('drag', event, filteredUi(ui));
6415              },
6416              stop: function(event, ui) {
6417                  options.position = [ui.position.left - doc.scrollLeft(),
6418                      ui.position.top - doc.scrollTop()];
6419                  $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
6420                  self._trigger('dragStop', event, filteredUi(ui));
6421                  $.ui.dialog.overlay.resize();
6422              }
6423          });
6424      },
6425  
6426      _makeResizable: function(handles) {
6427          handles = (handles === undefined ? this.options.resizable : handles);
6428          var self = this,
6429              options = self.options,
6430              // .ui-resizable has position: relative defined in the stylesheet
6431              // but dialogs have to use absolute or fixed positioning
6432              position = self.uiDialog.css('position'),
6433              resizeHandles = (typeof handles === 'string' ?
6434                  handles    :
6435                  'n,e,s,w,se,sw,ne,nw'
6436              );
6437  
6438  		function filteredUi(ui) {
6439              return {
6440                  originalPosition: ui.originalPosition,
6441                  originalSize: ui.originalSize,
6442                  position: ui.position,
6443                  size: ui.size
6444              };
6445          }
6446  
6447          self.uiDialog.resizable({
6448              cancel: '.ui-dialog-content',
6449              containment: 'document',
6450              alsoResize: self.element,
6451              maxWidth: options.maxWidth,
6452              maxHeight: options.maxHeight,
6453              minWidth: options.minWidth,
6454              minHeight: self._minHeight(),
6455              handles: resizeHandles,
6456              start: function(event, ui) {
6457                  $(this).addClass("ui-dialog-resizing");
6458                  self._trigger('resizeStart', event, filteredUi(ui));
6459              },
6460              resize: function(event, ui) {
6461                  self._trigger('resize', event, filteredUi(ui));
6462              },
6463              stop: function(event, ui) {
6464                  $(this).removeClass("ui-dialog-resizing");
6465                  options.height = $(this).height();
6466                  options.width = $(this).width();
6467                  self._trigger('resizeStop', event, filteredUi(ui));
6468                  $.ui.dialog.overlay.resize();
6469              }
6470          })
6471          .css('position', position)
6472          .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6473      },
6474  
6475      _minHeight: function() {
6476          var options = this.options;
6477  
6478          if (options.height === 'auto') {
6479              return options.minHeight;
6480          } else {
6481              return Math.min(options.minHeight, options.height);
6482          }
6483      },
6484  
6485      _position: function(position) {
6486          var myAt = [],
6487              offset = [0, 0],
6488              isVisible;
6489  
6490          if (position) {
6491              // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6492      //        if (typeof position == 'string' || $.isArray(position)) {
6493      //            myAt = $.isArray(position) ? position : position.split(' ');
6494  
6495              if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
6496                  myAt = position.split ? position.split(' ') : [position[0], position[1]];
6497                  if (myAt.length === 1) {
6498                      myAt[1] = myAt[0];
6499                  }
6500  
6501                  $.each(['left', 'top'], function(i, offsetPosition) {
6502                      if (+myAt[i] === myAt[i]) {
6503                          offset[i] = myAt[i];
6504                          myAt[i] = offsetPosition;
6505                      }
6506                  });
6507  
6508                  position = {
6509                      my: myAt.join(" "),
6510                      at: myAt.join(" "),
6511                      offset: offset.join(" ")
6512                  };
6513              } 
6514  
6515              position = $.extend({}, $.ui.dialog.prototype.options.position, position);
6516          } else {
6517              position = $.ui.dialog.prototype.options.position;
6518          }
6519  
6520          // need to show the dialog to get the actual offset in the position plugin
6521          isVisible = this.uiDialog.is(':visible');
6522          if (!isVisible) {
6523              this.uiDialog.show();
6524          }
6525          this.uiDialog
6526              // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6527              .css({ top: 0, left: 0 })
6528              .position($.extend({ of: window }, position));
6529          if (!isVisible) {
6530              this.uiDialog.hide();
6531          }
6532      },
6533  
6534      _setOptions: function( options ) {
6535          var self = this,
6536              resizableOptions = {},
6537              resize = false;
6538  
6539          $.each( options, function( key, value ) {
6540              self._setOption( key, value );
6541              
6542              if ( key in sizeRelatedOptions ) {
6543                  resize = true;
6544              }
6545              if ( key in resizableRelatedOptions ) {
6546                  resizableOptions[ key ] = value;
6547              }
6548          });
6549  
6550          if ( resize ) {
6551              this._size();
6552          }
6553          if ( this.uiDialog.is( ":data(resizable)" ) ) {
6554              this.uiDialog.resizable( "option", resizableOptions );
6555          }
6556      },
6557  
6558      _setOption: function(key, value){
6559          var self = this,
6560              uiDialog = self.uiDialog;
6561  
6562          switch (key) {
6563              //handling of deprecated beforeclose (vs beforeClose) option
6564              //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6565              //TODO: remove in 1.9pre
6566              case "beforeclose":
6567                  key = "beforeClose";
6568                  break;
6569              case "buttons":
6570                  self._createButtons(value);
6571                  break;
6572              case "closeText":
6573                  // ensure that we always pass a string
6574                  self.uiDialogTitlebarCloseText.text("" + value);
6575                  break;
6576              case "dialogClass":
6577                  uiDialog
6578                      .removeClass(self.options.dialogClass)
6579                      .addClass(uiDialogClasses + value);
6580                  break;
6581              case "disabled":
6582                  if (value) {
6583                      uiDialog.addClass('ui-dialog-disabled');
6584                  } else {
6585                      uiDialog.removeClass('ui-dialog-disabled');
6586                  }
6587                  break;
6588              case "draggable":
6589                  var isDraggable = uiDialog.is( ":data(draggable)" );
6590                  if ( isDraggable && !value ) {
6591                      uiDialog.draggable( "destroy" );
6592                  }
6593                  
6594                  if ( !isDraggable && value ) {
6595                      self._makeDraggable();
6596                  }
6597                  break;
6598              case "position":
6599                  self._position(value);
6600                  break;
6601              case "resizable":
6602                  // currently resizable, becoming non-resizable
6603                  var isResizable = uiDialog.is( ":data(resizable)" );
6604                  if (isResizable && !value) {
6605                      uiDialog.resizable('destroy');
6606                  }
6607  
6608                  // currently resizable, changing handles
6609                  if (isResizable && typeof value === 'string') {
6610                      uiDialog.resizable('option', 'handles', value);
6611                  }
6612  
6613                  // currently non-resizable, becoming resizable
6614                  if (!isResizable && value !== false) {
6615                      self._makeResizable(value);
6616                  }
6617                  break;
6618              case "title":
6619                  // convert whatever was passed in o a string, for html() to not throw up
6620                  $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
6621                  break;
6622          }
6623  
6624          $.Widget.prototype._setOption.apply(self, arguments);
6625      },
6626  
6627      _size: function() {
6628          /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6629           * divs will both have width and height set, so we need to reset them
6630           */
6631          var options = this.options,
6632              nonContentHeight,
6633              minContentHeight,
6634              isVisible = this.uiDialog.is( ":visible" );
6635  
6636          // reset content sizing
6637          this.element.show().css({
6638              width: 'auto',
6639              minHeight: 0,
6640              height: 0
6641          });
6642  
6643          if (options.minWidth > options.width) {
6644              options.width = options.minWidth;
6645          }
6646  
6647          // reset wrapper sizing
6648          // determine the height of all the non-content elements
6649          nonContentHeight = this.uiDialog.css({
6650                  height: 'auto',
6651                  width: options.width
6652              })
6653              .height();
6654          minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
6655          
6656          if ( options.height === "auto" ) {
6657              // only needed for IE6 support
6658              if ( $.support.minHeight ) {
6659                  this.element.css({
6660                      minHeight: minContentHeight,
6661                      height: "auto"
6662                  });
6663              } else {
6664                  this.uiDialog.show();
6665                  var autoHeight = this.element.css( "height", "auto" ).height();
6666                  if ( !isVisible ) {
6667                      this.uiDialog.hide();
6668                  }
6669                  this.element.height( Math.max( autoHeight, minContentHeight ) );
6670              }
6671          } else {
6672              this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
6673          }
6674  
6675          if (this.uiDialog.is(':data(resizable)')) {
6676              this.uiDialog.resizable('option', 'minHeight', this._minHeight());
6677          }
6678      }
6679  });
6680  
6681  $.extend($.ui.dialog, {
6682      version: "1.8.18",
6683  
6684      uuid: 0,
6685      maxZ: 0,
6686  
6687      getTitleId: function($el) {
6688          var id = $el.attr('id');
6689          if (!id) {
6690              this.uuid += 1;
6691              id = this.uuid;
6692          }
6693          return 'ui-dialog-title-' + id;
6694      },
6695  
6696      overlay: function(dialog) {
6697          this.$el = $.ui.dialog.overlay.create(dialog);
6698      }
6699  });
6700  
6701  $.extend($.ui.dialog.overlay, {
6702      instances: [],
6703      // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6704      oldInstances: [],
6705      maxZ: 0,
6706      events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6707          function(event) { return event + '.dialog-overlay'; }).join(' '),
6708      create: function(dialog) {
6709          if (this.instances.length === 0) {
6710              // prevent use of anchors and inputs
6711              // we use a setTimeout in case the overlay is created from an
6712              // event that we're going to be cancelling (see #2804)
6713              setTimeout(function() {
6714                  // handle $(el).dialog().dialog('close') (see #4065)
6715                  if ($.ui.dialog.overlay.instances.length) {
6716                      $(document).bind($.ui.dialog.overlay.events, function(event) {
6717                          // stop events if the z-index of the target is < the z-index of the overlay
6718                          // we cannot return true when we don't want to cancel the event (#3523)
6719                          if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
6720                              return false;
6721                          }
6722                      });
6723                  }
6724              }, 1);
6725  
6726              // allow closing by pressing the escape key
6727              $(document).bind('keydown.dialog-overlay', function(event) {
6728                  if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
6729                      event.keyCode === $.ui.keyCode.ESCAPE) {
6730                      
6731                      dialog.close(event);
6732                      event.preventDefault();
6733                  }
6734              });
6735  
6736              // handle window resize
6737              $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
6738          }
6739  
6740          var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6741              .appendTo(document.body)
6742              .css({
6743                  width: this.width(),
6744                  height: this.height()
6745              });
6746  
6747          if ($.fn.bgiframe) {
6748              $el.bgiframe();
6749          }
6750  
6751          this.instances.push($el);
6752          return $el;
6753      },
6754  
6755      destroy: function($el) {
6756          var indexOf = $.inArray($el, this.instances);
6757          if (indexOf != -1){
6758              this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
6759          }
6760  
6761          if (this.instances.length === 0) {
6762              $([document, window]).unbind('.dialog-overlay');
6763          }
6764  
6765          $el.remove();
6766          
6767          // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6768          var maxZ = 0;
6769          $.each(this.instances, function() {
6770              maxZ = Math.max(maxZ, this.css('z-index'));
6771          });
6772          this.maxZ = maxZ;
6773      },
6774  
6775      height: function() {
6776          var scrollHeight,
6777              offsetHeight;
6778          // handle IE 6
6779          if ($.browser.msie && $.browser.version < 7) {
6780              scrollHeight = Math.max(
6781                  document.documentElement.scrollHeight,
6782                  document.body.scrollHeight
6783              );
6784              offsetHeight = Math.max(
6785                  document.documentElement.offsetHeight,
6786                  document.body.offsetHeight
6787              );
6788  
6789              if (scrollHeight < offsetHeight) {
6790                  return $(window).height() + 'px';
6791              } else {
6792                  return scrollHeight + 'px';
6793              }
6794          // handle "good" browsers
6795          } else {
6796              return $(document).height() + 'px';
6797          }
6798      },
6799  
6800      width: function() {
6801          var scrollWidth,
6802              offsetWidth;
6803          // handle IE
6804          if ( $.browser.msie ) {
6805              scrollWidth = Math.max(
6806                  document.documentElement.scrollWidth,
6807                  document.body.scrollWidth
6808              );
6809              offsetWidth = Math.max(
6810                  document.documentElement.offsetWidth,
6811                  document.body.offsetWidth
6812              );
6813  
6814              if (scrollWidth < offsetWidth) {
6815                  return $(window).width() + 'px';
6816              } else {
6817                  return scrollWidth + 'px';
6818              }
6819          // handle "good" browsers
6820          } else {
6821              return $(document).width() + 'px';
6822          }
6823      },
6824  
6825      resize: function() {
6826          /* If the dialog is draggable and the user drags it past the
6827           * right edge of the window, the document becomes wider so we
6828           * need to stretch the overlay. If the user then drags the
6829           * dialog back to the left, the document will become narrower,
6830           * so we need to shrink the overlay to the appropriate size.
6831           * This is handled by shrinking the overlay before setting it
6832           * to the full document size.
6833           */
6834          var $overlays = $([]);
6835          $.each($.ui.dialog.overlay.instances, function() {
6836              $overlays = $overlays.add(this);
6837          });
6838  
6839          $overlays.css({
6840              width: 0,
6841              height: 0
6842          }).css({
6843              width: $.ui.dialog.overlay.width(),
6844              height: $.ui.dialog.overlay.height()
6845          });
6846      }
6847  });
6848  
6849  $.extend($.ui.dialog.overlay.prototype, {
6850      destroy: function() {
6851          $.ui.dialog.overlay.destroy(this.$el);
6852      }
6853  });
6854  
6855  }(jQuery));
6856  /*
6857   * jQuery UI Slider 1.8.18
6858   *
6859   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6860   * Dual licensed under the MIT or GPL Version 2 licenses.
6861   * http://jquery.org/license
6862   *
6863   * http://docs.jquery.com/UI/Slider
6864   *
6865   * Depends:
6866   *    jquery.ui.core.js
6867   *    jquery.ui.mouse.js
6868   *    jquery.ui.widget.js
6869   */
6870  (function( $, undefined ) {
6871  
6872  // number of pages in a slider
6873  // (how many times can you page up/down to go through the whole range)
6874  var numPages = 5;
6875  
6876  $.widget( "ui.slider", $.ui.mouse, {
6877  
6878      widgetEventPrefix: "slide",
6879  
6880      options: {
6881          animate: false,
6882          distance: 0,
6883          max: 100,
6884          min: 0,
6885          orientation: "horizontal",
6886          range: false,
6887          step: 1,
6888          value: 0,
6889          values: null
6890      },
6891  
6892      _create: function() {
6893          var self = this,
6894              o = this.options,
6895              existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6896              handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6897              handleCount = ( o.values && o.values.length ) || 1,
6898              handles = [];
6899  
6900          this._keySliding = false;
6901          this._mouseSliding = false;
6902          this._animateOff = true;
6903          this._handleIndex = null;
6904          this._detectOrientation();
6905          this._mouseInit();
6906  
6907          this.element
6908              .addClass( "ui-slider" +
6909                  " ui-slider-" + this.orientation +
6910                  " ui-widget" +
6911                  " ui-widget-content" +
6912                  " ui-corner-all" +
6913                  ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
6914  
6915          this.range = $([]);
6916  
6917          if ( o.range ) {
6918              if ( o.range === true ) {
6919                  if ( !o.values ) {
6920                      o.values = [ this._valueMin(), this._valueMin() ];
6921                  }
6922                  if ( o.values.length && o.values.length !== 2 ) {
6923                      o.values = [ o.values[0], o.values[0] ];
6924                  }
6925              }
6926  
6927              this.range = $( "<div></div>" )
6928                  .appendTo( this.element )
6929                  .addClass( "ui-slider-range" +
6930                  // note: this isn't the most fittingly semantic framework class for this element,
6931                  // but worked best visually with a variety of themes
6932                  " ui-widget-header" + 
6933                  ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
6934          }
6935  
6936          for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
6937              handles.push( handle );
6938          }
6939  
6940          this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
6941  
6942          this.handle = this.handles.eq( 0 );
6943  
6944          this.handles.add( this.range ).filter( "a" )
6945              .click(function( event ) {
6946                  event.preventDefault();
6947              })
6948              .hover(function() {
6949                  if ( !o.disabled ) {
6950                      $( this ).addClass( "ui-state-hover" );
6951                  }
6952              }, function() {
6953                  $( this ).removeClass( "ui-state-hover" );
6954              })
6955              .focus(function() {
6956                  if ( !o.disabled ) {
6957                      $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6958                      $( this ).addClass( "ui-state-focus" );
6959                  } else {
6960                      $( this ).blur();
6961                  }
6962              })
6963              .blur(function() {
6964                  $( this ).removeClass( "ui-state-focus" );
6965              });
6966  
6967          this.handles.each(function( i ) {
6968              $( this ).data( "index.ui-slider-handle", i );
6969          });
6970  
6971          this.handles
6972              .keydown(function( event ) {
6973                  var index = $( this ).data( "index.ui-slider-handle" ),
6974                      allowed,
6975                      curVal,
6976                      newVal,
6977                      step;
6978      
6979                  if ( self.options.disabled ) {
6980                      return;
6981                  }
6982      
6983                  switch ( event.keyCode ) {
6984                      case $.ui.keyCode.HOME:
6985                      case $.ui.keyCode.END:
6986                      case $.ui.keyCode.PAGE_UP:
6987                      case $.ui.keyCode.PAGE_DOWN:
6988                      case $.ui.keyCode.UP:
6989                      case $.ui.keyCode.RIGHT:
6990                      case $.ui.keyCode.DOWN:
6991                      case $.ui.keyCode.LEFT:
6992                          event.preventDefault();
6993                          if ( !self._keySliding ) {
6994                              self._keySliding = true;
6995                              $( this ).addClass( "ui-state-active" );
6996                              allowed = self._start( event, index );
6997                              if ( allowed === false ) {
6998                                  return;
6999                              }
7000                          }
7001                          break;
7002                  }
7003      
7004                  step = self.options.step;
7005                  if ( self.options.values && self.options.values.length ) {
7006                      curVal = newVal = self.values( index );
7007                  } else {
7008                      curVal = newVal = self.value();
7009                  }
7010      
7011                  switch ( event.keyCode ) {
7012                      case $.ui.keyCode.HOME:
7013                          newVal = self._valueMin();
7014                          break;
7015                      case $.ui.keyCode.END:
7016                          newVal = self._valueMax();
7017                          break;
7018                      case $.ui.keyCode.PAGE_UP:
7019                          newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
7020                          break;
7021                      case $.ui.keyCode.PAGE_DOWN:
7022                          newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
7023                          break;
7024                      case $.ui.keyCode.UP:
7025                      case $.ui.keyCode.RIGHT:
7026                          if ( curVal === self._valueMax() ) {
7027                              return;
7028                          }
7029                          newVal = self._trimAlignValue( curVal + step );
7030                          break;
7031                      case $.ui.keyCode.DOWN:
7032                      case $.ui.keyCode.LEFT:
7033                          if ( curVal === self._valueMin() ) {
7034                              return;
7035                          }
7036                          newVal = self._trimAlignValue( curVal - step );
7037                          break;
7038                  }
7039      
7040                  self._slide( event, index, newVal );
7041              })
7042              .keyup(function( event ) {
7043                  var index = $( this ).data( "index.ui-slider-handle" );
7044      
7045                  if ( self._keySliding ) {
7046                      self._keySliding = false;
7047                      self._stop( event, index );
7048                      self._change( event, index );
7049                      $( this ).removeClass( "ui-state-active" );
7050                  }
7051      
7052              });
7053  
7054          this._refreshValue();
7055  
7056          this._animateOff = false;
7057      },
7058  
7059      destroy: function() {
7060          this.handles.remove();
7061          this.range.remove();
7062  
7063          this.element
7064              .removeClass( "ui-slider" +
7065                  " ui-slider-horizontal" +
7066                  " ui-slider-vertical" +
7067                  " ui-slider-disabled" +
7068                  " ui-widget" +
7069                  " ui-widget-content" +
7070                  " ui-corner-all" )
7071              .removeData( "slider" )
7072              .unbind( ".slider" );
7073  
7074          this._mouseDestroy();
7075  
7076          return this;
7077      },
7078  
7079      _mouseCapture: function( event ) {
7080          var o = this.options,
7081              position,
7082              normValue,
7083              distance,
7084              closestHandle,
7085              self,
7086              index,
7087              allowed,
7088              offset,
7089              mouseOverHandle;
7090  
7091          if ( o.disabled ) {
7092              return false;
7093          }
7094  
7095          this.elementSize = {
7096              width: this.element.outerWidth(),
7097              height: this.element.outerHeight()
7098          };
7099          this.elementOffset = this.element.offset();
7100  
7101          position = { x: event.pageX, y: event.pageY };
7102          normValue = this._normValueFromMouse( position );
7103          distance = this._valueMax() - this._valueMin() + 1;
7104          self = this;
7105          this.handles.each(function( i ) {
7106              var thisDistance = Math.abs( normValue - self.values(i) );
7107              if ( distance > thisDistance ) {
7108                  distance = thisDistance;
7109                  closestHandle = $( this );
7110                  index = i;
7111              }
7112          });
7113  
7114          // workaround for bug #3736 (if both handles of a range are at 0,
7115          // the first is always used as the one with least distance,
7116          // and moving it is obviously prevented by preventing negative ranges)
7117          if( o.range === true && this.values(1) === o.min ) {
7118              index += 1;
7119              closestHandle = $( this.handles[index] );
7120          }
7121  
7122          allowed = this._start( event, index );
7123          if ( allowed === false ) {
7124              return false;
7125          }
7126          this._mouseSliding = true;
7127  
7128          self._handleIndex = index;
7129  
7130          closestHandle
7131              .addClass( "ui-state-active" )
7132              .focus();
7133          
7134          offset = closestHandle.offset();
7135          mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
7136          this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
7137              left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
7138              top: event.pageY - offset.top -
7139                  ( closestHandle.height() / 2 ) -
7140                  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
7141                  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
7142                  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
7143          };
7144  
7145          if ( !this.handles.hasClass( "ui-state-hover" ) ) {
7146              this._slide( event, index, normValue );
7147          }
7148          this._animateOff = true;
7149          return true;
7150      },
7151  
7152      _mouseStart: function( event ) {
7153          return true;
7154      },
7155  
7156      _mouseDrag: function( event ) {
7157          var position = { x: event.pageX, y: event.pageY },
7158              normValue = this._normValueFromMouse( position );
7159          
7160          this._slide( event, this._handleIndex, normValue );
7161  
7162          return false;
7163      },
7164  
7165      _mouseStop: function( event ) {
7166          this.handles.removeClass( "ui-state-active" );
7167          this._mouseSliding = false;
7168  
7169          this._stop( event, this._handleIndex );
7170          this._change( event, this._handleIndex );
7171  
7172          this._handleIndex = null;
7173          this._clickOffset = null;
7174          this._animateOff = false;
7175  
7176          return false;
7177      },
7178      
7179      _detectOrientation: function() {
7180          this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
7181      },
7182  
7183      _normValueFromMouse: function( position ) {
7184          var pixelTotal,
7185              pixelMouse,
7186              percentMouse,
7187              valueTotal,
7188              valueMouse;
7189  
7190          if ( this.orientation === "horizontal" ) {
7191              pixelTotal = this.elementSize.width;
7192              pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
7193          } else {
7194              pixelTotal = this.elementSize.height;
7195              pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
7196          }
7197  
7198          percentMouse = ( pixelMouse / pixelTotal );
7199          if ( percentMouse > 1 ) {
7200              percentMouse = 1;
7201          }
7202          if ( percentMouse < 0 ) {
7203              percentMouse = 0;
7204          }
7205          if ( this.orientation === "vertical" ) {
7206              percentMouse = 1 - percentMouse;
7207          }
7208  
7209          valueTotal = this._valueMax() - this._valueMin();
7210          valueMouse = this._valueMin() + percentMouse * valueTotal;
7211  
7212          return this._trimAlignValue( valueMouse );
7213      },
7214  
7215      _start: function( event, index ) {
7216          var uiHash = {
7217              handle: this.handles[ index ],
7218              value: this.value()
7219          };
7220          if ( this.options.values && this.options.values.length ) {
7221              uiHash.value = this.values( index );
7222              uiHash.values = this.values();
7223          }
7224          return this._trigger( "start", event, uiHash );
7225      },
7226  
7227      _slide: function( event, index, newVal ) {
7228          var otherVal,
7229              newValues,
7230              allowed;
7231  
7232          if ( this.options.values && this.options.values.length ) {
7233              otherVal = this.values( index ? 0 : 1 );
7234  
7235              if ( ( this.options.values.length === 2 && this.options.range === true ) && 
7236                      ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
7237                  ) {
7238                  newVal = otherVal;
7239              }
7240  
7241              if ( newVal !== this.values( index ) ) {
7242                  newValues = this.values();
7243                  newValues[ index ] = newVal;
7244                  // A slide can be canceled by returning false from the slide callback
7245                  allowed = this._trigger( "slide", event, {
7246                      handle: this.handles[ index ],
7247                      value: newVal,
7248                      values: newValues
7249                  } );
7250                  otherVal = this.values( index ? 0 : 1 );
7251                  if ( allowed !== false ) {
7252                      this.values( index, newVal, true );
7253                  }
7254              }
7255          } else {
7256              if ( newVal !== this.value() ) {
7257                  // A slide can be canceled by returning false from the slide callback
7258                  allowed = this._trigger( "slide", event, {
7259                      handle: this.handles[ index ],
7260                      value: newVal
7261                  } );
7262                  if ( allowed !== false ) {
7263                      this.value( newVal );
7264                  }
7265              }
7266          }
7267      },
7268  
7269      _stop: function( event, index ) {
7270          var uiHash = {
7271              handle: this.handles[ index ],
7272              value: this.value()
7273          };
7274          if ( this.options.values && this.options.values.length ) {
7275              uiHash.value = this.values( index );
7276              uiHash.values = this.values();
7277          }
7278  
7279          this._trigger( "stop", event, uiHash );
7280      },
7281  
7282      _change: function( event, index ) {
7283          if ( !this._keySliding && !this._mouseSliding ) {
7284              var uiHash = {
7285                  handle: this.handles[ index ],
7286                  value: this.value()
7287              };
7288              if ( this.options.values && this.options.values.length ) {
7289                  uiHash.value = this.values( index );
7290                  uiHash.values = this.values();
7291              }
7292  
7293              this._trigger( "change", event, uiHash );
7294          }
7295      },
7296  
7297      value: function( newValue ) {
7298          if ( arguments.length ) {
7299              this.options.value = this._trimAlignValue( newValue );
7300              this._refreshValue();
7301              this._change( null, 0 );
7302              return;
7303          }
7304  
7305          return this._value();
7306      },
7307  
7308      values: function( index, newValue ) {
7309          var vals,
7310              newValues,
7311              i;
7312  
7313          if ( arguments.length > 1 ) {
7314              this.options.values[ index ] = this._trimAlignValue( newValue );
7315              this._refreshValue();
7316              this._change( null, index );
7317              return;
7318          }
7319  
7320          if ( arguments.length ) {
7321              if ( $.isArray( arguments[ 0 ] ) ) {
7322                  vals = this.options.values;
7323                  newValues = arguments[ 0 ];
7324                  for ( i = 0; i < vals.length; i += 1 ) {
7325                      vals[ i ] = this._trimAlignValue( newValues[ i ] );
7326                      this._change( null, i );
7327                  }
7328                  this._refreshValue();
7329              } else {
7330                  if ( this.options.values && this.options.values.length ) {
7331                      return this._values( index );
7332                  } else {
7333                      return this.value();
7334                  }
7335              }
7336          } else {
7337              return this._values();
7338          }
7339      },
7340  
7341      _setOption: function( key, value ) {
7342          var i,
7343              valsLength = 0;
7344  
7345          if ( $.isArray( this.options.values ) ) {
7346              valsLength = this.options.values.length;
7347          }
7348  
7349          $.Widget.prototype._setOption.apply( this, arguments );
7350  
7351          switch ( key ) {
7352              case "disabled":
7353                  if ( value ) {
7354                      this.handles.filter( ".ui-state-focus" ).blur();
7355                      this.handles.removeClass( "ui-state-hover" );
7356                      this.handles.propAttr( "disabled", true );
7357                      this.element.addClass( "ui-disabled" );
7358                  } else {
7359                      this.handles.propAttr( "disabled", false );
7360                      this.element.removeClass( "ui-disabled" );
7361                  }
7362                  break;
7363              case "orientation":
7364                  this._detectOrientation();
7365                  this.element
7366                      .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7367                      .addClass( "ui-slider-" + this.orientation );
7368                  this._refreshValue();
7369                  break;
7370              case "value":
7371                  this._animateOff = true;
7372                  this._refreshValue();
7373                  this._change( null, 0 );
7374                  this._animateOff = false;
7375                  break;
7376              case "values":
7377                  this._animateOff = true;
7378                  this._refreshValue();
7379                  for ( i = 0; i < valsLength; i += 1 ) {
7380                      this._change( null, i );
7381                  }
7382                  this._animateOff = false;
7383                  break;
7384          }
7385      },
7386  
7387      //internal value getter
7388      // _value() returns value trimmed by min and max, aligned by step
7389      _value: function() {
7390          var val = this.options.value;
7391          val = this._trimAlignValue( val );
7392  
7393          return val;
7394      },
7395  
7396      //internal values getter
7397      // _values() returns array of values trimmed by min and max, aligned by step
7398      // _values( index ) returns single value trimmed by min and max, aligned by step
7399      _values: function( index ) {
7400          var val,
7401              vals,
7402              i;
7403  
7404          if ( arguments.length ) {
7405              val = this.options.values[ index ];
7406              val = this._trimAlignValue( val );
7407  
7408              return val;
7409          } else {
7410              // .slice() creates a copy of the array
7411              // this copy gets trimmed by min and max and then returned
7412              vals = this.options.values.slice();
7413              for ( i = 0; i < vals.length; i+= 1) {
7414                  vals[ i ] = this._trimAlignValue( vals[ i ] );
7415              }
7416  
7417              return vals;
7418          }
7419      },
7420      
7421      // returns the step-aligned value that val is closest to, between (inclusive) min and max
7422      _trimAlignValue: function( val ) {
7423          if ( val <= this._valueMin() ) {
7424              return this._valueMin();
7425          }
7426          if ( val >= this._valueMax() ) {
7427              return this._valueMax();
7428          }
7429          var step = ( this.options.step > 0 ) ? this.options.step : 1,
7430              valModStep = (val - this._valueMin()) % step,
7431              alignValue = val - valModStep;
7432  
7433          if ( Math.abs(valModStep) * 2 >= step ) {
7434              alignValue += ( valModStep > 0 ) ? step : ( -step );
7435          }
7436  
7437          // Since JavaScript has problems with large floats, round
7438          // the final value to 5 digits after the decimal point (see #4124)
7439          return parseFloat( alignValue.toFixed(5) );
7440      },
7441  
7442      _valueMin: function() {
7443          return this.options.min;
7444      },
7445  
7446      _valueMax: function() {
7447          return this.options.max;
7448      },
7449      
7450      _refreshValue: function() {
7451          var oRange = this.options.range,
7452              o = this.options,
7453              self = this,
7454              animate = ( !this._animateOff ) ? o.animate : false,
7455              valPercent,
7456              _set = {},
7457              lastValPercent,
7458              value,
7459              valueMin,
7460              valueMax;
7461  
7462          if ( this.options.values && this.options.values.length ) {
7463              this.handles.each(function( i, j ) {
7464                  valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
7465                  _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7466                  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7467                  if ( self.options.range === true ) {
7468                      if ( self.orientation === "horizontal" ) {
7469                          if ( i === 0 ) {
7470                              self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
7471                          }
7472                          if ( i === 1 ) {
7473                              self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7474                          }
7475                      } else {
7476                          if ( i === 0 ) {
7477                              self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
7478                          }
7479                          if ( i === 1 ) {
7480                              self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
7481                          }
7482                      }
7483                  }
7484                  lastValPercent = valPercent;
7485              });
7486          } else {
7487              value = this.value();
7488              valueMin = this._valueMin();
7489              valueMax = this._valueMax();
7490              valPercent = ( valueMax !== valueMin ) ?
7491                      ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
7492                      0;
7493              _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
7494              this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
7495  
7496              if ( oRange === "min" && this.orientation === "horizontal" ) {
7497                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
7498              }
7499              if ( oRange === "max" && this.orientation === "horizontal" ) {
7500                  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7501              }
7502              if ( oRange === "min" && this.orientation === "vertical" ) {
7503                  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
7504              }
7505              if ( oRange === "max" && this.orientation === "vertical" ) {
7506                  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
7507              }
7508          }
7509      }
7510  
7511  });
7512  
7513  $.extend( $.ui.slider, {
7514      version: "1.8.18"
7515  });
7516  
7517  }(jQuery));
7518  /*
7519   * jQuery UI Tabs 1.8.18
7520   *
7521   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7522   * Dual licensed under the MIT or GPL Version 2 licenses.
7523   * http://jquery.org/license
7524   *
7525   * http://docs.jquery.com/UI/Tabs
7526   *
7527   * Depends:
7528   *    jquery.ui.core.js
7529   *    jquery.ui.widget.js
7530   */
7531  (function( $, undefined ) {
7532  
7533  var tabId = 0,
7534      listId = 0;
7535  
7536  function getNextTabId() {
7537      return ++tabId;
7538  }
7539  
7540  function getNextListId() {
7541      return ++listId;
7542  }
7543  
7544  $.widget( "ui.tabs", {
7545      options: {
7546          add: null,
7547          ajaxOptions: null,
7548          cache: false,
7549          cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7550          collapsible: false,
7551          disable: null,
7552          disabled: [],
7553          enable: null,
7554          event: "click",
7555          fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7556          idPrefix: "ui-tabs-",
7557          load: null,
7558          panelTemplate: "<div></div>",
7559          remove: null,
7560          select: null,
7561          show: null,
7562          spinner: "<em>Loading&#8230;</em>",
7563          tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7564      },
7565  
7566      _create: function() {
7567          this._tabify( true );
7568      },
7569  
7570      _setOption: function( key, value ) {
7571          if ( key == "selected" ) {
7572              if (this.options.collapsible && value == this.options.selected ) {
7573                  return;
7574              }
7575              this.select( value );
7576          } else {
7577              this.options[ key ] = value;
7578              this._tabify();
7579          }
7580      },
7581  
7582      _tabId: function( a ) {
7583          return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7584              this.options.idPrefix + getNextTabId();
7585      },
7586  
7587      _sanitizeSelector: function( hash ) {
7588          // we need this because an id may contain a ":"
7589          return hash.replace( /:/g, "\\:" );
7590      },
7591  
7592      _cookie: function() {
7593          var cookie = this.cookie ||
7594              ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
7595          return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
7596      },
7597  
7598      _ui: function( tab, panel ) {
7599          return {
7600              tab: tab,
7601              panel: panel,
7602              index: this.anchors.index( tab )
7603          };
7604      },
7605  
7606      _cleanup: function() {
7607          // restore all former loading tabs labels
7608          this.lis.filter( ".ui-state-processing" )
7609              .removeClass( "ui-state-processing" )
7610              .find( "span:data(label.tabs)" )
7611                  .each(function() {
7612                      var el = $( this );
7613                      el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
7614                  });
7615      },
7616  
7617      _tabify: function( init ) {
7618          var self = this,
7619              o = this.options,
7620              fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
7621  
7622          this.list = this.element.find( "ol,ul" ).eq( 0 );
7623          this.lis = $( " > li:has(a[href])", this.list );
7624          this.anchors = this.lis.map(function() {
7625              return $( "a", this )[ 0 ];
7626          });
7627          this.panels = $( [] );
7628  
7629          this.anchors.each(function( i, a ) {
7630              var href = $( a ).attr( "href" );
7631              // For dynamically created HTML that contains a hash as href IE < 8 expands
7632              // such href to the full page url with hash and then misinterprets tab as ajax.
7633              // Same consideration applies for an added tab with a fragment identifier
7634              // since a[href=#fragment-identifier] does unexpectedly not match.
7635              // Thus normalize href attribute...
7636              var hrefBase = href.split( "#" )[ 0 ],
7637                  baseEl;
7638              if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
7639                      ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
7640                  href = a.hash;
7641                  a.href = href;
7642              }
7643  
7644              // inline tab
7645              if ( fragmentId.test( href ) ) {
7646                  self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
7647              // remote tab
7648              // prevent loading the page itself if href is just "#"
7649              } else if ( href && href !== "#" ) {
7650                  // required for restore on destroy
7651                  $.data( a, "href.tabs", href );
7652  
7653                  // TODO until #3808 is fixed strip fragment identifier from url
7654                  // (IE fails to load from such url)
7655                  $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
7656  
7657                  var id = self._tabId( a );
7658                  a.href = "#" + id;
7659                  var $panel = self.element.find( "#" + id );
7660                  if ( !$panel.length ) {
7661                      $panel = $( o.panelTemplate )
7662                          .attr( "id", id )
7663                          .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7664                          .insertAfter( self.panels[ i - 1 ] || self.list );
7665                      $panel.data( "destroy.tabs", true );
7666                  }
7667                  self.panels = self.panels.add( $panel );
7668              // invalid tab href
7669              } else {
7670                  o.disabled.push( i );
7671              }
7672          });
7673  
7674          // initialization from scratch
7675          if ( init ) {
7676              // attach necessary classes for styling
7677              this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7678              this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7679              this.lis.addClass( "ui-state-default ui-corner-top" );
7680              this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7681  
7682              // Selected tab
7683              // use "selected" option or try to retrieve:
7684              // 1. from fragment identifier in url
7685              // 2. from cookie
7686              // 3. from selected class attribute on <li>
7687              if ( o.selected === undefined ) {
7688                  if ( location.hash ) {
7689                      this.anchors.each(function( i, a ) {
7690                          if ( a.hash == location.hash ) {
7691                              o.selected = i;
7692                              return false;
7693                          }
7694                      });
7695                  }
7696                  if ( typeof o.selected !== "number" && o.cookie ) {
7697                      o.selected = parseInt( self._cookie(), 10 );
7698                  }
7699                  if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
7700                      o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7701                  }
7702                  o.selected = o.selected || ( this.lis.length ? 0 : -1 );
7703              } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
7704                  o.selected = -1;
7705              }
7706  
7707              // sanity check - default to first tab...
7708              o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
7709                  ? o.selected
7710                  : 0;
7711  
7712              // Take disabling tabs via class attribute from HTML
7713              // into account and update option properly.
7714              // A selected tab cannot become disabled.
7715              o.disabled = $.unique( o.disabled.concat(
7716                  $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
7717                      return self.lis.index( n );
7718                  })
7719              ) ).sort();
7720  
7721              if ( $.inArray( o.selected, o.disabled ) != -1 ) {
7722                  o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
7723              }
7724  
7725              // highlight selected tab
7726              this.panels.addClass( "ui-tabs-hide" );
7727              this.lis.removeClass( "ui-tabs-selected ui-state-active" );
7728              // check for length avoids error when initializing empty list
7729              if ( o.selected >= 0 && this.anchors.length ) {
7730                  self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
7731                  this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
7732  
7733                  // seems to be expected behavior that the show callback is fired
7734                  self.element.queue( "tabs", function() {
7735                      self._trigger( "show", null,
7736                          self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
7737                  });
7738  
7739                  this.load( o.selected );
7740              }
7741  
7742              // clean up to avoid memory leaks in certain versions of IE 6
7743              // TODO: namespace this event
7744              $( window ).bind( "unload", function() {
7745                  self.lis.add( self.anchors ).unbind( ".tabs" );
7746                  self.lis = self.anchors = self.panels = null;
7747              });
7748          // update selected after add/remove
7749          } else {
7750              o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
7751          }
7752  
7753          // update collapsible
7754          // TODO: use .toggleClass()
7755          this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7756  
7757          // set or update cookie after init and add/remove respectively
7758          if ( o.cookie ) {
7759              this._cookie( o.selected, o.cookie );
7760          }
7761  
7762          // disable tabs
7763          for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
7764              $( li )[ $.inArray( i, o.disabled ) != -1 &&
7765                  // TODO: use .toggleClass()
7766                  !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7767          }
7768  
7769          // reset cache if switching from cached to not cached
7770          if ( o.cache === false ) {
7771              this.anchors.removeData( "cache.tabs" );
7772          }
7773  
7774          // remove all handlers before, tabify may run on existing tabs after add or option change
7775          this.lis.add( this.anchors ).unbind( ".tabs" );
7776  
7777          if ( o.event !== "mouseover" ) {
7778              var addState = function( state, el ) {
7779                  if ( el.is( ":not(.ui-state-disabled)" ) ) {
7780                      el.addClass( "ui-state-" + state );
7781                  }
7782              };
7783              var removeState = function( state, el ) {
7784                  el.removeClass( "ui-state-" + state );
7785              };
7786              this.lis.bind( "mouseover.tabs" , function() {
7787                  addState( "hover", $( this ) );
7788              });
7789              this.lis.bind( "mouseout.tabs", function() {
7790                  removeState( "hover", $( this ) );
7791              });
7792              this.anchors.bind( "focus.tabs", function() {
7793                  addState( "focus", $( this ).closest( "li" ) );
7794              });
7795              this.anchors.bind( "blur.tabs", function() {
7796                  removeState( "focus", $( this ).closest( "li" ) );
7797              });
7798          }
7799  
7800          // set up animations
7801          var hideFx, showFx;
7802          if ( o.fx ) {
7803              if ( $.isArray( o.fx ) ) {
7804                  hideFx = o.fx[ 0 ];
7805                  showFx = o.fx[ 1 ];
7806              } else {
7807                  hideFx = showFx = o.fx;
7808              }
7809          }
7810  
7811          // Reset certain styles left over from animation
7812          // and prevent IE's ClearType bug...
7813  		function resetStyle( $el, fx ) {
7814              $el.css( "display", "" );
7815              if ( !$.support.opacity && fx.opacity ) {
7816                  $el[ 0 ].style.removeAttribute( "filter" );
7817              }
7818          }
7819  
7820          // Show a tab...
7821          var showTab = showFx
7822              ? function( clicked, $show ) {
7823                  $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7824                  $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7825                      .animate( showFx, showFx.duration || "normal", function() {
7826                          resetStyle( $show, showFx );
7827                          self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7828                      });
7829              }
7830              : function( clicked, $show ) {
7831                  $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7832                  $show.removeClass( "ui-tabs-hide" );
7833                  self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
7834              };
7835  
7836          // Hide a tab, $show is optional...
7837          var hideTab = hideFx
7838              ? function( clicked, $hide ) {
7839                  $hide.animate( hideFx, hideFx.duration || "normal", function() {
7840                      self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7841                      $hide.addClass( "ui-tabs-hide" );
7842                      resetStyle( $hide, hideFx );
7843                      self.element.dequeue( "tabs" );
7844                  });
7845              }
7846              : function( clicked, $hide, $show ) {
7847                  self.lis.removeClass( "ui-tabs-selected ui-state-active" );
7848                  $hide.addClass( "ui-tabs-hide" );
7849                  self.element.dequeue( "tabs" );
7850              };
7851  
7852          // attach tab event handler, unbind to avoid duplicates from former tabifying...
7853          this.anchors.bind( o.event + ".tabs", function() {
7854              var el = this,
7855                  $li = $(el).closest( "li" ),
7856                  $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
7857                  $show = self.element.find( self._sanitizeSelector( el.hash ) );
7858  
7859              // If tab is already selected and not collapsible or tab disabled or
7860              // or is already loading or click callback returns false stop here.
7861              // Check if click handler returns false last so that it is not executed
7862              // for a disabled or loading tab!
7863              if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
7864                  $li.hasClass( "ui-state-disabled" ) ||
7865                  $li.hasClass( "ui-state-processing" ) ||
7866                  self.panels.filter( ":animated" ).length ||
7867                  self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
7868                  this.blur();
7869                  return false;
7870              }
7871  
7872              o.selected = self.anchors.index( this );
7873  
7874              self.abort();
7875  
7876              // if tab may be closed
7877              if ( o.collapsible ) {
7878                  if ( $li.hasClass( "ui-tabs-selected" ) ) {
7879                      o.selected = -1;
7880  
7881                      if ( o.cookie ) {
7882                          self._cookie( o.selected, o.cookie );
7883                      }
7884  
7885                      self.element.queue( "tabs", function() {
7886                          hideTab( el, $hide );
7887                      }).dequeue( "tabs" );
7888  
7889                      this.blur();
7890                      return false;
7891                  } else if ( !$hide.length ) {
7892                      if ( o.cookie ) {
7893                          self._cookie( o.selected, o.cookie );
7894                      }
7895  
7896                      self.element.queue( "tabs", function() {
7897                          showTab( el, $show );
7898                      });
7899  
7900                      // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7901                      self.load( self.anchors.index( this ) );
7902  
7903                      this.blur();
7904                      return false;
7905                  }
7906              }
7907  
7908              if ( o.cookie ) {
7909                  self._cookie( o.selected, o.cookie );
7910              }
7911  
7912              // show new tab
7913              if ( $show.length ) {
7914                  if ( $hide.length ) {
7915                      self.element.queue( "tabs", function() {
7916                          hideTab( el, $hide );
7917                      });
7918                  }
7919                  self.element.queue( "tabs", function() {
7920                      showTab( el, $show );
7921                  });
7922  
7923                  self.load( self.anchors.index( this ) );
7924              } else {
7925                  throw "jQuery UI Tabs: Mismatching fragment identifier.";
7926              }
7927  
7928              // Prevent IE from keeping other link focussed when using the back button
7929              // and remove dotted border from clicked link. This is controlled via CSS
7930              // in modern browsers; blur() removes focus from address bar in Firefox
7931              // which can become a usability and annoying problem with tabs('rotate').
7932              if ( $.browser.msie ) {
7933                  this.blur();
7934              }
7935          });
7936  
7937          // disable click in any case
7938          this.anchors.bind( "click.tabs", function(){
7939              return false;
7940          });
7941      },
7942  
7943      _getIndex: function( index ) {
7944          // meta-function to give users option to provide a href string instead of a numerical index.
7945          // also sanitizes numerical indexes to valid values.
7946          if ( typeof index == "string" ) {
7947              index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
7948          }
7949  
7950          return index;
7951      },
7952  
7953      destroy: function() {
7954          var o = this.options;
7955  
7956          this.abort();
7957  
7958          this.element
7959              .unbind( ".tabs" )
7960              .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7961              .removeData( "tabs" );
7962  
7963          this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7964  
7965          this.anchors.each(function() {
7966              var href = $.data( this, "href.tabs" );
7967              if ( href ) {
7968                  this.href = href;
7969              }
7970              var $this = $( this ).unbind( ".tabs" );
7971              $.each( [ "href", "load", "cache" ], function( i, prefix ) {
7972                  $this.removeData( prefix + ".tabs" );
7973              });
7974          });
7975  
7976          this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
7977              if ( $.data( this, "destroy.tabs" ) ) {
7978                  $( this ).remove();
7979              } else {
7980                  $( this ).removeClass([
7981                      "ui-state-default",
7982                      "ui-corner-top",
7983                      "ui-tabs-selected",
7984                      "ui-state-active",
7985                      "ui-state-hover",
7986                      "ui-state-focus",
7987                      "ui-state-disabled",
7988                      "ui-tabs-panel",
7989                      "ui-widget-content",
7990                      "ui-corner-bottom",
7991                      "ui-tabs-hide"
7992                  ].join( " " ) );
7993              }
7994          });
7995  
7996          if ( o.cookie ) {
7997              this._cookie( null, o.cookie );
7998          }
7999  
8000          return this;
8001      },
8002  
8003      add: function( url, label, index ) {
8004          if ( index === undefined ) {
8005              index = this.anchors.length;
8006          }
8007  
8008          var self = this,
8009              o = this.options,
8010              $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
8011              id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
8012  
8013          $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
8014  
8015          // try to find an existing element before creating a new one
8016          var $panel = self.element.find( "#" + id );
8017          if ( !$panel.length ) {
8018              $panel = $( o.panelTemplate )
8019                  .attr( "id", id )
8020                  .data( "destroy.tabs", true );
8021          }
8022          $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
8023  
8024          if ( index >= this.lis.length ) {
8025              $li.appendTo( this.list );
8026              $panel.appendTo( this.list[ 0 ].parentNode );
8027          } else {
8028              $li.insertBefore( this.lis[ index ] );
8029              $panel.insertBefore( this.panels[ index ] );
8030          }
8031  
8032          o.disabled = $.map( o.disabled, function( n, i ) {
8033              return n >= index ? ++n : n;
8034          });
8035  
8036          this._tabify();
8037  
8038          if ( this.anchors.length == 1 ) {
8039              o.selected = 0;
8040              $li.addClass( "ui-tabs-selected ui-state-active" );
8041              $panel.removeClass( "ui-tabs-hide" );
8042              this.element.queue( "tabs", function() {
8043                  self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
8044              });
8045  
8046              this.load( 0 );
8047          }
8048  
8049          this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8050          return this;
8051      },
8052  
8053      remove: function( index ) {
8054          index = this._getIndex( index );
8055          var o = this.options,
8056              $li = this.lis.eq( index ).remove(),
8057              $panel = this.panels.eq( index ).remove();
8058  
8059          // If selected tab was removed focus tab to the right or
8060          // in case the last tab was removed the tab to the left.
8061          if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
8062              this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
8063          }
8064  
8065          o.disabled = $.map(
8066              $.grep( o.disabled, function(n, i) {
8067                  return n != index;
8068              }),
8069              function( n, i ) {
8070                  return n >= index ? --n : n;
8071              });
8072  
8073          this._tabify();
8074  
8075          this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
8076          return this;
8077      },
8078  
8079      enable: function( index ) {
8080          index = this._getIndex( index );
8081          var o = this.options;
8082          if ( $.inArray( index, o.disabled ) == -1 ) {
8083              return;
8084          }
8085  
8086          this.lis.eq( index ).removeClass( "ui-state-disabled" );
8087          o.disabled = $.grep( o.disabled, function( n, i ) {
8088              return n != index;
8089          });
8090  
8091          this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8092          return this;
8093      },
8094  
8095      disable: function( index ) {
8096          index = this._getIndex( index );
8097          var self = this, o = this.options;
8098          // cannot disable already selected tab
8099          if ( index != o.selected ) {
8100              this.lis.eq( index ).addClass( "ui-state-disabled" );
8101  
8102              o.disabled.push( index );
8103              o.disabled.sort();
8104  
8105              this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
8106          }
8107  
8108          return this;
8109      },
8110  
8111      select: function( index ) {
8112          index = this._getIndex( index );
8113          if ( index == -1 ) {
8114              if ( this.options.collapsible && this.options.selected != -1 ) {
8115                  index = this.options.selected;
8116              } else {
8117                  return this;
8118              }
8119          }
8120          this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
8121          return this;
8122      },
8123  
8124      load: function( index ) {
8125          index = this._getIndex( index );
8126          var self = this,
8127              o = this.options,
8128              a = this.anchors.eq( index )[ 0 ],
8129              url = $.data( a, "load.tabs" );
8130  
8131          this.abort();
8132  
8133          // not remote or from cache
8134          if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
8135              this.element.dequeue( "tabs" );
8136              return;
8137          }
8138  
8139          // load remote from here on
8140          this.lis.eq( index ).addClass( "ui-state-processing" );
8141  
8142          if ( o.spinner ) {
8143              var span = $( "span", a );
8144              span.data( "label.tabs", span.html() ).html( o.spinner );
8145          }
8146  
8147          this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
8148              url: url,
8149              success: function( r, s ) {
8150                  self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
8151  
8152                  // take care of tab labels
8153                  self._cleanup();
8154  
8155                  if ( o.cache ) {
8156                      $.data( a, "cache.tabs", true );
8157                  }
8158  
8159                  self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8160                  try {
8161                      o.ajaxOptions.success( r, s );
8162                  }
8163                  catch ( e ) {}
8164              },
8165              error: function( xhr, s, e ) {
8166                  // take care of tab labels
8167                  self._cleanup();
8168  
8169                  self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
8170                  try {
8171                      // Passing index avoid a race condition when this method is
8172                      // called after the user has selected another tab.
8173                      // Pass the anchor that initiated this request allows
8174                      // loadError to manipulate the tab content panel via $(a.hash)
8175                      o.ajaxOptions.error( xhr, s, index, a );
8176                  }
8177                  catch ( e ) {}
8178              }
8179          } ) );
8180  
8181          // last, so that load event is fired before show...
8182          self.element.dequeue( "tabs" );
8183  
8184          return this;
8185      },
8186  
8187      abort: function() {
8188          // stop possibly running animations
8189          this.element.queue( [] );
8190          this.panels.stop( false, true );
8191  
8192          // "tabs" queue must not contain more than two elements,
8193          // which are the callbacks for the latest clicked tab...
8194          this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
8195  
8196          // terminate pending requests from other tabs
8197          if ( this.xhr ) {
8198              this.xhr.abort();
8199              delete this.xhr;
8200          }
8201  
8202          // take care of tab labels
8203          this._cleanup();
8204          return this;
8205      },
8206  
8207      url: function( index, url ) {
8208          this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
8209          return this;
8210      },
8211  
8212      length: function() {
8213          return this.anchors.length;
8214      }
8215  });
8216  
8217  $.extend( $.ui.tabs, {
8218      version: "1.8.18"
8219  });
8220  
8221  /*
8222   * Tabs Extensions
8223   */
8224  
8225  /*
8226   * Rotate
8227   */
8228  $.extend( $.ui.tabs.prototype, {
8229      rotation: null,
8230      rotate: function( ms, continuing ) {
8231          var self = this,
8232              o = this.options;
8233  
8234          var rotate = self._rotate || ( self._rotate = function( e ) {
8235              clearTimeout( self.rotation );
8236              self.rotation = setTimeout(function() {
8237                  var t = o.selected;
8238                  self.select( ++t < self.anchors.length ? t : 0 );
8239              }, ms );
8240              
8241              if ( e ) {
8242                  e.stopPropagation();
8243              }
8244          });
8245  
8246          var stop = self._unrotate || ( self._unrotate = !continuing
8247              ? function(e) {
8248                  if (e.clientX) { // in case of a true click
8249                      self.rotate(null);
8250                  }
8251              }
8252              : function( e ) {
8253                  t = o.selected;
8254                  rotate();
8255              });
8256  
8257          // start rotation
8258          if ( ms ) {
8259              this.element.bind( "tabsshow", rotate );
8260              this.anchors.bind( o.event + ".tabs", stop );
8261              rotate();
8262          // stop rotation
8263          } else {
8264              clearTimeout( self.rotation );
8265              this.element.unbind( "tabsshow", rotate );
8266              this.anchors.unbind( o.event + ".tabs", stop );
8267              delete this._rotate;
8268              delete this._unrotate;
8269          }
8270  
8271          return this;
8272      }
8273  });
8274  
8275  })( jQuery );
8276  /*
8277   * jQuery UI Datepicker 1.8.18
8278   *
8279   * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
8280   * Dual licensed under the MIT or GPL Version 2 licenses.
8281   * http://jquery.org/license
8282   *
8283   * http://docs.jquery.com/UI/Datepicker
8284   *
8285   * Depends:
8286   *    jquery.ui.core.js
8287   */
8288  (function( $, undefined ) {
8289  
8290  $.extend($.ui, { datepicker: { version: "1.8.18" } });
8291  
8292  var PROP_NAME = 'datepicker';
8293  var dpuuid = new Date().getTime();
8294  var instActive;
8295  
8296  /* Date picker manager.
8297     Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8298     Settings for (groups of) date pickers are maintained in an instance object,
8299     allowing multiple different settings on the same page. */
8300  
8301  function Datepicker() {
8302      this.debug = false; // Change this to true to start debugging
8303      this._curInst = null; // The current instance in use
8304      this._keyEvent = false; // If the last event was a key event
8305      this._disabledInputs = []; // List of date picker inputs that have been disabled
8306      this._datepickerShowing = false; // True if the popup picker is showing , false if not
8307      this._inDialog = false; // True if showing within a "dialog", false if not
8308      this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
8309      this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
8310      this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
8311      this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
8312      this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
8313      this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8314      this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8315      this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
8316      this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8317      this.regional = []; // Available regional settings, indexed by language code
8318      this.regional[''] = { // Default regional settings
8319          closeText: 'Done', // Display text for close link
8320          prevText: 'Prev', // Display text for previous month link
8321          nextText: 'Next', // Display text for next month link
8322          currentText: 'Today', // Display text for current month link
8323          monthNames: ['January','February','March','April','May','June',
8324              'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8325          monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8326          dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8327          dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8328          dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8329          weekHeader: 'Wk', // Column header for week of the year
8330          dateFormat: 'mm/dd/yy', // See format options on parseDate
8331          firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8332          isRTL: false, // True if right-to-left language, false if left-to-right
8333          showMonthAfterYear: false, // True if the year select precedes month, false for month then year
8334          yearSuffix: '' // Additional text to append to the year in the month headers
8335      };
8336      this._defaults = { // Global defaults for all the date picker instances
8337          showOn: 'focus', // 'focus' for popup on focus,
8338              // 'button' for trigger button, or 'both' for either
8339          showAnim: 'fadeIn', // Name of jQuery animation for popup
8340          showOptions: {}, // Options for enhanced animations
8341          defaultDate: null, // Used when field is blank: actual date,
8342              // +/-number for offset from today, null for today
8343          appendText: '', // Display text following the input box, e.g. showing the format
8344          buttonText: '...', // Text for trigger button
8345          buttonImage: '', // URL for trigger button image
8346          buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
8347          hideIfNoPrevNext: false, // True to hide next/previous month links
8348              // if not applicable, false to just disable them
8349          navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
8350          gotoCurrent: false, // True if today link goes back to current selection instead
8351          changeMonth: false, // True if month can be selected directly, false if only prev/next
8352          changeYear: false, // True if year can be selected directly, false if only prev/next
8353          yearRange: 'c-10:c+10', // Range of years to display in drop-down,
8354              // either relative to today's year (-nn:+nn), relative to currently displayed year
8355              // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8356          showOtherMonths: false, // True to show dates in other months, false to leave blank
8357          selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
8358          showWeek: false, // True to show week of the year, false to not show it
8359          calculateWeek: this.iso8601Week, // How to calculate the week of the year,
8360              // takes a Date and returns the number of the week for it
8361          shortYearCutoff: '+10', // Short year values < this are in the current century,
8362              // > this are in the previous century,
8363              // string value starting with '+' for current year + value
8364          minDate: null, // The earliest selectable date, or null for no limit
8365          maxDate: null, // The latest selectable date, or null for no limit
8366          duration: 'fast', // Duration of display/closure
8367          beforeShowDay: null, // Function that takes a date and returns an array with
8368              // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8369              // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8370          beforeShow: null, // Function that takes an input field and
8371              // returns a set of custom settings for the date picker
8372          onSelect: null, // Define a callback function when a date is selected
8373          onChangeMonthYear: null, // Define a callback function when the month or year is changed
8374          onClose: null, // Define a callback function when the datepicker is closed
8375          numberOfMonths: 1, // Number of months to show at a time
8376          showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
8377          stepMonths: 1, // Number of months to step back/forward
8378          stepBigMonths: 12, // Number of months to step back/forward for the big links
8379          altField: '', // Selector for an alternate field to store selected dates into
8380          altFormat: '', // The date format to use for the alternate field
8381          constrainInput: true, // The input is constrained by the current date format
8382          showButtonPanel: false, // True to show button panel, false to not show it
8383          autoSize: false, // True to size the input for the date format, false to leave as is
8384          disabled: false // The initial disabled state
8385      };
8386      $.extend(this._defaults, this.regional['']);
8387      this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8388  }
8389  
8390  $.extend(Datepicker.prototype, {
8391      /* Class name added to elements to indicate already configured with a date picker. */
8392      markerClassName: 'hasDatepicker',
8393      
8394      //Keep track of the maximum number of rows displayed (see #7043)
8395      maxRows: 4,
8396  
8397      /* Debug logging (if enabled). */
8398      log: function () {
8399          if (this.debug)
8400              console.log.apply('', arguments);
8401      },
8402      
8403      // TODO rename to "widget" when switching to widget factory
8404      _widgetDatepicker: function() {
8405          return this.dpDiv;
8406      },
8407  
8408      /* Override the default settings for all instances of the date picker.
8409         @param  settings  object - the new settings to use as defaults (anonymous object)
8410         @return the manager object */
8411      setDefaults: function(settings) {
8412          extendRemove(this._defaults, settings || {});
8413          return this;
8414      },
8415  
8416      /* Attach the date picker to a jQuery selection.
8417         @param  target    element - the target input field or division or span
8418         @param  settings  object - the new settings to use for this date picker instance (anonymous) */
8419      _attachDatepicker: function(target, settings) {
8420          // check for settings on the control itself - in namespace 'date:'
8421          var inlineSettings = null;
8422          for (var attrName in this._defaults) {
8423              var attrValue = target.getAttribute('date:' + attrName);
8424              if (attrValue) {
8425                  inlineSettings = inlineSettings || {};
8426                  try {
8427                      inlineSettings[attrName] = eval(attrValue);
8428                  } catch (err) {
8429                      inlineSettings[attrName] = attrValue;
8430                  }
8431              }
8432          }
8433          var nodeName = target.nodeName.toLowerCase();
8434          var inline = (nodeName == 'div' || nodeName == 'span');
8435          if (!target.id) {
8436              this.uuid += 1;
8437              target.id = 'dp' + this.uuid;
8438          }
8439          var inst = this._newInst($(target), inline);
8440          inst.settings = $.extend({}, settings || {}, inlineSettings || {});
8441          if (nodeName == 'input') {
8442              this._connectDatepicker(target, inst);
8443          } else if (inline) {
8444              this._inlineDatepicker(target, inst);
8445          }
8446      },
8447  
8448      /* Create a new instance object. */
8449      _newInst: function(target, inline) {
8450          var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8451          return {id: id, input: target, // associated target
8452              selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
8453              drawMonth: 0, drawYear: 0, // month being drawn
8454              inline: inline, // is datepicker inline or not
8455              dpDiv: (!inline ? this.dpDiv : // presentation div
8456              bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8457      },
8458  
8459      /* Attach the date picker to an input field. */
8460      _connectDatepicker: function(target, inst) {
8461          var input = $(target);
8462          inst.append = $([]);
8463          inst.trigger = $([]);
8464          if (input.hasClass(this.markerClassName))
8465              return;
8466          this._attachments(input, inst);
8467          input.addClass(this.markerClassName).keydown(this._doKeyDown).
8468              keypress(this._doKeyPress).keyup(this._doKeyUp).
8469              bind("setData.datepicker", function(event, key, value) {
8470                  inst.settings[key] = value;
8471              }).bind("getData.datepicker", function(event, key) {
8472                  return this._get(inst, key);
8473              });
8474          this._autoSize(inst);
8475          $.data(target, PROP_NAME, inst);
8476          //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8477          if( inst.settings.disabled ) {
8478              this._disableDatepicker( target );
8479          }
8480      },
8481  
8482      /* Make attachments based on settings. */
8483      _attachments: function(input, inst) {
8484          var appendText = this._get(inst, 'appendText');
8485          var isRTL = this._get(inst, 'isRTL');
8486          if (inst.append)
8487              inst.append.remove();
8488          if (appendText) {
8489              inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
8490              input[isRTL ? 'before' : 'after'](inst.append);
8491          }
8492          input.unbind('focus', this._showDatepicker);
8493          if (inst.trigger)
8494              inst.trigger.remove();
8495          var showOn = this._get(inst, 'showOn');
8496          if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
8497              input.focus(this._showDatepicker);
8498          if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
8499              var buttonText = this._get(inst, 'buttonText');
8500              var buttonImage = this._get(inst, 'buttonImage');
8501              inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
8502                  $('<img/>').addClass(this._triggerClass).
8503                      attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
8504                  $('<button type="button"></button>').addClass(this._triggerClass).
8505                      html(buttonImage == '' ? buttonText : $('<img/>').attr(
8506                      { src:buttonImage, alt:buttonText, title:buttonText })));
8507              input[isRTL ? 'before' : 'after'](inst.trigger);
8508              inst.trigger.click(function() {
8509                  if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
8510                      $.datepicker._hideDatepicker();
8511                  else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
8512                      $.datepicker._hideDatepicker(); 
8513                      $.datepicker._showDatepicker(input[0]);
8514                  } else
8515                      $.datepicker._showDatepicker(input[0]);
8516                  return false;
8517              });
8518          }
8519      },
8520  
8521      /* Apply the maximum length for the date format. */
8522      _autoSize: function(inst) {
8523          if (this._get(inst, 'autoSize') && !inst.inline) {
8524              var date = new Date(2009, 12 - 1, 20); // Ensure double digits
8525              var dateFormat = this._get(inst, 'dateFormat');
8526              if (dateFormat.match(/[DM]/)) {
8527                  var findMax = function(names) {
8528                      var max = 0;
8529                      var maxI = 0;
8530                      for (var i = 0; i < names.length; i++) {
8531                          if (names[i].length > max) {
8532                              max = names[i].length;
8533                              maxI = i;
8534                          }
8535                      }
8536                      return maxI;
8537                  };
8538                  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
8539                      'monthNames' : 'monthNamesShort'))));
8540                  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
8541                      'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
8542              }
8543              inst.input.attr('size', this._formatDate(inst, date).length);
8544          }
8545      },
8546  
8547      /* Attach an inline date picker to a div. */
8548      _inlineDatepicker: function(target, inst) {
8549          var divSpan = $(target);
8550          if (divSpan.hasClass(this.markerClassName))
8551              return;
8552          divSpan.addClass(this.markerClassName).append(inst.dpDiv).
8553              bind("setData.datepicker", function(event, key, value){
8554                  inst.settings[key] = value;
8555              }).bind("getData.datepicker", function(event, key){
8556                  return this._get(inst, key);
8557              });
8558          $.data(target, PROP_NAME, inst);
8559          this._setDate(inst, this._getDefaultDate(inst), true);
8560          this._updateDatepicker(inst);
8561          this._updateAlternate(inst);
8562          //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8563          if( inst.settings.disabled ) {
8564              this._disableDatepicker( target );
8565          }
8566          // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8567          // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8568          inst.dpDiv.css( "display", "block" );
8569      },
8570  
8571      /* Pop-up the date picker in a "dialog" box.
8572         @param  input     element - ignored
8573         @param  date      string or Date - the initial date to display
8574         @param  onSelect  function - the function to call when a date is selected
8575         @param  settings  object - update the dialog date picker instance's settings (anonymous object)
8576         @param  pos       int[2] - coordinates for the dialog's position within the screen or
8577                           event - with x/y coordinates or
8578                           leave empty for default (screen centre)
8579         @return the manager object */
8580      _dialogDatepicker: function(input, date, onSelect, settings, pos) {
8581          var inst = this._dialogInst; // internal instance
8582          if (!inst) {
8583              this.uuid += 1;
8584              var id = 'dp' + this.uuid;
8585              this._dialogInput = $('<input type="text" id="' + id +
8586                  '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8587              this._dialogInput.keydown(this._doKeyDown);
8588              $('body').append(this._dialogInput);
8589              inst = this._dialogInst = this._newInst(this._dialogInput, false);
8590              inst.settings = {};
8591              $.data(this._dialogInput[0], PROP_NAME, inst);
8592          }
8593          extendRemove(inst.settings, settings || {});
8594          date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
8595          this._dialogInput.val(date);
8596  
8597          this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
8598          if (!this._pos) {
8599              var browserWidth = document.documentElement.clientWidth;
8600              var browserHeight = document.documentElement.clientHeight;
8601              var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
8602              var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
8603              this._pos = // should use actual width/height below
8604                  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
8605          }
8606  
8607          // move input on screen for focus, but hidden behind dialog
8608          this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
8609          inst.settings.onSelect = onSelect;
8610          this._inDialog = true;
8611          this.dpDiv.addClass(this._dialogClass);
8612          this._showDatepicker(this._dialogInput[0]);
8613          if ($.blockUI)
8614              $.blockUI(this.dpDiv);
8615          $.data(this._dialogInput[0], PROP_NAME, inst);
8616          return this;
8617      },
8618  
8619      /* Detach a datepicker from its control.
8620         @param  target    element - the target input field or division or span */
8621      _destroyDatepicker: function(target) {
8622          var $target = $(target);
8623          var inst = $.data(target, PROP_NAME);
8624          if (!$target.hasClass(this.markerClassName)) {
8625              return;
8626          }
8627          var nodeName = target.nodeName.toLowerCase();
8628          $.removeData(target, PROP_NAME);
8629          if (nodeName == 'input') {
8630              inst.append.remove();
8631              inst.trigger.remove();
8632              $target.removeClass(this.markerClassName).
8633                  unbind('focus', this._showDatepicker).
8634                  unbind('keydown', this._doKeyDown).
8635                  unbind('keypress', this._doKeyPress).
8636                  unbind('keyup', this._doKeyUp);
8637          } else if (nodeName == 'div' || nodeName == 'span')
8638              $target.removeClass(this.markerClassName).empty();
8639      },
8640  
8641      /* Enable the date picker to a jQuery selection.
8642         @param  target    element - the target input field or division or span */
8643      _enableDatepicker: function(target) {
8644          var $target = $(target);
8645          var inst = $.data(target, PROP_NAME);
8646          if (!$target.hasClass(this.markerClassName)) {
8647              return;
8648          }
8649          var nodeName = target.nodeName.toLowerCase();
8650          if (nodeName == 'input') {
8651              target.disabled = false;
8652              inst.trigger.filter('button').
8653                  each(function() { this.disabled = false; }).end().
8654                  filter('img').css({opacity: '1.0', cursor: ''});
8655          }
8656          else if (nodeName == 'div' || nodeName == 'span') {
8657              var inline = $target.children('.' + this._inlineClass);
8658              inline.children().removeClass('ui-state-disabled');
8659              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8660                  removeAttr("disabled");
8661          }
8662          this._disabledInputs = $.map(this._disabledInputs,
8663              function(value) { return (value == target ? null : value); }); // delete entry
8664      },
8665  
8666      /* Disable the date picker to a jQuery selection.
8667         @param  target    element - the target input field or division or span */
8668      _disableDatepicker: function(target) {
8669          var $target = $(target);
8670          var inst = $.data(target, PROP_NAME);
8671          if (!$target.hasClass(this.markerClassName)) {
8672              return;
8673          }
8674          var nodeName = target.nodeName.toLowerCase();
8675          if (nodeName == 'input') {
8676              target.disabled = true;
8677              inst.trigger.filter('button').
8678                  each(function() { this.disabled = true; }).end().
8679                  filter('img').css({opacity: '0.5', cursor: 'default'});
8680          }
8681          else if (nodeName == 'div' || nodeName == 'span') {
8682              var inline = $target.children('.' + this._inlineClass);
8683              inline.children().addClass('ui-state-disabled');
8684              inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8685                  attr("disabled", "disabled");
8686          }
8687          this._disabledInputs = $.map(this._disabledInputs,
8688              function(value) { return (value == target ? null : value); }); // delete entry
8689          this._disabledInputs[this._disabledInputs.length] = target;
8690      },
8691  
8692      /* Is the first field in a jQuery collection disabled as a datepicker?
8693         @param  target    element - the target input field or division or span
8694         @return boolean - true if disabled, false if enabled */
8695      _isDisabledDatepicker: function(target) {
8696          if (!target) {
8697              return false;
8698          }
8699          for (var i = 0; i < this._disabledInputs.length; i++) {
8700              if (this._disabledInputs[i] == target)
8701                  return true;
8702          }
8703          return false;
8704      },
8705  
8706      /* Retrieve the instance data for the target control.
8707         @param  target  element - the target input field or division or span
8708         @return  object - the associated instance data
8709         @throws  error if a jQuery problem getting data */
8710      _getInst: function(target) {
8711          try {
8712              return $.data(target, PROP_NAME);
8713          }
8714          catch (err) {
8715              throw 'Missing instance data for this datepicker';
8716          }
8717      },
8718  
8719      /* Update or retrieve the settings for a date picker attached to an input field or division.
8720         @param  target  element - the target input field or division or span
8721         @param  name    object - the new settings to update or
8722                         string - the name of the setting to change or retrieve,
8723                         when retrieving also 'all' for all instance settings or
8724                         'defaults' for all global defaults
8725         @param  value   any - the new value for the setting
8726                         (omit if above is an object or to retrieve a value) */
8727      _optionDatepicker: function(target, name, value) {
8728          var inst = this._getInst(target);
8729          if (arguments.length == 2 && typeof name == 'string') {
8730              return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
8731                  (inst ? (name == 'all' ? $.extend({}, inst.settings) :
8732                  this._get(inst, name)) : null));
8733          }
8734          var settings = name || {};
8735          if (typeof name == 'string') {
8736              settings = {};
8737              settings[name] = value;
8738          }
8739          if (inst) {
8740              if (this._curInst == inst) {
8741                  this._hideDatepicker();
8742              }
8743              var date = this._getDateDatepicker(target, true);
8744              var minDate = this._getMinMaxDate(inst, 'min');
8745              var maxDate = this._getMinMaxDate(inst, 'max');
8746              extendRemove(inst.settings, settings);
8747              // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8748              if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
8749                  inst.settings.minDate = this._formatDate(inst, minDate);
8750              if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
8751                  inst.settings.maxDate = this._formatDate(inst, maxDate);
8752              this._attachments($(target), inst);
8753              this._autoSize(inst);
8754              this._setDate(inst, date);
8755              this._updateAlternate(inst);
8756              this._updateDatepicker(inst);
8757          }
8758      },
8759  
8760      // change method deprecated
8761      _changeDatepicker: function(target, name, value) {
8762          this._optionDatepicker(target, name, value);
8763      },
8764  
8765      /* Redraw the date picker attached to an input field or division.
8766         @param  target  element - the target input field or division or span */
8767      _refreshDatepicker: function(target) {
8768          var inst = this._getInst(target);
8769          if (inst) {
8770              this._updateDatepicker(inst);
8771          }
8772      },
8773  
8774      /* Set the dates for a jQuery selection.
8775         @param  target   element - the target input field or division or span
8776         @param  date     Date - the new date */
8777      _setDateDatepicker: function(target, date) {
8778          var inst = this._getInst(target);
8779          if (inst) {
8780              this._setDate(inst, date);
8781              this._updateDatepicker(inst);
8782              this._updateAlternate(inst);
8783          }
8784      },
8785  
8786      /* Get the date(s) for the first entry in a jQuery selection.
8787         @param  target     element - the target input field or division or span
8788         @param  noDefault  boolean - true if no default date is to be used
8789         @return Date - the current date */
8790      _getDateDatepicker: function(target, noDefault) {
8791          var inst = this._getInst(target);
8792          if (inst && !inst.inline)
8793              this._setDateFromField(inst, noDefault);
8794          return (inst ? this._getDate(inst) : null);
8795      },
8796  
8797      /* Handle keystrokes. */
8798      _doKeyDown: function(event) {
8799          var inst = $.datepicker._getInst(event.target);
8800          var handled = true;
8801          var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
8802          inst._keyEvent = true;
8803          if ($.datepicker._datepickerShowing)
8804              switch (event.keyCode) {
8805                  case 9: $.datepicker._hideDatepicker();
8806                          handled = false;
8807                          break; // hide on tab out
8808                  case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
8809                                      $.datepicker._currentClass + ')', inst.dpDiv);
8810                          if (sel[0])
8811                              $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8812                              var onSelect = $.datepicker._get(inst, 'onSelect');
8813                              if (onSelect) {
8814                                  var dateStr = $.datepicker._formatDate(inst);
8815  
8816                                  // trigger custom callback
8817                                  onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8818                              }
8819                          else
8820                              $.datepicker._hideDatepicker();
8821                          return false; // don't submit the form
8822                          break; // select the value on enter
8823                  case 27: $.datepicker._hideDatepicker();
8824                          break; // hide on escape
8825                  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8826                              -$.datepicker._get(inst, 'stepBigMonths') :
8827                              -$.datepicker._get(inst, 'stepMonths')), 'M');
8828                          break; // previous month/year on page up/+ ctrl
8829                  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8830                              +$.datepicker._get(inst, 'stepBigMonths') :
8831                              +$.datepicker._get(inst, 'stepMonths')), 'M');
8832                          break; // next month/year on page down/+ ctrl
8833                  case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
8834                          handled = event.ctrlKey || event.metaKey;
8835                          break; // clear on ctrl or command +end
8836                  case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
8837                          handled = event.ctrlKey || event.metaKey;
8838                          break; // current on ctrl or command +home
8839                  case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
8840                          handled = event.ctrlKey || event.metaKey;
8841                          // -1 day on ctrl or command +left
8842                          if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8843                                      -$.datepicker._get(inst, 'stepBigMonths') :
8844                                      -$.datepicker._get(inst, 'stepMonths')), 'M');
8845                          // next month/year on alt +left on Mac
8846                          break;
8847                  case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
8848                          handled = event.ctrlKey || event.metaKey;
8849                          break; // -1 week on ctrl or command +up
8850                  case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
8851                          handled = event.ctrlKey || event.metaKey;
8852                          // +1 day on ctrl or command +right
8853                          if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8854                                      +$.datepicker._get(inst, 'stepBigMonths') :
8855                                      +$.datepicker._get(inst, 'stepMonths')), 'M');
8856                          // next month/year on alt +right
8857                          break;
8858                  case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
8859                          handled = event.ctrlKey || event.metaKey;
8860                          break; // +1 week on ctrl or command +down
8861                  default: handled = false;
8862              }
8863          else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
8864              $.datepicker._showDatepicker(this);
8865          else {
8866              handled = false;
8867          }
8868          if (handled) {
8869              event.preventDefault();
8870              event.stopPropagation();
8871          }
8872      },
8873  
8874      /* Filter entered characters - based on date format. */
8875      _doKeyPress: function(event) {
8876          var inst = $.datepicker._getInst(event.target);
8877          if ($.datepicker._get(inst, 'constrainInput')) {
8878              var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
8879              var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
8880              return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
8881          }
8882      },
8883  
8884      /* Synchronise manual entry and field/alternate field. */
8885      _doKeyUp: function(event) {
8886          var inst = $.datepicker._getInst(event.target);
8887          if (inst.input.val() != inst.lastVal) {
8888              try {
8889                  var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8890                      (inst.input ? inst.input.val() : null),
8891                      $.datepicker._getFormatConfig(inst));
8892                  if (date) { // only if valid
8893                      $.datepicker._setDateFromField(inst);
8894                      $.datepicker._updateAlternate(inst);
8895                      $.datepicker._updateDatepicker(inst);
8896                  }
8897              }
8898              catch (event) {
8899                  $.datepicker.log(event);
8900              }
8901          }
8902          return true;
8903      },
8904  
8905      /* Pop-up the date picker for a given input field.
8906         If false returned from beforeShow event handler do not show. 
8907         @param  input  element - the input field attached to the date picker or
8908                        event - if triggered by focus */
8909      _showDatepicker: function(input) {
8910          input = input.target || input;
8911          if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
8912              input = $('input', input.parentNode)[0];
8913          if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
8914              return;
8915          var inst = $.datepicker._getInst(input);
8916          if ($.datepicker._curInst && $.datepicker._curInst != inst) {
8917              $.datepicker._curInst.dpDiv.stop(true, true);
8918              if ( inst && $.datepicker._datepickerShowing ) {
8919                  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8920              }
8921          }
8922          var beforeShow = $.datepicker._get(inst, 'beforeShow');
8923          var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8924          if(beforeShowSettings === false){
8925              //false
8926              return;
8927          }
8928          extendRemove(inst.settings, beforeShowSettings);
8929          inst.lastVal = null;
8930          $.datepicker._lastInput = input;
8931          $.datepicker._setDateFromField(inst);
8932          if ($.datepicker._inDialog) // hide cursor
8933              input.value = '';
8934          if (!$.datepicker._pos) { // position below input
8935              $.datepicker._pos = $.datepicker._findPos(input);
8936              $.datepicker._pos[1] += input.offsetHeight; // add the height
8937          }
8938          var isFixed = false;
8939          $(input).parents().each(function() {
8940              isFixed |= $(this).css('position') == 'fixed';
8941              return !isFixed;
8942          });
8943          if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
8944              $.datepicker._pos[0] -= document.documentElement.scrollLeft;
8945              $.datepicker._pos[1] -= document.documentElement.scrollTop;
8946          }
8947          var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8948          $.datepicker._pos = null;
8949          //to avoid flashes on Firefox
8950          inst.dpDiv.empty();
8951          // determine sizing offscreen
8952          inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
8953          $.datepicker._updateDatepicker(inst);
8954          // fix width for dynamic number of date pickers
8955          // and adjust position before showing
8956          offset = $.datepicker._checkOffset(inst, offset, isFixed);
8957          inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8958              'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
8959              left: offset.left + 'px', top: offset.top + 'px'});
8960          if (!inst.inline) {
8961              var showAnim = $.datepicker._get(inst, 'showAnim');
8962              var duration = $.datepicker._get(inst, 'duration');
8963              var postProcess = function() {
8964                  var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8965                  if( !! cover.length ){
8966                      var borders = $.datepicker._getBorders(inst.dpDiv);
8967                      cover.css({left: -borders[0], top: -borders[1],
8968                          width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
8969                  }
8970              };
8971              inst.dpDiv.zIndex($(input).zIndex()+1);
8972              $.datepicker._datepickerShowing = true;
8973              if ($.effects && $.effects[showAnim])
8974                  inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8975              else
8976                  inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
8977              if (!showAnim || !duration)
8978                  postProcess();
8979              if (inst.input.is(':visible') && !inst.input.is(':disabled'))
8980                  inst.input.focus();
8981              $.datepicker._curInst = inst;
8982          }
8983      },
8984  
8985      /* Generate the date picker content. */
8986      _updateDatepicker: function(inst) {
8987          var self = this;
8988          self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8989          var borders = $.datepicker._getBorders(inst.dpDiv);
8990          instActive = inst; // for delegate hover events
8991          inst.dpDiv.empty().append(this._generateHTML(inst));
8992          var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
8993          if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
8994              cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
8995          }
8996          inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
8997          var numMonths = this._getNumberOfMonths(inst);
8998          var cols = numMonths[1];
8999          var width = 17;
9000          inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
9001          if (cols > 1)
9002              inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
9003          inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
9004              'Class']('ui-datepicker-multi');
9005          inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
9006              'Class']('ui-datepicker-rtl');
9007          if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
9008                  // #6694 - don't focus the input if it's already focused
9009                  // this breaks the change event in IE
9010                  inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
9011              inst.input.focus();
9012          // deffered render of the years select (to avoid flashes on Firefox) 
9013          if( inst.yearshtml ){
9014              var origyearshtml = inst.yearshtml;
9015              setTimeout(function(){
9016                  //assure that inst.yearshtml didn't change.
9017                  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
9018                      inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
9019                  }
9020                  origyearshtml = inst.yearshtml = null;
9021              }, 0);
9022          }
9023      },
9024  
9025      /* Retrieve the size of left and top borders for an element.
9026         @param  elem  (jQuery object) the element of interest
9027         @return  (number[2]) the left and top borders */
9028      _getBorders: function(elem) {
9029          var convert = function(value) {
9030              return {thin: 1, medium: 2, thick: 3}[value] || value;
9031          };
9032          return [parseFloat(convert(elem.css('border-left-width'))),
9033              parseFloat(convert(elem.css('border-top-width')))];
9034      },
9035  
9036      /* Check positioning to remain on screen. */
9037      _checkOffset: function(inst, offset, isFixed) {
9038          var dpWidth = inst.dpDiv.outerWidth();
9039          var dpHeight = inst.dpDiv.outerHeight();
9040          var inputWidth = inst.input ? inst.input.outerWidth() : 0;
9041          var inputHeight = inst.input ? inst.input.outerHeight() : 0;
9042          var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
9043          var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
9044  
9045          offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
9046          offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
9047          offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
9048  
9049          // now check if datepicker is showing outside window viewport - move to a better place if so.
9050          offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
9051              Math.abs(offset.left + dpWidth - viewWidth) : 0);
9052          offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
9053              Math.abs(dpHeight + inputHeight) : 0);
9054  
9055          return offset;
9056      },
9057  
9058      /* Find an object's position on the screen. */
9059      _findPos: function(obj) {
9060          var inst = this._getInst(obj);
9061          var isRTL = this._get(inst, 'isRTL');
9062          while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
9063              obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
9064          }
9065          var position = $(obj).offset();
9066          return [position.left, position.top];
9067      },
9068  
9069      /* Hide the date picker from view.
9070         @param  input  element - the input field attached to the date picker */
9071      _hideDatepicker: function(input) {
9072          var inst = this._curInst;
9073          if (!inst || (input && inst != $.data(input, PROP_NAME)))
9074              return;
9075          if (this._datepickerShowing) {
9076              var showAnim = this._get(inst, 'showAnim');
9077              var duration = this._get(inst, 'duration');
9078              var self = this;
9079              var postProcess = function() {
9080                  $.datepicker._tidyDialog(inst);
9081                  self._curInst = null;
9082              };
9083              if ($.effects && $.effects[showAnim])
9084                  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
9085              else
9086                  inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
9087                      (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
9088              if (!showAnim)
9089                  postProcess();
9090              this._datepickerShowing = false;
9091              var onClose = this._get(inst, 'onClose');
9092              if (onClose)
9093                  onClose.apply((inst.input ? inst.input[0] : null),
9094                      [(inst.input ? inst.input.val() : ''), inst]);
9095              this._lastInput = null;
9096              if (this._inDialog) {
9097                  this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
9098                  if ($.blockUI) {
9099                      $.unblockUI();
9100                      $('body').append(this.dpDiv);
9101                  }
9102              }
9103              this._inDialog = false;
9104          }
9105      },
9106  
9107      /* Tidy up after a dialog display. */
9108      _tidyDialog: function(inst) {
9109          inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
9110      },
9111  
9112      /* Close date picker if clicked elsewhere. */
9113      _checkExternalClick: function(event) {
9114          if (!$.datepicker._curInst)
9115              return;
9116  
9117          var $target = $(event.target),
9118              inst = $.datepicker._getInst($target[0]);
9119  
9120          if ( ( ( $target[0].id != $.datepicker._mainDivId &&
9121                  $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
9122                  !$target.hasClass($.datepicker.markerClassName) &&
9123                  !$target.closest("." + $.datepicker._triggerClass).length &&
9124                  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
9125              ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
9126              $.datepicker._hideDatepicker();
9127      },
9128  
9129      /* Adjust one of the date sub-fields. */
9130      _adjustDate: function(id, offset, period) {
9131          var target = $(id);
9132          var inst = this._getInst(target[0]);
9133          if (this._isDisabledDatepicker(target[0])) {
9134              return;
9135          }
9136          this._adjustInstDate(inst, offset +
9137              (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
9138              period);
9139          this._updateDatepicker(inst);
9140      },
9141  
9142      /* Action for current link. */
9143      _gotoToday: function(id) {
9144          var target = $(id);
9145          var inst = this._getInst(target[0]);
9146          if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
9147              inst.selectedDay = inst.currentDay;
9148              inst.drawMonth = inst.selectedMonth = inst.currentMonth;
9149              inst.drawYear = inst.selectedYear = inst.currentYear;
9150          }
9151          else {
9152              var date = new Date();
9153              inst.selectedDay = date.getDate();
9154              inst.drawMonth = inst.selectedMonth = date.getMonth();
9155              inst.drawYear = inst.selectedYear = date.getFullYear();
9156          }
9157          this._notifyChange(inst);
9158          this._adjustDate(target);
9159      },
9160  
9161      /* Action for selecting a new month/year. */
9162      _selectMonthYear: function(id, select, period) {
9163          var target = $(id);
9164          var inst = this._getInst(target[0]);
9165          inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9166          inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9167              parseInt(select.options[select.selectedIndex].value,10);
9168          this._notifyChange(inst);
9169          this._adjustDate(target);
9170      },
9171  
9172      /* Action for selecting a day. */
9173      _selectDay: function(id, month, year, td) {
9174          var target = $(id);
9175          if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
9176              return;
9177          }
9178          var inst = this._getInst(target[0]);
9179          inst.selectedDay = inst.currentDay = $('a', td).html();
9180          inst.selectedMonth = inst.currentMonth = month;
9181          inst.selectedYear = inst.currentYear = year;
9182          this._selectDate(id, this._formatDate(inst,
9183              inst.currentDay, inst.currentMonth, inst.currentYear));
9184      },
9185  
9186      /* Erase the input field and hide the date picker. */
9187      _clearDate: function(id) {
9188          var target = $(id);
9189          var inst = this._getInst(target[0]);
9190          this._selectDate(target, '');
9191      },
9192  
9193      /* Update the input field with the selected date. */
9194      _selectDate: function(id, dateStr) {
9195          var target = $(id);
9196          var inst = this._getInst(target[0]);
9197          dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
9198          if (inst.input)
9199              inst.input.val(dateStr);
9200          this._updateAlternate(inst);
9201          var onSelect = this._get(inst, 'onSelect');
9202          if (onSelect)
9203              onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
9204          else if (inst.input)
9205              inst.input.trigger('change'); // fire the change event
9206          if (inst.inline)
9207              this._updateDatepicker(inst);
9208          else {
9209              this._hideDatepicker();
9210              this._lastInput = inst.input[0];
9211              if (typeof(inst.input[0]) != 'object')
9212                  inst.input.focus(); // restore focus
9213              this._lastInput = null;
9214          }
9215      },
9216  
9217      /* Update any alternate field to synchronise with the main field. */
9218      _updateAlternate: function(inst) {
9219          var altField = this._get(inst, 'altField');
9220          if (altField) { // update alternate field too
9221              var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
9222              var date = this._getDate(inst);
9223              var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
9224              $(altField).each(function() { $(this).val(dateStr); });
9225          }
9226      },
9227  
9228      /* Set as beforeShowDay function to prevent selection of weekends.
9229         @param  date  Date - the date to customise
9230         @return [boolean, string] - is this date selectable?, what is its CSS class? */
9231      noWeekends: function(date) {
9232          var day = date.getDay();
9233          return [(day > 0 && day < 6), ''];
9234      },
9235  
9236      /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9237         @param  date  Date - the date to get the week for
9238         @return  number - the number of the week within the year that contains this date */
9239      iso8601Week: function(date) {
9240          var checkDate = new Date(date.getTime());
9241          // Find Thursday of this week starting on Monday
9242          checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
9243          var time = checkDate.getTime();
9244          checkDate.setMonth(0); // Compare with Jan 1
9245          checkDate.setDate(1);
9246          return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
9247      },
9248  
9249      /* Parse a string value into a date object.
9250         See formatDate below for the possible formats.
9251  
9252         @param  format    string - the expected format of the date
9253         @param  value     string - the date in the above format
9254         @param  settings  Object - attributes include:
9255                           shortYearCutoff  number - the cutoff year for determining the century (optional)
9256                           dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9257                           dayNames         string[7] - names of the days from Sunday (optional)
9258                           monthNamesShort  string[12] - abbreviated names of the months (optional)
9259                           monthNames       string[12] - names of the months (optional)
9260         @return  Date - the extracted date value or null if value is blank */
9261      parseDate: function (format, value, settings) {
9262          if (format == null || value == null)
9263              throw 'Invalid arguments';
9264          value = (typeof value == 'object' ? value.toString() : value + '');
9265          if (value == '')
9266              return null;
9267          var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
9268          shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
9269                  new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9270          var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9271          var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9272          var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9273          var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9274          var year = -1;
9275          var month = -1;
9276          var day = -1;
9277          var doy = -1;
9278          var literal = false;
9279          // Check whether a format character is doubled
9280          var lookAhead = function(match) {
9281              var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9282              if (matches)
9283                  iFormat++;
9284              return matches;
9285          };
9286          // Extract a number from the string value
9287          var getNumber = function(match) {
9288              var isDoubled = lookAhead(match);
9289              var size = (match == '@' ? 14 : (match == '!' ? 20 :
9290                  (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
9291              var digits = new RegExp('^\\d{1,' + size + '}');
9292              var num = value.substring(iValue).match(digits);
9293              if (!num)
9294                  throw 'Missing number at position ' + iValue;
9295              iValue += num[0].length;
9296              return parseInt(num[0], 10);
9297          };
9298          // Extract a name from the string value and convert to an index
9299          var getName = function(match, shortNames, longNames) {
9300              var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
9301                  return [ [k, v] ];
9302              }).sort(function (a, b) {
9303                  return -(a[1].length - b[1].length);
9304              });
9305              var index = -1;
9306              $.each(names, function (i, pair) {
9307                  var name = pair[1];
9308                  if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
9309                      index = pair[0];
9310                      iValue += name.length;
9311                      return false;
9312                  }
9313              });
9314              if (index != -1)
9315                  return index + 1;
9316              else
9317                  throw 'Unknown name at position ' + iValue;
9318          };
9319          // Confirm that a literal character matches the string value
9320          var checkLiteral = function() {
9321              if (value.charAt(iValue) != format.charAt(iFormat))
9322                  throw 'Unexpected literal at position ' + iValue;
9323              iValue++;
9324          };
9325          var iValue = 0;
9326          for (var iFormat = 0; iFormat < format.length; iFormat++) {
9327              if (literal)
9328                  if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9329                      literal = false;
9330                  else
9331                      checkLiteral();
9332              else
9333                  switch (format.charAt(iFormat)) {
9334                      case 'd':
9335                          day = getNumber('d');
9336                          break;
9337                      case 'D':
9338                          getName('D', dayNamesShort, dayNames);
9339                          break;
9340                      case 'o':
9341                          doy = getNumber('o');
9342                          break;
9343                      case 'm':
9344                          month = getNumber('m');
9345                          break;
9346                      case 'M':
9347                          month = getName('M', monthNamesShort, monthNames);
9348                          break;
9349                      case 'y':
9350                          year = getNumber('y');
9351                          break;
9352                      case '@':
9353                          var date = new Date(getNumber('@'));
9354                          year = date.getFullYear();
9355                          month = date.getMonth() + 1;
9356                          day = date.getDate();
9357                          break;
9358                      case '!':
9359                          var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
9360                          year = date.getFullYear();
9361                          month = date.getMonth() + 1;
9362                          day = date.getDate();
9363                          break;
9364                      case "'":
9365                          if (lookAhead("'"))
9366                              checkLiteral();
9367                          else
9368                              literal = true;
9369                          break;
9370                      default:
9371                          checkLiteral();
9372                  }
9373          }
9374          if (iValue < value.length){
9375              throw "Extra/unparsed characters found in date: " + value.substring(iValue);
9376          }
9377          if (year == -1)
9378              year = new Date().getFullYear();
9379          else if (year < 100)
9380              year += new Date().getFullYear() - new Date().getFullYear() % 100 +
9381                  (year <= shortYearCutoff ? 0 : -100);
9382          if (doy > -1) {
9383              month = 1;
9384              day = doy;
9385              do {
9386                  var dim = this._getDaysInMonth(year, month - 1);
9387                  if (day <= dim)
9388                      break;
9389                  month++;
9390                  day -= dim;
9391              } while (true);
9392          }
9393          var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
9394          if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
9395              throw 'Invalid date'; // E.g. 31/02/00
9396          return date;
9397      },
9398  
9399      /* Standard date formats. */
9400      ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9401      COOKIE: 'D, dd M yy',
9402      ISO_8601: 'yy-mm-dd',
9403      RFC_822: 'D, d M y',
9404      RFC_850: 'DD, dd-M-y',
9405      RFC_1036: 'D, d M y',
9406      RFC_1123: 'D, d M yy',
9407      RFC_2822: 'D, d M yy',
9408      RSS: 'D, d M y', // RFC 822
9409      TICKS: '!',
9410      TIMESTAMP: '@',
9411      W3C: 'yy-mm-dd', // ISO 8601
9412  
9413      _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
9414          Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9415  
9416      /* Format a date object into a string value.
9417         The format can be combinations of the following:
9418         d  - day of month (no leading zero)
9419         dd - day of month (two digit)
9420         o  - day of year (no leading zeros)
9421         oo - day of year (three digit)
9422         D  - day name short
9423         DD - day name long
9424         m  - month of year (no leading zero)
9425         mm - month of year (two digit)
9426         M  - month name short
9427         MM - month name long
9428         y  - year (two digit)
9429         yy - year (four digit)
9430         @ - Unix timestamp (ms since 01/01/1970)
9431         ! - Windows ticks (100ns since 01/01/0001)
9432         '...' - literal text
9433         '' - single quote
9434  
9435         @param  format    string - the desired format of the date
9436         @param  date      Date - the date value to format
9437         @param  settings  Object - attributes include:
9438                           dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
9439                           dayNames         string[7] - names of the days from Sunday (optional)
9440                           monthNamesShort  string[12] - abbreviated names of the months (optional)
9441                           monthNames       string[12] - names of the months (optional)
9442         @return  string - the date in the above format */
9443      formatDate: function (format, date, settings) {
9444          if (!date)
9445              return '';
9446          var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
9447          var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
9448          var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
9449          var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
9450          // Check whether a format character is doubled
9451          var lookAhead = function(match) {
9452              var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9453              if (matches)
9454                  iFormat++;
9455              return matches;
9456          };
9457          // Format a number, with leading zero if necessary
9458          var formatNumber = function(match, value, len) {
9459              var num = '' + value;
9460              if (lookAhead(match))
9461                  while (num.length < len)
9462                      num = '0' + num;
9463              return num;
9464          };
9465          // Format a name, short or long as requested
9466          var formatName = function(match, value, shortNames, longNames) {
9467              return (lookAhead(match) ? longNames[value] : shortNames[value]);
9468          };
9469          var output = '';
9470          var literal = false;
9471          if (date)
9472              for (var iFormat = 0; iFormat < format.length; iFormat++) {
9473                  if (literal)
9474                      if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9475                          literal = false;
9476                      else
9477                          output += format.charAt(iFormat);
9478                  else
9479                      switch (format.charAt(iFormat)) {
9480                          case 'd':
9481                              output += formatNumber('d', date.getDate(), 2);
9482                              break;
9483                          case 'D':
9484                              output += formatName('D', date.getDay(), dayNamesShort, dayNames);
9485                              break;
9486                          case 'o':
9487                              output += formatNumber('o',
9488                                  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9489                              break;
9490                          case 'm':
9491                              output += formatNumber('m', date.getMonth() + 1, 2);
9492                              break;
9493                          case 'M':
9494                              output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
9495                              break;
9496                          case 'y':
9497                              output += (lookAhead('y') ? date.getFullYear() :
9498                                  (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
9499                              break;
9500                          case '@':
9501                              output += date.getTime();
9502                              break;
9503                          case '!':
9504                              output += date.getTime() * 10000 + this._ticksTo1970;
9505                              break;
9506                          case "'":
9507                              if (lookAhead("'"))
9508                                  output += "'";
9509                              else
9510                                  literal = true;
9511                              break;
9512                          default:
9513                              output += format.charAt(iFormat);
9514                      }
9515              }
9516          return output;
9517      },
9518  
9519      /* Extract all possible characters from the date format. */
9520      _possibleChars: function (format) {
9521          var chars = '';
9522          var literal = false;
9523          // Check whether a format character is doubled
9524          var lookAhead = function(match) {
9525              var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
9526              if (matches)
9527                  iFormat++;
9528              return matches;
9529          };
9530          for (var iFormat = 0; iFormat < format.length; iFormat++)
9531              if (literal)
9532                  if (format.charAt(iFormat) == "'" && !lookAhead("'"))
9533                      literal = false;
9534                  else
9535                      chars += format.charAt(iFormat);
9536              else
9537                  switch (format.charAt(iFormat)) {
9538                      case 'd': case 'm': case 'y': case '@':
9539                          chars += '0123456789';
9540                          break;
9541                      case 'D': case 'M':
9542                          return null; // Accept anything
9543                      case "'":
9544                          if (lookAhead("'"))
9545                              chars += "'";
9546                          else
9547                              literal = true;
9548                          break;
9549                      default:
9550                          chars += format.charAt(iFormat);
9551                  }
9552          return chars;
9553      },
9554  
9555      /* Get a setting value, defaulting if necessary. */
9556      _get: function(inst, name) {
9557          return inst.settings[name] !== undefined ?
9558              inst.settings[name] : this._defaults[name];
9559      },
9560  
9561      /* Parse existing date and initialise date picker. */
9562      _setDateFromField: function(inst, noDefault) {
9563          if (inst.input.val() == inst.lastVal) {
9564              return;
9565          }
9566          var dateFormat = this._get(inst, 'dateFormat');
9567          var dates = inst.lastVal = inst.input ? inst.input.val() : null;
9568          var date, defaultDate;
9569          date = defaultDate = this._getDefaultDate(inst);
9570          var settings = this._getFormatConfig(inst);
9571          try {
9572              date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9573          } catch (event) {
9574              this.log(event);
9575              dates = (noDefault ? '' : dates);
9576          }
9577          inst.selectedDay = date.getDate();
9578          inst.drawMonth = inst.selectedMonth = date.getMonth();
9579          inst.drawYear = inst.selectedYear = date.getFullYear();
9580          inst.currentDay = (dates ? date.getDate() : 0);
9581          inst.currentMonth = (dates ? date.getMonth() : 0);
9582          inst.currentYear = (dates ? date.getFullYear() : 0);
9583          this._adjustInstDate(inst);
9584      },
9585  
9586      /* Retrieve the default date shown on opening. */
9587      _getDefaultDate: function(inst) {
9588          return this._restrictMinMax(inst,
9589              this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
9590      },
9591  
9592      /* A date may be specified as an exact value or a relative one. */
9593      _determineDate: function(inst, date, defaultDate) {
9594          var offsetNumeric = function(offset) {
9595              var date = new Date();
9596              date.setDate(date.getDate() + offset);
9597              return date;
9598          };
9599          var offsetString = function(offset) {
9600              try {
9601                  return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
9602                      offset, $.datepicker._getFormatConfig(inst));
9603              }
9604              catch (e) {
9605                  // Ignore
9606              }
9607              var date = (offset.toLowerCase().match(/^c/) ?
9608                  $.datepicker._getDate(inst) : null) || new Date();
9609              var year = date.getFullYear();
9610              var month = date.getMonth();
9611              var day = date.getDate();
9612              var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9613              var matches = pattern.exec(offset);
9614              while (matches) {
9615                  switch (matches[2] || 'd') {
9616                      case 'd' : case 'D' :
9617                          day += parseInt(matches[1],10); break;
9618                      case 'w' : case 'W' :
9619                          day += parseInt(matches[1],10) * 7; break;
9620                      case 'm' : case 'M' :
9621                          month += parseInt(matches[1],10);
9622                          day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9623                          break;
9624                      case 'y': case 'Y' :
9625                          year += parseInt(matches[1],10);
9626                          day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9627                          break;
9628                  }
9629                  matches = pattern.exec(offset);
9630              }
9631              return new Date(year, month, day);
9632          };
9633          var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
9634              (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9635          newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
9636          if (newDate) {
9637              newDate.setHours(0);
9638              newDate.setMinutes(0);
9639              newDate.setSeconds(0);
9640              newDate.setMilliseconds(0);
9641          }
9642          return this._daylightSavingAdjust(newDate);
9643      },
9644  
9645      /* Handle switch to/from daylight saving.
9646         Hours may be non-zero on daylight saving cut-over:
9647         > 12 when midnight changeover, but then cannot generate
9648         midnight datetime, so jump to 1AM, otherwise reset.
9649         @param  date  (Date) the date to check
9650         @return  (Date) the corrected date */
9651      _daylightSavingAdjust: function(date) {
9652          if (!date) return null;
9653          date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9654          return date;
9655      },
9656  
9657      /* Set the date(s) directly. */
9658      _setDate: function(inst, date, noChange) {
9659          var clear = !date;
9660          var origMonth = inst.selectedMonth;
9661          var origYear = inst.selectedYear;
9662          var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9663          inst.selectedDay = inst.currentDay = newDate.getDate();
9664          inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9665          inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9666          if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
9667              this._notifyChange(inst);
9668          this._adjustInstDate(inst);
9669          if (inst.input) {
9670              inst.input.val(clear ? '' : this._formatDate(inst));
9671          }
9672      },
9673  
9674      /* Retrieve the date(s) directly. */
9675      _getDate: function(inst) {
9676          var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
9677              this._daylightSavingAdjust(new Date(
9678              inst.currentYear, inst.currentMonth, inst.currentDay)));
9679              return startDate;
9680      },
9681  
9682      /* Generate the HTML for the current state of the date picker. */
9683      _generateHTML: function(inst) {
9684          var today = new Date();
9685          today = this._daylightSavingAdjust(
9686              new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
9687          var isRTL = this._get(in