1 /*! jQuery UI - v1.10.0 - 2013-01-24
 
   3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js
 
   4 * Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
 
   6 (function( $, undefined ) {
 
   9         runiqueId = /^ui-id-\d+$/;
 
  11 // prevent duplicate loading
 
  12 // this is only a problem because we proxy existing functions
 
  13 // and we don't want to double proxy them
 
  51         focus: function( delay, fn ) {
 
  52                 return typeof delay === "number" ?
 
  53                         this.each(function() {
 
  55                                 setTimeout(function() {
 
  62                         this._focus.apply( this, arguments );
 
  65         scrollParent: function() {
 
  67                 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
 
  68                         scrollParent = this.parents().filter(function() {
 
  69                                 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
 
  72                         scrollParent = this.parents().filter(function() {
 
  73                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
 
  77                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
 
  80         zIndex: function( zIndex ) {
 
  81                 if ( zIndex !== undefined ) {
 
  82                         return this.css( "zIndex", zIndex );
 
  86                         var elem = $( this[ 0 ] ), position, value;
 
  87                         while ( elem.length && elem[ 0 ] !== document ) {
 
  88                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
 
  89                                 // This makes behavior of this function consistent across browsers
 
  90                                 // WebKit always returns auto if the element is positioned
 
  91                                 position = elem.css( "position" );
 
  92                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
 
  93                                         // IE returns 0 when zIndex is not specified
 
  94                                         // other browsers return a string
 
  95                                         // we ignore the case of nested elements with an explicit value of 0
 
  96                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
 
  97                                         value = parseInt( elem.css( "zIndex" ), 10 );
 
  98                                         if ( !isNaN( value ) && value !== 0 ) {
 
 102                                 elem = elem.parent();
 
 109         uniqueId: function() {
 
 110                 return this.each(function() {
 
 112                                 this.id = "ui-id-" + (++uuid);
 
 117         removeUniqueId: function() {
 
 118                 return this.each(function() {
 
 119                         if ( runiqueId.test( this.id ) ) {
 
 120                                 $( this ).removeAttr( "id" );
 
 127 function focusable( element, isTabIndexNotNaN ) {
 
 128         var map, mapName, img,
 
 129                 nodeName = element.nodeName.toLowerCase();
 
 130         if ( "area" === nodeName ) {
 
 131                 map = element.parentNode;
 
 133                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
 
 136                 img = $( "img[usemap=#" + mapName + "]" )[0];
 
 137                 return !!img && visible( img );
 
 139         return ( /input|select|textarea|button|object/.test( nodeName ) ?
 
 142                         element.href || isTabIndexNotNaN :
 
 144                 // the element and all of its ancestors must be visible
 
 148 function visible( element ) {
 
 149         return $.expr.filters.visible( element ) &&
 
 150                 !$( element ).parents().addBack().filter(function() {
 
 151                         return $.css( this, "visibility" ) === "hidden";
 
 155 $.extend( $.expr[ ":" ], {
 
 156         data: $.expr.createPseudo ?
 
 157                 $.expr.createPseudo(function( dataName ) {
 
 158                         return function( elem ) {
 
 159                                 return !!$.data( elem, dataName );
 
 162                 // support: jQuery <1.8
 
 163                 function( elem, i, match ) {
 
 164                         return !!$.data( elem, match[ 3 ] );
 
 167         focusable: function( element ) {
 
 168                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
 
 171         tabbable: function( element ) {
 
 172                 var tabIndex = $.attr( element, "tabindex" ),
 
 173                         isTabIndexNaN = isNaN( tabIndex );
 
 174                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
 
 178 // support: jQuery <1.8
 
 179 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
 
 180         $.each( [ "Width", "Height" ], function( i, name ) {
 
 181                 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
 
 182                         type = name.toLowerCase(),
 
 184                                 innerWidth: $.fn.innerWidth,
 
 185                                 innerHeight: $.fn.innerHeight,
 
 186                                 outerWidth: $.fn.outerWidth,
 
 187                                 outerHeight: $.fn.outerHeight
 
 190                 function reduce( elem, size, border, margin ) {
 
 191                         $.each( side, function() {
 
 192                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
 
 194                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
 
 197                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
 
 203                 $.fn[ "inner" + name ] = function( size ) {
 
 204                         if ( size === undefined ) {
 
 205                                 return orig[ "inner" + name ].call( this );
 
 208                         return this.each(function() {
 
 209                                 $( this ).css( type, reduce( this, size ) + "px" );
 
 213                 $.fn[ "outer" + name] = function( size, margin ) {
 
 214                         if ( typeof size !== "number" ) {
 
 215                                 return orig[ "outer" + name ].call( this, size );
 
 218                         return this.each(function() {
 
 219                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
 
 225 // support: jQuery <1.8
 
 226 if ( !$.fn.addBack ) {
 
 227         $.fn.addBack = function( selector ) {
 
 228                 return this.add( selector == null ?
 
 229                         this.prevObject : this.prevObject.filter( selector )
 
 234 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
 
 235 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
 
 236         $.fn.removeData = (function( removeData ) {
 
 237                 return function( key ) {
 
 238                         if ( arguments.length ) {
 
 239                                 return removeData.call( this, $.camelCase( key ) );
 
 241                                 return removeData.call( this );
 
 244         })( $.fn.removeData );
 
 252 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
 
 254 $.support.selectstart = "onselectstart" in document.createElement( "div" );
 
 256         disableSelection: function() {
 
 257                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
 
 258                         ".ui-disableSelection", function( event ) {
 
 259                                 event.preventDefault();
 
 263         enableSelection: function() {
 
 264                 return this.unbind( ".ui-disableSelection" );
 
 269         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
 
 271                 add: function( module, option, set ) {
 
 273                                 proto = $.ui[ module ].prototype;
 
 275                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
 
 276                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
 
 279                 call: function( instance, name, args ) {
 
 281                                 set = instance.plugins[ name ];
 
 282                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
 
 286                         for ( i = 0; i < set.length; i++ ) {
 
 287                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
 
 288                                         set[ i ][ 1 ].apply( instance.element, args );
 
 294         // only used by resizable
 
 295         hasScroll: function( el, a ) {
 
 297                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
 
 298                 if ( $( el ).css( "overflow" ) === "hidden") {
 
 302                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
 
 305                 if ( el[ scroll ] > 0 ) {
 
 309                 // TODO: determine which cases actually cause this to happen
 
 310                 // if the element doesn't have the scroll set, see if it's possible to
 
 313                 has = ( el[ scroll ] > 0 );
 
 320 (function( $, undefined ) {
 
 323         slice = Array.prototype.slice,
 
 324         _cleanData = $.cleanData;
 
 325 $.cleanData = function( elems ) {
 
 326         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
 
 328                         $( elem ).triggerHandler( "remove" );
 
 329                 // http://bugs.jquery.com/ticket/8235
 
 335 $.widget = function( name, base, prototype ) {
 
 336         var fullName, existingConstructor, constructor, basePrototype,
 
 337                 // proxiedPrototype allows the provided prototype to remain unmodified
 
 338                 // so that it can be used as a mixin for multiple widgets (#8876)
 
 339                 proxiedPrototype = {},
 
 340                 namespace = name.split( "." )[ 0 ];
 
 342         name = name.split( "." )[ 1 ];
 
 343         fullName = namespace + "-" + name;
 
 350         // create selector for plugin
 
 351         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
 
 352                 return !!$.data( elem, fullName );
 
 355         $[ namespace ] = $[ namespace ] || {};
 
 356         existingConstructor = $[ namespace ][ name ];
 
 357         constructor = $[ namespace ][ name ] = function( options, element ) {
 
 358                 // allow instantiation without "new" keyword
 
 359                 if ( !this._createWidget ) {
 
 360                         return new constructor( options, element );
 
 363                 // allow instantiation without initializing for simple inheritance
 
 364                 // must use "new" keyword (the code above always passes args)
 
 365                 if ( arguments.length ) {
 
 366                         this._createWidget( options, element );
 
 369         // extend with the existing constructor to carry over any static properties
 
 370         $.extend( constructor, existingConstructor, {
 
 371                 version: prototype.version,
 
 372                 // copy the object used to create the prototype in case we need to
 
 373                 // redefine the widget later
 
 374                 _proto: $.extend( {}, prototype ),
 
 375                 // track widgets that inherit from this widget in case this widget is
 
 376                 // redefined after a widget inherits from it
 
 377                 _childConstructors: []
 
 380         basePrototype = new base();
 
 381         // we need to make the options hash a property directly on the new instance
 
 382         // otherwise we'll modify the options hash on the prototype that we're
 
 384         basePrototype.options = $.widget.extend( {}, basePrototype.options );
 
 385         $.each( prototype, function( prop, value ) {
 
 386                 if ( !$.isFunction( value ) ) {
 
 387                         proxiedPrototype[ prop ] = value;
 
 390                 proxiedPrototype[ prop ] = (function() {
 
 391                         var _super = function() {
 
 392                                         return base.prototype[ prop ].apply( this, arguments );
 
 394                                 _superApply = function( args ) {
 
 395                                         return base.prototype[ prop ].apply( this, args );
 
 398                                 var __super = this._super,
 
 399                                         __superApply = this._superApply,
 
 402                                 this._super = _super;
 
 403                                 this._superApply = _superApply;
 
 405                                 returnValue = value.apply( this, arguments );
 
 407                                 this._super = __super;
 
 408                                 this._superApply = __superApply;
 
 414         constructor.prototype = $.widget.extend( basePrototype, {
 
 415                 // TODO: remove support for widgetEventPrefix
 
 416                 // always use the name + a colon as the prefix, e.g., draggable:start
 
 417                 // don't prefix for widgets that aren't DOM-based
 
 418                 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
 
 419         }, proxiedPrototype, {
 
 420                 constructor: constructor,
 
 421                 namespace: namespace,
 
 423                 widgetFullName: fullName
 
 426         // If this widget is being redefined then we need to find all widgets that
 
 427         // are inheriting from it and redefine all of them so that they inherit from
 
 428         // the new version of this widget. We're essentially trying to replace one
 
 429         // level in the prototype chain.
 
 430         if ( existingConstructor ) {
 
 431                 $.each( existingConstructor._childConstructors, function( i, child ) {
 
 432                         var childPrototype = child.prototype;
 
 434                         // redefine the child widget using the same prototype that was
 
 435                         // originally used, but inherit from the new version of the base
 
 436                         $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
 
 438                 // remove the list of existing child constructors from the old constructor
 
 439                 // so the old child constructors can be garbage collected
 
 440                 delete existingConstructor._childConstructors;
 
 442                 base._childConstructors.push( constructor );
 
 445         $.widget.bridge( name, constructor );
 
 448 $.widget.extend = function( target ) {
 
 449         var input = slice.call( arguments, 1 ),
 
 451                 inputLength = input.length,
 
 454         for ( ; inputIndex < inputLength; inputIndex++ ) {
 
 455                 for ( key in input[ inputIndex ] ) {
 
 456                         value = input[ inputIndex ][ key ];
 
 457                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
 
 459                                 if ( $.isPlainObject( value ) ) {
 
 460                                         target[ key ] = $.isPlainObject( target[ key ] ) ?
 
 461                                                 $.widget.extend( {}, target[ key ], value ) :
 
 462                                                 // Don't extend strings, arrays, etc. with objects
 
 463                                                 $.widget.extend( {}, value );
 
 464                                 // Copy everything else by reference
 
 466                                         target[ key ] = value;
 
 474 $.widget.bridge = function( name, object ) {
 
 475         var fullName = object.prototype.widgetFullName || name;
 
 476         $.fn[ name ] = function( options ) {
 
 477                 var isMethodCall = typeof options === "string",
 
 478                         args = slice.call( arguments, 1 ),
 
 481                 // allow multiple hashes to be passed on init
 
 482                 options = !isMethodCall && args.length ?
 
 483                         $.widget.extend.apply( null, [ options ].concat(args) ) :
 
 486                 if ( isMethodCall ) {
 
 487                         this.each(function() {
 
 489                                         instance = $.data( this, fullName );
 
 491                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
 
 492                                                 "attempted to call method '" + options + "'" );
 
 494                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
 
 495                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
 
 497                                 methodValue = instance[ options ].apply( instance, args );
 
 498                                 if ( methodValue !== instance && methodValue !== undefined ) {
 
 499                                         returnValue = methodValue && methodValue.jquery ?
 
 500                                                 returnValue.pushStack( methodValue.get() ) :
 
 506                         this.each(function() {
 
 507                                 var instance = $.data( this, fullName );
 
 509                                         instance.option( options || {} )._init();
 
 511                                         $.data( this, fullName, new object( options, this ) );
 
 520 $.Widget = function( /* options, element */ ) {};
 
 521 $.Widget._childConstructors = [];
 
 523 $.Widget.prototype = {
 
 524         widgetName: "widget",
 
 525         widgetEventPrefix: "",
 
 526         defaultElement: "<div>",
 
 533         _createWidget: function( options, element ) {
 
 534                 element = $( element || this.defaultElement || this )[ 0 ];
 
 535                 this.element = $( element );
 
 537                 this.eventNamespace = "." + this.widgetName + this.uuid;
 
 538                 this.options = $.widget.extend( {},
 
 540                         this._getCreateOptions(),
 
 544                 this.hoverable = $();
 
 545                 this.focusable = $();
 
 547                 if ( element !== this ) {
 
 548                         $.data( element, this.widgetFullName, this );
 
 549                         this._on( true, this.element, {
 
 550                                 remove: function( event ) {
 
 551                                         if ( event.target === element ) {
 
 556                         this.document = $( element.style ?
 
 557                                 // element within the document
 
 558                                 element.ownerDocument :
 
 559                                 // element is window or document
 
 560                                 element.document || element );
 
 561                         this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
 
 565                 this._trigger( "create", null, this._getCreateEventData() );
 
 568         _getCreateOptions: $.noop,
 
 569         _getCreateEventData: $.noop,
 
 573         destroy: function() {
 
 575                 // we can probably remove the unbind calls in 2.0
 
 576                 // all event bindings should go through this._on()
 
 578                         .unbind( this.eventNamespace )
 
 580                         // TODO remove dual storage
 
 581                         .removeData( this.widgetName )
 
 582                         .removeData( this.widgetFullName )
 
 583                         // support: jquery <1.6.3
 
 584                         // http://bugs.jquery.com/ticket/9413
 
 585                         .removeData( $.camelCase( this.widgetFullName ) );
 
 587                         .unbind( this.eventNamespace )
 
 588                         .removeAttr( "aria-disabled" )
 
 590                                 this.widgetFullName + "-disabled " +
 
 591                                 "ui-state-disabled" );
 
 593                 // clean up events and states
 
 594                 this.bindings.unbind( this.eventNamespace );
 
 595                 this.hoverable.removeClass( "ui-state-hover" );
 
 596                 this.focusable.removeClass( "ui-state-focus" );
 
 604         option: function( key, value ) {
 
 610                 if ( arguments.length === 0 ) {
 
 611                         // don't return a reference to the internal hash
 
 612                         return $.widget.extend( {}, this.options );
 
 615                 if ( typeof key === "string" ) {
 
 616                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 
 618                         parts = key.split( "." );
 
 620                         if ( parts.length ) {
 
 621                                 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
 
 622                                 for ( i = 0; i < parts.length - 1; i++ ) {
 
 623                                         curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
 
 624                                         curOption = curOption[ parts[ i ] ];
 
 627                                 if ( value === undefined ) {
 
 628                                         return curOption[ key ] === undefined ? null : curOption[ key ];
 
 630                                 curOption[ key ] = value;
 
 632                                 if ( value === undefined ) {
 
 633                                         return this.options[ key ] === undefined ? null : this.options[ key ];
 
 635                                 options[ key ] = value;
 
 639                 this._setOptions( options );
 
 643         _setOptions: function( options ) {
 
 646                 for ( key in options ) {
 
 647                         this._setOption( key, options[ key ] );
 
 652         _setOption: function( key, value ) {
 
 653                 this.options[ key ] = value;
 
 655                 if ( key === "disabled" ) {
 
 657                                 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
 
 658                                 .attr( "aria-disabled", value );
 
 659                         this.hoverable.removeClass( "ui-state-hover" );
 
 660                         this.focusable.removeClass( "ui-state-focus" );
 
 667                 return this._setOption( "disabled", false );
 
 669         disable: function() {
 
 670                 return this._setOption( "disabled", true );
 
 673         _on: function( suppressDisabledCheck, element, handlers ) {
 
 677                 // no suppressDisabledCheck flag, shuffle arguments
 
 678                 if ( typeof suppressDisabledCheck !== "boolean" ) {
 
 680                         element = suppressDisabledCheck;
 
 681                         suppressDisabledCheck = false;
 
 684                 // no element argument, shuffle and use this.element
 
 687                         element = this.element;
 
 688                         delegateElement = this.widget();
 
 690                         // accept selectors, DOM elements
 
 691                         element = delegateElement = $( element );
 
 692                         this.bindings = this.bindings.add( element );
 
 695                 $.each( handlers, function( event, handler ) {
 
 696                         function handlerProxy() {
 
 697                                 // allow widgets to customize the disabled handling
 
 698                                 // - disabled as an array instead of boolean
 
 699                                 // - disabled class as method for disabling individual parts
 
 700                                 if ( !suppressDisabledCheck &&
 
 701                                                 ( instance.options.disabled === true ||
 
 702                                                         $( this ).hasClass( "ui-state-disabled" ) ) ) {
 
 705                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
 
 706                                         .apply( instance, arguments );
 
 709                         // copy the guid so direct unbinding works
 
 710                         if ( typeof handler !== "string" ) {
 
 711                                 handlerProxy.guid = handler.guid =
 
 712                                         handler.guid || handlerProxy.guid || $.guid++;
 
 715                         var match = event.match( /^(\w+)\s*(.*)$/ ),
 
 716                                 eventName = match[1] + instance.eventNamespace,
 
 719                                 delegateElement.delegate( selector, eventName, handlerProxy );
 
 721                                 element.bind( eventName, handlerProxy );
 
 726         _off: function( element, eventName ) {
 
 727                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
 
 728                 element.unbind( eventName ).undelegate( eventName );
 
 731         _delay: function( handler, delay ) {
 
 732                 function handlerProxy() {
 
 733                         return ( typeof handler === "string" ? instance[ handler ] : handler )
 
 734                                 .apply( instance, arguments );
 
 737                 return setTimeout( handlerProxy, delay || 0 );
 
 740         _hoverable: function( element ) {
 
 741                 this.hoverable = this.hoverable.add( element );
 
 743                         mouseenter: function( event ) {
 
 744                                 $( event.currentTarget ).addClass( "ui-state-hover" );
 
 746                         mouseleave: function( event ) {
 
 747                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
 
 752         _focusable: function( element ) {
 
 753                 this.focusable = this.focusable.add( element );
 
 755                         focusin: function( event ) {
 
 756                                 $( event.currentTarget ).addClass( "ui-state-focus" );
 
 758                         focusout: function( event ) {
 
 759                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
 
 764         _trigger: function( type, event, data ) {
 
 766                         callback = this.options[ type ];
 
 769                 event = $.Event( event );
 
 770                 event.type = ( type === this.widgetEventPrefix ?
 
 772                         this.widgetEventPrefix + type ).toLowerCase();
 
 773                 // the original event may come from any element
 
 774                 // so we need to reset the target on the new event
 
 775                 event.target = this.element[ 0 ];
 
 777                 // copy original event properties over to the new event
 
 778                 orig = event.originalEvent;
 
 780                         for ( prop in orig ) {
 
 781                                 if ( !( prop in event ) ) {
 
 782                                         event[ prop ] = orig[ prop ];
 
 787                 this.element.trigger( event, data );
 
 788                 return !( $.isFunction( callback ) &&
 
 789                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
 
 790                         event.isDefaultPrevented() );
 
 794 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
 
 795         $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
 
 796                 if ( typeof options === "string" ) {
 
 797                         options = { effect: options };
 
 800                         effectName = !options ?
 
 802                                 options === true || typeof options === "number" ?
 
 804                                         options.effect || defaultEffect;
 
 805                 options = options || {};
 
 806                 if ( typeof options === "number" ) {
 
 807                         options = { duration: options };
 
 809                 hasOptions = !$.isEmptyObject( options );
 
 810                 options.complete = callback;
 
 811                 if ( options.delay ) {
 
 812                         element.delay( options.delay );
 
 814                 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
 
 815                         element[ method ]( options );
 
 816                 } else if ( effectName !== method && element[ effectName ] ) {
 
 817                         element[ effectName ]( options.duration, options.easing, callback );
 
 819                         element.queue(function( next ) {
 
 820                                 $( this )[ method ]();
 
 822                                         callback.call( element[ 0 ] );
 
 831 (function( $, undefined ) {
 
 833 var mouseHandled = false;
 
 834 $( document ).mouseup( function() {
 
 835         mouseHandled = false;
 
 838 $.widget("ui.mouse", {
 
 841                 cancel: "input,textarea,button,select,option",
 
 845         _mouseInit: function() {
 
 849                         .bind("mousedown."+this.widgetName, function(event) {
 
 850                                 return that._mouseDown(event);
 
 852                         .bind("click."+this.widgetName, function(event) {
 
 853                                 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
 
 854                                         $.removeData(event.target, that.widgetName + ".preventClickEvent");
 
 855                                         event.stopImmediatePropagation();
 
 860                 this.started = false;
 
 863         // TODO: make sure destroying one instance of mouse doesn't mess with
 
 864         // other instances of mouse
 
 865         _mouseDestroy: function() {
 
 866                 this.element.unbind("."+this.widgetName);
 
 867                 if ( this._mouseMoveDelegate ) {
 
 869                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
 
 870                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
 
 874         _mouseDown: function(event) {
 
 875                 // don't let more than one widget handle mouseStart
 
 876                 if( mouseHandled ) { return; }
 
 878                 // we may have missed mouseup (out of window)
 
 879                 (this._mouseStarted && this._mouseUp(event));
 
 881                 this._mouseDownEvent = event;
 
 884                         btnIsLeft = (event.which === 1),
 
 885                         // event.target.nodeName works around a bug in IE 8 with
 
 886                         // disabled inputs (#7620)
 
 887                         elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
 
 888                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
 
 892                 this.mouseDelayMet = !this.options.delay;
 
 893                 if (!this.mouseDelayMet) {
 
 894                         this._mouseDelayTimer = setTimeout(function() {
 
 895                                 that.mouseDelayMet = true;
 
 896                         }, this.options.delay);
 
 899                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 
 900                         this._mouseStarted = (this._mouseStart(event) !== false);
 
 901                         if (!this._mouseStarted) {
 
 902                                 event.preventDefault();
 
 907                 // Click event may never have fired (Gecko & Opera)
 
 908                 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
 
 909                         $.removeData(event.target, this.widgetName + ".preventClickEvent");
 
 912                 // these delegates are required to keep context
 
 913                 this._mouseMoveDelegate = function(event) {
 
 914                         return that._mouseMove(event);
 
 916                 this._mouseUpDelegate = function(event) {
 
 917                         return that._mouseUp(event);
 
 920                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
 
 921                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
 
 923                 event.preventDefault();
 
 929         _mouseMove: function(event) {
 
 930                 // IE mouseup check - mouseup happened when mouse was out of window
 
 931                 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
 
 932                         return this._mouseUp(event);
 
 935                 if (this._mouseStarted) {
 
 936                         this._mouseDrag(event);
 
 937                         return event.preventDefault();
 
 940                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
 
 942                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
 
 943                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
 
 946                 return !this._mouseStarted;
 
 949         _mouseUp: function(event) {
 
 951                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
 
 952                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
 
 954                 if (this._mouseStarted) {
 
 955                         this._mouseStarted = false;
 
 957                         if (event.target === this._mouseDownEvent.target) {
 
 958                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
 
 961                         this._mouseStop(event);
 
 967         _mouseDistanceMet: function(event) {
 
 969                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
 
 970                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
 
 971                         ) >= this.options.distance
 
 975         _mouseDelayMet: function(/* event */) {
 
 976                 return this.mouseDelayMet;
 
 979         // These are placeholder methods, to be overriden by extending plugin
 
 980         _mouseStart: function(/* event */) {},
 
 981         _mouseDrag: function(/* event */) {},
 
 982         _mouseStop: function(/* event */) {},
 
 983         _mouseCapture: function(/* event */) { return true; }
 
 987 (function( $, undefined ) {
 
 989 $.widget("ui.draggable", $.ui.mouse, {
 
 991         widgetEventPrefix: "drag",
 
 996                 connectToSortable: false,
 
1005                 refreshPositions: false,
 
1007                 revertDuration: 500,
 
1010                 scrollSensitivity: 20,
 
1023         _create: function() {
 
1025                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
 
1026                         this.element[0].style.position = "relative";
 
1028                 if (this.options.addClasses){
 
1029                         this.element.addClass("ui-draggable");
 
1031                 if (this.options.disabled){
 
1032                         this.element.addClass("ui-draggable-disabled");
 
1039         _destroy: function() {
 
1040                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
 
1041                 this._mouseDestroy();
 
1044         _mouseCapture: function(event) {
 
1046                 var o = this.options;
 
1048                 // among others, prevent a drag on a resizable-handle
 
1049                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
 
1053                 //Quit if we're not on a valid handle
 
1054                 this.handle = this._getHandle(event);
 
1059                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
 
1060                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
 
1062                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
 
1063                                 position: "absolute", opacity: "0.001", zIndex: 1000
 
1065                         .css($(this).offset())
 
1073         _mouseStart: function(event) {
 
1075                 var o = this.options;
 
1077                 //Create and append the visible helper
 
1078                 this.helper = this._createHelper(event);
 
1080                 this.helper.addClass("ui-draggable-dragging");
 
1082                 //Cache the helper size
 
1083                 this._cacheHelperProportions();
 
1085                 //If ddmanager is used for droppables, set the global draggable
 
1086                 if($.ui.ddmanager) {
 
1087                         $.ui.ddmanager.current = this;
 
1091                  * - Position generation -
 
1092                  * This block generates everything position related - it's the core of draggables.
 
1095                 //Cache the margins of the original element
 
1096                 this._cacheMargins();
 
1098                 //Store the helper's css position
 
1099                 this.cssPosition = this.helper.css("position");
 
1100                 this.scrollParent = this.helper.scrollParent();
 
1102                 //The element's absolute position on the page minus margins
 
1103                 this.offset = this.positionAbs = this.element.offset();
 
1105                         top: this.offset.top - this.margins.top,
 
1106                         left: this.offset.left - this.margins.left
 
1109                 $.extend(this.offset, {
 
1110                         click: { //Where the click happened, relative to the element
 
1111                                 left: event.pageX - this.offset.left,
 
1112                                 top: event.pageY - this.offset.top
 
1114                         parent: this._getParentOffset(),
 
1115                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
 
1118                 //Generate the original position
 
1119                 this.originalPosition = this.position = this._generatePosition(event);
 
1120                 this.originalPageX = event.pageX;
 
1121                 this.originalPageY = event.pageY;
 
1123                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
 
1124                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
 
1126                 //Set a containment if given in the options
 
1128                         this._setContainment();
 
1131                 //Trigger event + callbacks
 
1132                 if(this._trigger("start", event) === false) {
 
1137                 //Recache the helper size
 
1138                 this._cacheHelperProportions();
 
1140                 //Prepare the droppable offsets
 
1141                 if ($.ui.ddmanager && !o.dropBehaviour) {
 
1142                         $.ui.ddmanager.prepareOffsets(this, event);
 
1146                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
 
1148                 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
 
1149                 if ( $.ui.ddmanager ) {
 
1150                         $.ui.ddmanager.dragStart(this, event);
 
1156         _mouseDrag: function(event, noPropagation) {
 
1158                 //Compute the helpers position
 
1159                 this.position = this._generatePosition(event);
 
1160                 this.positionAbs = this._convertPositionTo("absolute");
 
1162                 //Call plugins and callbacks and use the resulting position if something is returned
 
1163                 if (!noPropagation) {
 
1164                         var ui = this._uiHash();
 
1165                         if(this._trigger("drag", event, ui) === false) {
 
1169                         this.position = ui.position;
 
1172                 if(!this.options.axis || this.options.axis !== "y") {
 
1173                         this.helper[0].style.left = this.position.left+"px";
 
1175                 if(!this.options.axis || this.options.axis !== "x") {
 
1176                         this.helper[0].style.top = this.position.top+"px";
 
1178                 if($.ui.ddmanager) {
 
1179                         $.ui.ddmanager.drag(this, event);
 
1185         _mouseStop: function(event) {
 
1187                 //If we are using droppables, inform the manager about the drop
 
1190                         elementInDom = false,
 
1192                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
 
1193                         dropped = $.ui.ddmanager.drop(this, event);
 
1196                 //if a drop comes from outside (a sortable)
 
1198                         dropped = this.dropped;
 
1199                         this.dropped = false;
 
1202                 //if the original element is no longer in the DOM don't bother to continue (see #8269)
 
1203                 element = this.element[0];
 
1204                 while ( element && (element = element.parentNode) ) {
 
1205                         if (element === document ) {
 
1206                                 elementInDom = true;
 
1209                 if ( !elementInDom && this.options.helper === "original" ) {
 
1213                 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))) {
 
1214                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
 
1215                                 if(that._trigger("stop", event) !== false) {
 
1220                         if(this._trigger("stop", event) !== false) {
 
1228         _mouseUp: function(event) {
 
1229                 //Remove frame helpers
 
1230                 $("div.ui-draggable-iframeFix").each(function() {
 
1231                         this.parentNode.removeChild(this);
 
1234                 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
 
1235                 if( $.ui.ddmanager ) {
 
1236                         $.ui.ddmanager.dragStop(this, event);
 
1239                 return $.ui.mouse.prototype._mouseUp.call(this, event);
 
1242         cancel: function() {
 
1244                 if(this.helper.is(".ui-draggable-dragging")) {
 
1254         _getHandle: function(event) {
 
1256                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
 
1257                 $(this.options.handle, this.element)
 
1261                                 if(this === event.target) {
 
1270         _createHelper: function(event) {
 
1272                 var o = this.options,
 
1273                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
 
1275                 if(!helper.parents("body").length) {
 
1276                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
 
1279                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
 
1280                         helper.css("position", "absolute");
 
1287         _adjustOffsetFromHelper: function(obj) {
 
1288                 if (typeof obj === "string") {
 
1289                         obj = obj.split(" ");
 
1291                 if ($.isArray(obj)) {
 
1292                         obj = {left: +obj[0], top: +obj[1] || 0};
 
1294                 if ("left" in obj) {
 
1295                         this.offset.click.left = obj.left + this.margins.left;
 
1297                 if ("right" in obj) {
 
1298                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 
1301                         this.offset.click.top = obj.top + this.margins.top;
 
1303                 if ("bottom" in obj) {
 
1304                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 
1308         _getParentOffset: function() {
 
1310                 //Get the offsetParent and cache its position
 
1311                 this.offsetParent = this.helper.offsetParent();
 
1312                 var po = this.offsetParent.offset();
 
1314                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
 
1315                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
 
1316                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
 
1317                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
 
1318                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
 
1319                         po.left += this.scrollParent.scrollLeft();
 
1320                         po.top += this.scrollParent.scrollTop();
 
1323                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
 
1325                 if((this.offsetParent[0] === document.body) ||
 
1326                         (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
 
1327                         po = { top: 0, left: 0 };
 
1331                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
 
1332                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
 
1337         _getRelativeOffset: function() {
 
1339                 if(this.cssPosition === "relative") {
 
1340                         var p = this.element.position();
 
1342                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
 
1343                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
 
1346                         return { top: 0, left: 0 };
 
1351         _cacheMargins: function() {
 
1353                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
 
1354                         top: (parseInt(this.element.css("marginTop"),10) || 0),
 
1355                         right: (parseInt(this.element.css("marginRight"),10) || 0),
 
1356                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
 
1360         _cacheHelperProportions: function() {
 
1361                 this.helperProportions = {
 
1362                         width: this.helper.outerWidth(),
 
1363                         height: this.helper.outerHeight()
 
1367         _setContainment: function() {
 
1372                 if(o.containment === "parent") {
 
1373                         o.containment = this.helper[0].parentNode;
 
1375                 if(o.containment === "document" || o.containment === "window") {
 
1376                         this.containment = [
 
1377                                 o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
 
1378                                 o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
 
1379                                 (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
 
1380                                 (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
 
1384                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
 
1385                         c = $(o.containment);
 
1392                         over = ($(ce).css("overflow") !== "hidden");
 
1394                         this.containment = [
 
1395                                 (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
 
1396                                 (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
 
1397                                 (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,
 
1398                                 (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
 
1400                         this.relative_container = c;
 
1402                 } else if(o.containment.constructor === Array) {
 
1403                         this.containment = o.containment;
 
1408         _convertPositionTo: function(d, pos) {
 
1411                         pos = this.position;
 
1414                 var mod = d === "absolute" ? 1 : -1,
 
1415                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 
1419                                 pos.top +                                                                                                                               // The absolute mouse position
 
1420                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
 
1421                                 this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
 
1422                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
 
1425                                 pos.left +                                                                                                                              // The absolute mouse position
 
1426                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
 
1427                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
 
1428                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
 
1434         _generatePosition: function(event) {
 
1436                 var containment, co, top, left,
 
1438                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
 
1439                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
 
1440                         pageX = event.pageX,
 
1441                         pageY = event.pageY;
 
1444                  * - Position constraining -
 
1445                  * Constrain the position to a mix of grid, containment.
 
1448                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
 
1449                         if(this.containment) {
 
1450                         if (this.relative_container){
 
1451                                 co = this.relative_container.offset();
 
1452                                 containment = [ this.containment[0] + co.left,
 
1453                                         this.containment[1] + co.top,
 
1454                                         this.containment[2] + co.left,
 
1455                                         this.containment[3] + co.top ];
 
1458                                 containment = this.containment;
 
1461                                 if(event.pageX - this.offset.click.left < containment[0]) {
 
1462                                         pageX = containment[0] + this.offset.click.left;
 
1464                                 if(event.pageY - this.offset.click.top < containment[1]) {
 
1465                                         pageY = containment[1] + this.offset.click.top;
 
1467                                 if(event.pageX - this.offset.click.left > containment[2]) {
 
1468                                         pageX = containment[2] + this.offset.click.left;
 
1470                                 if(event.pageY - this.offset.click.top > containment[3]) {
 
1471                                         pageY = containment[3] + this.offset.click.top;
 
1476                                 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
 
1477                                 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
 
1478                                 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;
 
1480                                 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
 
1481                                 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;
 
1488                                 pageY -                                                                                                                                 // The absolute mouse position
 
1489                                 this.offset.click.top   -                                                                                               // Click offset (relative to the element)
 
1490                                 this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
 
1491                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
 
1492                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
 
1495                                 pageX -                                                                                                                                 // The absolute mouse position
 
1496                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
 
1497                                 this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
 
1498                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
 
1499                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
 
1505         _clear: function() {
 
1506                 this.helper.removeClass("ui-draggable-dragging");
 
1507                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
 
1508                         this.helper.remove();
 
1511                 this.cancelHelperRemoval = false;
 
1514         // From now on bulk stuff - mainly helpers
 
1516         _trigger: function(type, event, ui) {
 
1517                 ui = ui || this._uiHash();
 
1518                 $.ui.plugin.call(this, type, [event, ui]);
 
1519                 //The absolute position has to be recalculated after plugins
 
1520                 if(type === "drag") {
 
1521                         this.positionAbs = this._convertPositionTo("absolute");
 
1523                 return $.Widget.prototype._trigger.call(this, type, event, ui);
 
1528         _uiHash: function() {
 
1530                         helper: this.helper,
 
1531                         position: this.position,
 
1532                         originalPosition: this.originalPosition,
 
1533                         offset: this.positionAbs
 
1539 $.ui.plugin.add("draggable", "connectToSortable", {
 
1540         start: function(event, ui) {
 
1542                 var inst = $(this).data("ui-draggable"), o = inst.options,
 
1543                         uiSortable = $.extend({}, ui, { item: inst.element });
 
1544                 inst.sortables = [];
 
1545                 $(o.connectToSortable).each(function() {
 
1546                         var sortable = $.data(this, "ui-sortable");
 
1547                         if (sortable && !sortable.options.disabled) {
 
1548                                 inst.sortables.push({
 
1550                                         shouldRevert: sortable.options.revert
 
1552                                 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).
 
1553                                 sortable._trigger("activate", event, uiSortable);
 
1558         stop: function(event, ui) {
 
1560                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
 
1561                 var inst = $(this).data("ui-draggable"),
 
1562                         uiSortable = $.extend({}, ui, { item: inst.element });
 
1564                 $.each(inst.sortables, function() {
 
1565                         if(this.instance.isOver) {
 
1567                                 this.instance.isOver = 0;
 
1569                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
 
1570                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
 
1572                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
 
1573                                 if(this.shouldRevert) {
 
1574                                         this.instance.options.revert = true;
 
1577                                 //Trigger the stop of the sortable
 
1578                                 this.instance._mouseStop(event);
 
1580                                 this.instance.options.helper = this.instance.options._helper;
 
1582                                 //If the helper has been the original item, restore properties in the sortable
 
1583                                 if(inst.options.helper === "original") {
 
1584                                         this.instance.currentItem.css({ top: "auto", left: "auto" });
 
1588                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
 
1589                                 this.instance._trigger("deactivate", event, uiSortable);
 
1595         drag: function(event, ui) {
 
1597                 var inst = $(this).data("ui-draggable"), that = this;
 
1599                 $.each(inst.sortables, function() {
 
1601                         var innermostIntersecting = false,
 
1602                                 thisSortable = this;
 
1604                         //Copy over some variables to allow calling the sortable's native _intersectsWith
 
1605                         this.instance.positionAbs = inst.positionAbs;
 
1606                         this.instance.helperProportions = inst.helperProportions;
 
1607                         this.instance.offset.click = inst.offset.click;
 
1609                         if(this.instance._intersectsWith(this.instance.containerCache)) {
 
1610                                 innermostIntersecting = true;
 
1611                                 $.each(inst.sortables, function () {
 
1612                                         this.instance.positionAbs = inst.positionAbs;
 
1613                                         this.instance.helperProportions = inst.helperProportions;
 
1614                                         this.instance.offset.click = inst.offset.click;
 
1615                                         if (this !== thisSortable &&
 
1616                                                 this.instance._intersectsWith(this.instance.containerCache) &&
 
1617                                                 $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])
 
1619                                                 innermostIntersecting = false;
 
1621                                         return innermostIntersecting;
 
1626                         if(innermostIntersecting) {
 
1627                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
 
1628                                 if(!this.instance.isOver) {
 
1630                                         this.instance.isOver = 1;
 
1631                                         //Now we fake the start of dragging for the sortable instance,
 
1632                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
 
1633                                         //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)
 
1634                                         this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
 
1635                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
 
1636                                         this.instance.options.helper = function() { return ui.helper[0]; };
 
1638                                         event.target = this.instance.currentItem[0];
 
1639                                         this.instance._mouseCapture(event, true);
 
1640                                         this.instance._mouseStart(event, true, true);
 
1642                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
 
1643                                         this.instance.offset.click.top = inst.offset.click.top;
 
1644                                         this.instance.offset.click.left = inst.offset.click.left;
 
1645                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
 
1646                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
 
1648                                         inst._trigger("toSortable", event);
 
1649                                         inst.dropped = this.instance.element; //draggable revert needs that
 
1650                                         //hack so receive/update callbacks work (mostly)
 
1651                                         inst.currentItem = inst.element;
 
1652                                         this.instance.fromOutside = inst;
 
1656                                 //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
 
1657                                 if(this.instance.currentItem) {
 
1658                                         this.instance._mouseDrag(event);
 
1663                                 //If it doesn't intersect with the sortable, and it intersected before,
 
1664                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
 
1665                                 if(this.instance.isOver) {
 
1667                                         this.instance.isOver = 0;
 
1668                                         this.instance.cancelHelperRemoval = true;
 
1670                                         //Prevent reverting on this forced stop
 
1671                                         this.instance.options.revert = false;
 
1673                                         // The out event needs to be triggered independently
 
1674                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
 
1676                                         this.instance._mouseStop(event, true);
 
1677                                         this.instance.options.helper = this.instance.options._helper;
 
1679                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
 
1680                                         this.instance.currentItem.remove();
 
1681                                         if(this.instance.placeholder) {
 
1682                                                 this.instance.placeholder.remove();
 
1685                                         inst._trigger("fromSortable", event);
 
1686                                         inst.dropped = false; //draggable revert needs that
 
1696 $.ui.plugin.add("draggable", "cursor", {
 
1698                 var t = $("body"), o = $(this).data("ui-draggable").options;
 
1699                 if (t.css("cursor")) {
 
1700                         o._cursor = t.css("cursor");
 
1702                 t.css("cursor", o.cursor);
 
1705                 var o = $(this).data("ui-draggable").options;
 
1707                         $("body").css("cursor", o._cursor);
 
1712 $.ui.plugin.add("draggable", "opacity", {
 
1713         start: function(event, ui) {
 
1714                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
 
1715                 if(t.css("opacity")) {
 
1716                         o._opacity = t.css("opacity");
 
1718                 t.css("opacity", o.opacity);
 
1720         stop: function(event, ui) {
 
1721                 var o = $(this).data("ui-draggable").options;
 
1723                         $(ui.helper).css("opacity", o._opacity);
 
1728 $.ui.plugin.add("draggable", "scroll", {
 
1730                 var i = $(this).data("ui-draggable");
 
1731                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
 
1732                         i.overflowOffset = i.scrollParent.offset();
 
1735         drag: function( event ) {
 
1737                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
 
1739                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
 
1741                         if(!o.axis || o.axis !== "x") {
 
1742                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
 
1743                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
 
1744                                 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
 
1745                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
 
1749                         if(!o.axis || o.axis !== "y") {
 
1750                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
 
1751                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
 
1752                                 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
 
1753                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
 
1759                         if(!o.axis || o.axis !== "x") {
 
1760                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
 
1761                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
 
1762                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
 
1763                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
 
1767                         if(!o.axis || o.axis !== "y") {
 
1768                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
 
1769                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
 
1770                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
 
1771                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
 
1777                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
 
1778                         $.ui.ddmanager.prepareOffsets(i, event);
 
1784 $.ui.plugin.add("draggable", "snap", {
 
1787                 var i = $(this).data("ui-draggable"),
 
1790                 i.snapElements = [];
 
1792                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
 
1795                         if(this !== i.element[0]) {
 
1796                                 i.snapElements.push({
 
1798                                         width: $t.outerWidth(), height: $t.outerHeight(),
 
1799                                         top: $o.top, left: $o.left
 
1805         drag: function(event, ui) {
 
1807                 var ts, bs, ls, rs, l, r, t, b, i, first,
 
1808                         inst = $(this).data("ui-draggable"),
 
1810                         d = o.snapTolerance,
 
1811                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
 
1812                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
 
1814                 for (i = inst.snapElements.length - 1; i >= 0; i--){
 
1816                         l = inst.snapElements[i].left;
 
1817                         r = l + inst.snapElements[i].width;
 
1818                         t = inst.snapElements[i].top;
 
1819                         b = t + inst.snapElements[i].height;
 
1821                         //Yes, I know, this is insane ;)
 
1822                         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))) {
 
1823                                 if(inst.snapElements[i].snapping) {
 
1824                                         (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
 
1826                                 inst.snapElements[i].snapping = false;
 
1830                         if(o.snapMode !== "inner") {
 
1831                                 ts = Math.abs(t - y2) <= d;
 
1832                                 bs = Math.abs(b - y1) <= d;
 
1833                                 ls = Math.abs(l - x2) <= d;
 
1834                                 rs = Math.abs(r - x1) <= d;
 
1836                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
 
1839                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
 
1842                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
 
1845                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
 
1849                         first = (ts || bs || ls || rs);
 
1851                         if(o.snapMode !== "outer") {
 
1852                                 ts = Math.abs(t - y1) <= d;
 
1853                                 bs = Math.abs(b - y2) <= d;
 
1854                                 ls = Math.abs(l - x1) <= d;
 
1855                                 rs = Math.abs(r - x2) <= d;
 
1857                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
 
1860                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
 
1863                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
 
1866                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
 
1870                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
 
1871                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
 
1873                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
 
1880 $.ui.plugin.add("draggable", "stack", {
 
1884                         o = $(this).data("ui-draggable").options,
 
1885                         group = $.makeArray($(o.stack)).sort(function(a,b) {
 
1886                                 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
 
1889                 if (!group.length) { return; }
 
1891                 min = parseInt(group[0].style.zIndex, 10) || 0;
 
1892                 $(group).each(function(i) {
 
1893                         this.style.zIndex = min + i;
 
1896                 this[0].style.zIndex = min + group.length;
 
1901 $.ui.plugin.add("draggable", "zIndex", {
 
1902         start: function(event, ui) {
 
1903                 var t = $(ui.helper), o = $(this).data("ui-draggable").options;
 
1904                 if(t.css("zIndex")) {
 
1905                         o._zIndex = t.css("zIndex");
 
1907                 t.css("zIndex", o.zIndex);
 
1909         stop: function(event, ui) {
 
1910                 var o = $(this).data("ui-draggable").options;
 
1912                         $(ui.helper).css("zIndex", o._zIndex);
 
1918 (function( $, undefined ) {
 
1920 function isOverAxis( x, reference, size ) {
 
1921         return ( x > reference ) && ( x < ( reference + size ) );
 
1924 $.widget("ui.droppable", {
 
1926         widgetEventPrefix: "drop",
 
1934                 tolerance: "intersect",
 
1943         _create: function() {
 
1945                 var o = this.options,
 
1948                 this.isover = false;
 
1951                 this.accept = $.isFunction(accept) ? accept : function(d) {
 
1952                         return d.is(accept);
 
1955                 //Store the droppable's proportions
 
1956                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
 
1958                 // Add the reference and positions to the manager
 
1959                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
 
1960                 $.ui.ddmanager.droppables[o.scope].push(this);
 
1962                 (o.addClasses && this.element.addClass("ui-droppable"));
 
1966         _destroy: function() {
 
1968                         drop = $.ui.ddmanager.droppables[this.options.scope];
 
1970                 for ( ; i < drop.length; i++ ) {
 
1971                         if ( drop[i] === this ) {
 
1976                 this.element.removeClass("ui-droppable ui-droppable-disabled");
 
1979         _setOption: function(key, value) {
 
1981                 if(key === "accept") {
 
1982                         this.accept = $.isFunction(value) ? value : function(d) {
 
1986                 $.Widget.prototype._setOption.apply(this, arguments);
 
1989         _activate: function(event) {
 
1990                 var draggable = $.ui.ddmanager.current;
 
1991                 if(this.options.activeClass) {
 
1992                         this.element.addClass(this.options.activeClass);
 
1995                         this._trigger("activate", event, this.ui(draggable));
 
1999         _deactivate: function(event) {
 
2000                 var draggable = $.ui.ddmanager.current;
 
2001                 if(this.options.activeClass) {
 
2002                         this.element.removeClass(this.options.activeClass);
 
2005                         this._trigger("deactivate", event, this.ui(draggable));
 
2009         _over: function(event) {
 
2011                 var draggable = $.ui.ddmanager.current;
 
2013                 // Bail if draggable and droppable are same element
 
2014                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
 
2018                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 
2019                         if(this.options.hoverClass) {
 
2020                                 this.element.addClass(this.options.hoverClass);
 
2022                         this._trigger("over", event, this.ui(draggable));
 
2027         _out: function(event) {
 
2029                 var draggable = $.ui.ddmanager.current;
 
2031                 // Bail if draggable and droppable are same element
 
2032                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
 
2036                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 
2037                         if(this.options.hoverClass) {
 
2038                                 this.element.removeClass(this.options.hoverClass);
 
2040                         this._trigger("out", event, this.ui(draggable));
 
2045         _drop: function(event,custom) {
 
2047                 var draggable = custom || $.ui.ddmanager.current,
 
2048                         childrenIntersection = false;
 
2050                 // Bail if draggable and droppable are same element
 
2051                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
 
2055                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
 
2056                         var inst = $.data(this, "ui-droppable");
 
2058                                 inst.options.greedy &&
 
2059                                 !inst.options.disabled &&
 
2060                                 inst.options.scope === draggable.options.scope &&
 
2061                                 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
 
2062                                 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
 
2063                         ) { childrenIntersection = true; return false; }
 
2065                 if(childrenIntersection) {
 
2069                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 
2070                         if(this.options.activeClass) {
 
2071                                 this.element.removeClass(this.options.activeClass);
 
2073                         if(this.options.hoverClass) {
 
2074                                 this.element.removeClass(this.options.hoverClass);
 
2076                         this._trigger("drop", event, this.ui(draggable));
 
2077                         return this.element;
 
2086                         draggable: (c.currentItem || c.element),
 
2088                         position: c.position,
 
2089                         offset: c.positionAbs
 
2095 $.ui.intersect = function(draggable, droppable, toleranceMode) {
 
2097         if (!droppable.offset) {
 
2101         var draggableLeft, draggableTop,
 
2102                 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
 
2103                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
 
2104                 l = droppable.offset.left, r = l + droppable.proportions.width,
 
2105                 t = droppable.offset.top, b = t + droppable.proportions.height;
 
2107         switch (toleranceMode) {
 
2109                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
 
2111                         return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
 
2112                                 x2 - (draggable.helperProportions.width / 2) < r && // Left Half
 
2113                                 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
 
2114                                 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
 
2116                         draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
 
2117                         draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
 
2118                         return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
 
2121                                 (y1 >= t && y1 <= b) || // Top edge touching
 
2122                                 (y2 >= t && y2 <= b) || // Bottom edge touching
 
2123                                 (y1 < t && y2 > b)              // Surrounded vertically
 
2125                                 (x1 >= l && x1 <= r) || // Left edge touching
 
2126                                 (x2 >= l && x2 <= r) || // Right edge touching
 
2127                                 (x1 < l && x2 > r)              // Surrounded horizontally
 
2136         This manager tracks offsets of draggables and droppables
 
2140         droppables: { "default": [] },
 
2141         prepareOffsets: function(t, event) {
 
2144                         m = $.ui.ddmanager.droppables[t.options.scope] || [],
 
2145                         type = event ? event.type : null, // workaround for #2317
 
2146                         list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
 
2148                 droppablesLoop: for (i = 0; i < m.length; i++) {
 
2150                         //No disabled and non-accepted
 
2151                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
 
2155                         // Filter out elements in the current dragged item
 
2156                         for (j=0; j < list.length; j++) {
 
2157                                 if(list[j] === m[i].element[0]) {
 
2158                                         m[i].proportions.height = 0;
 
2159                                         continue droppablesLoop;
 
2163                         m[i].visible = m[i].element.css("display") !== "none";
 
2168                         //Activate the droppable if used directly from draggables
 
2169                         if(type === "mousedown") {
 
2170                                 m[i]._activate.call(m[i], event);
 
2173                         m[i].offset = m[i].element.offset();
 
2174                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
 
2179         drop: function(draggable, event) {
 
2181                 var dropped = false;
 
2182                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
 
2187                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
 
2188                                 dropped = this._drop.call(this, event) || dropped;
 
2191                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
 
2193                                 this.isover = false;
 
2194                                 this._deactivate.call(this, event);
 
2201         dragStart: function( draggable, event ) {
 
2202                 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
 
2203                 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
 
2204                         if( !draggable.options.refreshPositions ) {
 
2205                                 $.ui.ddmanager.prepareOffsets( draggable, event );
 
2209         drag: function(draggable, event) {
 
2211                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
 
2212                 if(draggable.options.refreshPositions) {
 
2213                         $.ui.ddmanager.prepareOffsets(draggable, event);
 
2216                 //Run through all droppables and check their positions based on specific tolerance options
 
2217                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
 
2219                         if(this.options.disabled || this.greedyChild || !this.visible) {
 
2223                         var parentInstance, scope, parent,
 
2224                                 intersects = $.ui.intersect(draggable, this, this.options.tolerance),
 
2225                                 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
 
2230                         if (this.options.greedy) {
 
2231                                 // find droppable parents with same scope
 
2232                                 scope = this.options.scope;
 
2233                                 parent = this.element.parents(":data(ui-droppable)").filter(function () {
 
2234                                         return $.data(this, "ui-droppable").options.scope === scope;
 
2237                                 if (parent.length) {
 
2238                                         parentInstance = $.data(parent[0], "ui-droppable");
 
2239                                         parentInstance.greedyChild = (c === "isover");
 
2243                         // we just moved into a greedy child
 
2244                         if (parentInstance && c === "isover") {
 
2245                                 parentInstance.isover = false;
 
2246                                 parentInstance.isout = true;
 
2247                                 parentInstance._out.call(parentInstance, event);
 
2251                         this[c === "isout" ? "isover" : "isout"] = false;
 
2252                         this[c === "isover" ? "_over" : "_out"].call(this, event);
 
2254                         // we just moved out of a greedy child
 
2255                         if (parentInstance && c === "isout") {
 
2256                                 parentInstance.isout = false;
 
2257                                 parentInstance.isover = true;
 
2258                                 parentInstance._over.call(parentInstance, event);
 
2263         dragStop: function( draggable, event ) {
 
2264                 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
 
2265                 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
 
2266                 if( !draggable.options.refreshPositions ) {
 
2267                         $.ui.ddmanager.prepareOffsets( draggable, event );
 
2273 (function( $, undefined ) {
 
2275 $.widget("ui.selectable", $.ui.mouse, {
 
2292         _create: function() {
 
2296                 this.element.addClass("ui-selectable");
 
2298                 this.dragged = false;
 
2300                 // cache selectee children based on filter
 
2301                 this.refresh = function() {
 
2302                         selectees = $(that.options.filter, that.element[0]);
 
2303                         selectees.addClass("ui-selectee");
 
2304                         selectees.each(function() {
 
2305                                 var $this = $(this),
 
2306                                         pos = $this.offset();
 
2307                                 $.data(this, "selectable-item", {
 
2312                                         right: pos.left + $this.outerWidth(),
 
2313                                         bottom: pos.top + $this.outerHeight(),
 
2314                                         startselected: false,
 
2315                                         selected: $this.hasClass("ui-selected"),
 
2316                                         selecting: $this.hasClass("ui-selecting"),
 
2317                                         unselecting: $this.hasClass("ui-unselecting")
 
2323                 this.selectees = selectees.addClass("ui-selectee");
 
2327                 this.helper = $("<div class='ui-selectable-helper'></div>");
 
2330         _destroy: function() {
 
2332                         .removeClass("ui-selectee")
 
2333                         .removeData("selectable-item");
 
2335                         .removeClass("ui-selectable ui-selectable-disabled");
 
2336                 this._mouseDestroy();
 
2339         _mouseStart: function(event) {
 
2341                         options = this.options;
 
2343                 this.opos = [event.pageX, event.pageY];
 
2345                 if (this.options.disabled) {
 
2349                 this.selectees = $(options.filter, this.element[0]);
 
2351                 this._trigger("start", event);
 
2353                 $(options.appendTo).append(this.helper);
 
2354                 // position helper (lasso)
 
2356                         "left": event.pageX,
 
2362                 if (options.autoRefresh) {
 
2366                 this.selectees.filter(".ui-selected").each(function() {
 
2367                         var selectee = $.data(this, "selectable-item");
 
2368                         selectee.startselected = true;
 
2369                         if (!event.metaKey && !event.ctrlKey) {
 
2370                                 selectee.$element.removeClass("ui-selected");
 
2371                                 selectee.selected = false;
 
2372                                 selectee.$element.addClass("ui-unselecting");
 
2373                                 selectee.unselecting = true;
 
2374                                 // selectable UNSELECTING callback
 
2375                                 that._trigger("unselecting", event, {
 
2376                                         unselecting: selectee.element
 
2381                 $(event.target).parents().addBack().each(function() {
 
2383                                 selectee = $.data(this, "selectable-item");
 
2385                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
 
2387                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
 
2388                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
 
2389                                 selectee.unselecting = !doSelect;
 
2390                                 selectee.selecting = doSelect;
 
2391                                 selectee.selected = doSelect;
 
2392                                 // selectable (UN)SELECTING callback
 
2394                                         that._trigger("selecting", event, {
 
2395                                                 selecting: selectee.element
 
2398                                         that._trigger("unselecting", event, {
 
2399                                                 unselecting: selectee.element
 
2408         _mouseDrag: function(event) {
 
2410                 this.dragged = true;
 
2412                 if (this.options.disabled) {
 
2418                         options = this.options,
 
2424                 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
 
2425                 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
 
2426                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
 
2428                 this.selectees.each(function() {
 
2429                         var selectee = $.data(this, "selectable-item"),
 
2432                         //prevent helper from being selected if appendTo: selectable
 
2433                         if (!selectee || selectee.element === that.element[0]) {
 
2437                         if (options.tolerance === "touch") {
 
2438                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
 
2439                         } else if (options.tolerance === "fit") {
 
2440                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
 
2445                                 if (selectee.selected) {
 
2446                                         selectee.$element.removeClass("ui-selected");
 
2447                                         selectee.selected = false;
 
2449                                 if (selectee.unselecting) {
 
2450                                         selectee.$element.removeClass("ui-unselecting");
 
2451                                         selectee.unselecting = false;
 
2453                                 if (!selectee.selecting) {
 
2454                                         selectee.$element.addClass("ui-selecting");
 
2455                                         selectee.selecting = true;
 
2456                                         // selectable SELECTING callback
 
2457                                         that._trigger("selecting", event, {
 
2458                                                 selecting: selectee.element
 
2463                                 if (selectee.selecting) {
 
2464                                         if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
 
2465                                                 selectee.$element.removeClass("ui-selecting");
 
2466                                                 selectee.selecting = false;
 
2467                                                 selectee.$element.addClass("ui-selected");
 
2468                                                 selectee.selected = true;
 
2470                                                 selectee.$element.removeClass("ui-selecting");
 
2471                                                 selectee.selecting = false;
 
2472                                                 if (selectee.startselected) {
 
2473                                                         selectee.$element.addClass("ui-unselecting");
 
2474                                                         selectee.unselecting = true;
 
2476                                                 // selectable UNSELECTING callback
 
2477                                                 that._trigger("unselecting", event, {
 
2478                                                         unselecting: selectee.element
 
2482                                 if (selectee.selected) {
 
2483                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
 
2484                                                 selectee.$element.removeClass("ui-selected");
 
2485                                                 selectee.selected = false;
 
2487                                                 selectee.$element.addClass("ui-unselecting");
 
2488                                                 selectee.unselecting = true;
 
2489                                                 // selectable UNSELECTING callback
 
2490                                                 that._trigger("unselecting", event, {
 
2491                                                         unselecting: selectee.element
 
2501         _mouseStop: function(event) {
 
2504                 this.dragged = false;
 
2506                 $(".ui-unselecting", this.element[0]).each(function() {
 
2507                         var selectee = $.data(this, "selectable-item");
 
2508                         selectee.$element.removeClass("ui-unselecting");
 
2509                         selectee.unselecting = false;
 
2510                         selectee.startselected = false;
 
2511                         that._trigger("unselected", event, {
 
2512                                 unselected: selectee.element
 
2515                 $(".ui-selecting", this.element[0]).each(function() {
 
2516                         var selectee = $.data(this, "selectable-item");
 
2517                         selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
 
2518                         selectee.selecting = false;
 
2519                         selectee.selected = true;
 
2520                         selectee.startselected = true;
 
2521                         that._trigger("selected", event, {
 
2522                                 selected: selectee.element
 
2525                 this._trigger("stop", event);
 
2527                 this.helper.remove();
 
2535 (function( $, undefined ) {
 
2537 /*jshint loopfunc: true */
 
2539 function isOverAxis( x, reference, size ) {
 
2540         return ( x > reference ) && ( x < ( reference + size ) );
 
2543 $.widget("ui.sortable", $.ui.mouse, {
 
2545         widgetEventPrefix: "sort",
 
2555                 forcePlaceholderSize: false,
 
2556                 forceHelperSize: false,
 
2565                 scrollSensitivity: 20,
 
2568                 tolerance: "intersect",
 
2585         _create: function() {
 
2587                 var o = this.options;
 
2588                 this.containerCache = {};
 
2589                 this.element.addClass("ui-sortable");
 
2594                 //Let's determine if the items are being displayed horizontally
 
2595                 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;
 
2597                 //Let's determine the parent's offset
 
2598                 this.offset = this.element.offset();
 
2600                 //Initialize mouse events for interaction
 
2608         _destroy: function() {
 
2610                         .removeClass("ui-sortable ui-sortable-disabled");
 
2611                 this._mouseDestroy();
 
2613                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
 
2614                         this.items[i].item.removeData(this.widgetName + "-item");
 
2620         _setOption: function(key, value){
 
2621                 if ( key === "disabled" ) {
 
2622                         this.options[ key ] = value;
 
2624                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
 
2626                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
 
2627                         $.Widget.prototype._setOption.apply(this, arguments);
 
2631         _mouseCapture: function(event, overrideHandle) {
 
2632                 var currentItem = null,
 
2633                         validHandle = false,
 
2636                 if (this.reverting) {
 
2640                 if(this.options.disabled || this.options.type === "static") {
 
2644                 //We have to refresh the items data once first
 
2645                 this._refreshItems(event);
 
2647                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
 
2648                 $(event.target).parents().each(function() {
 
2649                         if($.data(this, that.widgetName + "-item") === that) {
 
2650                                 currentItem = $(this);
 
2654                 if($.data(event.target, that.widgetName + "-item") === that) {
 
2655                         currentItem = $(event.target);
 
2661                 if(this.options.handle && !overrideHandle) {
 
2662                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
 
2663                                 if(this === event.target) {
 
2672                 this.currentItem = currentItem;
 
2673                 this._removeCurrentsFromItems();
 
2678         _mouseStart: function(event, overrideHandle, noActivation) {
 
2683                 this.currentContainer = this;
 
2685                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
 
2686                 this.refreshPositions();
 
2688                 //Create and append the visible helper
 
2689                 this.helper = this._createHelper(event);
 
2691                 //Cache the helper size
 
2692                 this._cacheHelperProportions();
 
2695                  * - Position generation -
 
2696                  * This block generates everything position related - it's the core of draggables.
 
2699                 //Cache the margins of the original element
 
2700                 this._cacheMargins();
 
2702                 //Get the next scrolling parent
 
2703                 this.scrollParent = this.helper.scrollParent();
 
2705                 //The element's absolute position on the page minus margins
 
2706                 this.offset = this.currentItem.offset();
 
2708                         top: this.offset.top - this.margins.top,
 
2709                         left: this.offset.left - this.margins.left
 
2712                 $.extend(this.offset, {
 
2713                         click: { //Where the click happened, relative to the element
 
2714                                 left: event.pageX - this.offset.left,
 
2715                                 top: event.pageY - this.offset.top
 
2717                         parent: this._getParentOffset(),
 
2718                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
 
2721                 // Only after we got the offset, we can change the helper's position to absolute
 
2722                 // TODO: Still need to figure out a way to make relative sorting possible
 
2723                 this.helper.css("position", "absolute");
 
2724                 this.cssPosition = this.helper.css("position");
 
2726                 //Generate the original position
 
2727                 this.originalPosition = this._generatePosition(event);
 
2728                 this.originalPageX = event.pageX;
 
2729                 this.originalPageY = event.pageY;
 
2731                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
 
2732                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
 
2734                 //Cache the former DOM position
 
2735                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
 
2737                 //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
 
2738                 if(this.helper[0] !== this.currentItem[0]) {
 
2739                         this.currentItem.hide();
 
2742                 //Create the placeholder
 
2743                 this._createPlaceholder();
 
2745                 //Set a containment if given in the options
 
2747                         this._setContainment();
 
2750                 if(o.cursor) { // cursor option
 
2751                         if ($("body").css("cursor")) {
 
2752                                 this._storedCursor = $("body").css("cursor");
 
2754                         $("body").css("cursor", o.cursor);
 
2757                 if(o.opacity) { // opacity option
 
2758                         if (this.helper.css("opacity")) {
 
2759                                 this._storedOpacity = this.helper.css("opacity");
 
2761                         this.helper.css("opacity", o.opacity);
 
2764                 if(o.zIndex) { // zIndex option
 
2765                         if (this.helper.css("zIndex")) {
 
2766                                 this._storedZIndex = this.helper.css("zIndex");
 
2768                         this.helper.css("zIndex", o.zIndex);
 
2772                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
 
2773                         this.overflowOffset = this.scrollParent.offset();
 
2777                 this._trigger("start", event, this._uiHash());
 
2779                 //Recache the helper size
 
2780                 if(!this._preserveHelperProportions) {
 
2781                         this._cacheHelperProportions();
 
2785                 //Post "activate" events to possible containers
 
2786                 if( !noActivation ) {
 
2787                         for ( i = this.containers.length - 1; i >= 0; i-- ) {
 
2788                                 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
 
2792                 //Prepare possible droppables
 
2793                 if($.ui.ddmanager) {
 
2794                         $.ui.ddmanager.current = this;
 
2797                 if ($.ui.ddmanager && !o.dropBehaviour) {
 
2798                         $.ui.ddmanager.prepareOffsets(this, event);
 
2801                 this.dragging = true;
 
2803                 this.helper.addClass("ui-sortable-helper");
 
2804                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
 
2809         _mouseDrag: function(event) {
 
2810                 var i, item, itemElement, intersection,
 
2814                 //Compute the helpers position
 
2815                 this.position = this._generatePosition(event);
 
2816                 this.positionAbs = this._convertPositionTo("absolute");
 
2818                 if (!this.lastPositionAbs) {
 
2819                         this.lastPositionAbs = this.positionAbs;
 
2823                 if(this.options.scroll) {
 
2824                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
 
2826                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
 
2827                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
 
2828                                 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
 
2829                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
 
2832                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
 
2833                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
 
2834                                 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
 
2835                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
 
2840                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
 
2841                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
 
2842                                 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
 
2843                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
 
2846                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
 
2847                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
 
2848                                 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
 
2849                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
 
2854                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
 
2855                                 $.ui.ddmanager.prepareOffsets(this, event);
 
2859                 //Regenerate the absolute position used for position checks
 
2860                 this.positionAbs = this._convertPositionTo("absolute");
 
2862                 //Set the helper position
 
2863                 if(!this.options.axis || this.options.axis !== "y") {
 
2864                         this.helper[0].style.left = this.position.left+"px";
 
2866                 if(!this.options.axis || this.options.axis !== "x") {
 
2867                         this.helper[0].style.top = this.position.top+"px";
 
2871                 for (i = this.items.length - 1; i >= 0; i--) {
 
2873                         //Cache variables and intersection, continue if no intersection
 
2874                         item = this.items[i];
 
2875                         itemElement = item.item[0];
 
2876                         intersection = this._intersectsWithPointer(item);
 
2877                         if (!intersection) {
 
2881                         // Only put the placeholder inside the current Container, skip all
 
2882                         // items form other containers. This works because when moving
 
2883                         // an item from one container to another the
 
2884                         // currentContainer is switched before the placeholder is moved.
 
2886                         // Without this moving items in "sub-sortables" can cause the placeholder to jitter
 
2887                         // beetween the outer and inner container.
 
2888                         if (item.instance !== this.currentContainer) {
 
2892                         // cannot intersect with itself
 
2893                         // no useless actions that have been done before
 
2894                         // no action if the item moved is the parent of the item checked
 
2895                         if (itemElement !== this.currentItem[0] &&
 
2896                                 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
 
2897                                 !$.contains(this.placeholder[0], itemElement) &&
 
2898                                 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
 
2901                                 this.direction = intersection === 1 ? "down" : "up";
 
2903                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
 
2904                                         this._rearrange(event, item);
 
2909                                 this._trigger("change", event, this._uiHash());
 
2914                 //Post events to containers
 
2915                 this._contactContainers(event);
 
2917                 //Interconnect with droppables
 
2918                 if($.ui.ddmanager) {
 
2919                         $.ui.ddmanager.drag(this, event);
 
2923                 this._trigger("sort", event, this._uiHash());
 
2925                 this.lastPositionAbs = this.positionAbs;
 
2930         _mouseStop: function(event, noPropagation) {
 
2936                 //If we are using droppables, inform the manager about the drop
 
2937                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
 
2938                         $.ui.ddmanager.drop(this, event);
 
2941                 if(this.options.revert) {
 
2943                                 cur = this.placeholder.offset();
 
2945                         this.reverting = true;
 
2947                         $(this.helper).animate({
 
2948                                 left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft),
 
2949                                 top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop)
 
2950                         }, parseInt(this.options.revert, 10) || 500, function() {
 
2954                         this._clear(event, noPropagation);
 
2961         cancel: function() {
 
2965                         this._mouseUp({ target: null });
 
2967                         if(this.options.helper === "original") {
 
2968                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
 
2970                                 this.currentItem.show();
 
2973                         //Post deactivating events to containers
 
2974                         for (var i = this.containers.length - 1; i >= 0; i--){
 
2975                                 this.containers[i]._trigger("deactivate", null, this._uiHash(this));
 
2976                                 if(this.containers[i].containerCache.over) {
 
2977                                         this.containers[i]._trigger("out", null, this._uiHash(this));
 
2978                                         this.containers[i].containerCache.over = 0;
 
2984                 if (this.placeholder) {
 
2985                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
 
2986                         if(this.placeholder[0].parentNode) {
 
2987                                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
 
2989                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
 
2990                                 this.helper.remove();
 
3000                         if(this.domPosition.prev) {
 
3001                                 $(this.domPosition.prev).after(this.currentItem);
 
3003                                 $(this.domPosition.parent).prepend(this.currentItem);
 
3011         serialize: function(o) {
 
3013                 var items = this._getItemsAsjQuery(o && o.connected),
 
3017                 $(items).each(function() {
 
3018                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
 
3020                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
 
3024                 if(!str.length && o.key) {
 
3025                         str.push(o.key + "=");
 
3028                 return str.join("&");
 
3032         toArray: function(o) {
 
3034                 var items = this._getItemsAsjQuery(o && o.connected),
 
3039                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
 
3044         /* Be careful with the following core functions */
 
3045         _intersectsWith: function(item) {
 
3047                 var x1 = this.positionAbs.left,
 
3048                         x2 = x1 + this.helperProportions.width,
 
3049                         y1 = this.positionAbs.top,
 
3050                         y2 = y1 + this.helperProportions.height,
 
3054                         b = t + item.height,
 
3055                         dyClick = this.offset.click.top,
 
3056                         dxClick = this.offset.click.left,
 
3057                         isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
 
3059                 if ( this.options.tolerance === "pointer" ||
 
3060                         this.options.forcePointerForContainers ||
 
3061                         (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
 
3063                         return isOverElement;
 
3066                         return (l < x1 + (this.helperProportions.width / 2) && // Right Half
 
3067                                 x2 - (this.helperProportions.width / 2) < r && // Left Half
 
3068                                 t < y1 + (this.helperProportions.height / 2) && // Bottom Half
 
3069                                 y2 - (this.helperProportions.height / 2) < b ); // Top Half
 
3074         _intersectsWithPointer: function(item) {
 
3076                 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
 
3077                         isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
 
3078                         isOverElement = isOverElementHeight && isOverElementWidth,
 
3079                         verticalDirection = this._getDragVerticalDirection(),
 
3080                         horizontalDirection = this._getDragHorizontalDirection();
 
3082                 if (!isOverElement) {
 
3086                 return this.floating ?
 
3087                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
 
3088                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
 
3092         _intersectsWithSides: function(item) {
 
3094                 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
 
3095                         isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
 
3096                         verticalDirection = this._getDragVerticalDirection(),
 
3097                         horizontalDirection = this._getDragHorizontalDirection();
 
3099                 if (this.floating && horizontalDirection) {
 
3100                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
 
3102                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
 
3107         _getDragVerticalDirection: function() {
 
3108                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
 
3109                 return delta !== 0 && (delta > 0 ? "down" : "up");
 
3112         _getDragHorizontalDirection: function() {
 
3113                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
 
3114                 return delta !== 0 && (delta > 0 ? "right" : "left");
 
3117         refresh: function(event) {
 
3118                 this._refreshItems(event);
 
3119                 this.refreshPositions();
 
3123         _connectWith: function() {
 
3124                 var options = this.options;
 
3125                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
 
3128         _getItemsAsjQuery: function(connected) {
 
3130                 var i, j, cur, inst,
 
3133                         connectWith = this._connectWith();
 
3135                 if(connectWith && connected) {
 
3136                         for (i = connectWith.length - 1; i >= 0; i--){
 
3137                                 cur = $(connectWith[i]);
 
3138                                 for ( j = cur.length - 1; j >= 0; j--){
 
3139                                         inst = $.data(cur[j], this.widgetFullName);
 
3140                                         if(inst && inst !== this && !inst.options.disabled) {
 
3141                                                 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]);
 
3147                 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]);
 
3149                 for (i = queries.length - 1; i >= 0; i--){
 
3150                         queries[i][0].each(function() {
 
3159         _removeCurrentsFromItems: function() {
 
3161                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
 
3163                 this.items = $.grep(this.items, function (item) {
 
3164                         for (var j=0; j < list.length; j++) {
 
3165                                 if(list[j] === item.item[0]) {
 
3174         _refreshItems: function(event) {
 
3177                 this.containers = [this];
 
3179                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
 
3181                         queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
 
3182                         connectWith = this._connectWith();
 
3184                 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
 
3185                         for (i = connectWith.length - 1; i >= 0; i--){
 
3186                                 cur = $(connectWith[i]);
 
3187                                 for (j = cur.length - 1; j >= 0; j--){
 
3188                                         inst = $.data(cur[j], this.widgetFullName);
 
3189                                         if(inst && inst !== this && !inst.options.disabled) {
 
3190                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
 
3191                                                 this.containers.push(inst);
 
3197                 for (i = queries.length - 1; i >= 0; i--) {
 
3198                         targetData = queries[i][1];
 
3199                         _queries = queries[i][0];
 
3201                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
 
3202                                 item = $(_queries[j]);
 
3204                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
 
3208                                         instance: targetData,
 
3209                                         width: 0, height: 0,
 
3217         refreshPositions: function(fast) {
 
3219                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
 
3220                 if(this.offsetParent && this.helper) {
 
3221                         this.offset.parent = this._getParentOffset();
 
3226                 for (i = this.items.length - 1; i >= 0; i--){
 
3227                         item = this.items[i];
 
3229                         //We ignore calculating positions of all connected containers when we're not over them
 
3230                         if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
 
3234                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
 
3237                                 item.width = t.outerWidth();
 
3238                                 item.height = t.outerHeight();
 
3246                 if(this.options.custom && this.options.custom.refreshContainers) {
 
3247                         this.options.custom.refreshContainers.call(this);
 
3249                         for (i = this.containers.length - 1; i >= 0; i--){
 
3250                                 p = this.containers[i].element.offset();
 
3251                                 this.containers[i].containerCache.left = p.left;
 
3252                                 this.containers[i].containerCache.top = p.top;
 
3253                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
 
3254                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
 
3261         _createPlaceholder: function(that) {
 
3262                 that = that || this;
 
3266                 if(!o.placeholder || o.placeholder.constructor === String) {
 
3267                         className = o.placeholder;
 
3269                                 element: function() {
 
3271                                         var el = $(document.createElement(that.currentItem[0].nodeName))
 
3272                                                 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
 
3273                                                 .removeClass("ui-sortable-helper")[0];
 
3276                                                 el.style.visibility = "hidden";
 
3281                                 update: function(container, p) {
 
3283                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
 
3284                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
 
3285                                         if(className && !o.forcePlaceholderSize) {
 
3289                                         //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
 
3290                                         if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
 
3291                                         if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
 
3296                 //Create the placeholder
 
3297                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
 
3299                 //Append it after the actual current item
 
3300                 that.currentItem.after(that.placeholder);
 
3302                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
 
3303                 o.placeholder.update(that, that.placeholder);
 
3307         _contactContainers: function(event) {
 
3308                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
 
3309                         innermostContainer = null,
 
3310                         innermostIndex = null;
 
3312                 // get innermost container that intersects with item
 
3313                 for (i = this.containers.length - 1; i >= 0; i--) {
 
3315                         // never consider a container that's located within the item itself
 
3316                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
 
3320                         if(this._intersectsWith(this.containers[i].containerCache)) {
 
3322                                 // if we've already found a container and it's more "inner" than this, then continue
 
3323                                 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
 
3327                                 innermostContainer = this.containers[i];
 
3331                                 // container doesn't intersect. trigger "out" event if necessary
 
3332                                 if(this.containers[i].containerCache.over) {
 
3333                                         this.containers[i]._trigger("out", event, this._uiHash(this));
 
3334                                         this.containers[i].containerCache.over = 0;
 
3340                 // if no intersecting containers found, return
 
3341                 if(!innermostContainer) {
 
3345                 // move the item into the container if it's not there already
 
3346                 if(this.containers.length === 1) {
 
3347                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
 
3348                         this.containers[innermostIndex].containerCache.over = 1;
 
3351                         //When entering a new container, we will find the item with the least distance and append our item near it
 
3353                         itemWithLeastDistance = null;
 
3354                         posProperty = this.containers[innermostIndex].floating ? "left" : "top";
 
3355                         sizeProperty = this.containers[innermostIndex].floating ? "width" : "height";
 
3356                         base = this.positionAbs[posProperty] + this.offset.click[posProperty];
 
3357                         for (j = this.items.length - 1; j >= 0; j--) {
 
3358                                 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
 
3361                                 if(this.items[j].item[0] === this.currentItem[0]) {
 
3364                                 cur = this.items[j].item.offset()[posProperty];
 
3366                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
 
3368                                         cur += this.items[j][sizeProperty];
 
3371                                 if(Math.abs(cur - base) < dist) {
 
3372                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
 
3373                                         this.direction = nearBottom ? "up": "down";
 
3377                         //Check if dropOnEmpty is enabled
 
3378                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
 
3382                         this.currentContainer = this.containers[innermostIndex];
 
3383                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
 
3384                         this._trigger("change", event, this._uiHash());
 
3385                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
 
3387                         //Update the placeholder
 
3388                         this.options.placeholder.update(this.currentContainer, this.placeholder);
 
3390                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
 
3391                         this.containers[innermostIndex].containerCache.over = 1;
 
3397         _createHelper: function(event) {
 
3399                 var o = this.options,
 
3400                         helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
 
3402                 //Add the helper to the DOM if that didn't happen already
 
3403                 if(!helper.parents("body").length) {
 
3404                         $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
 
3407                 if(helper[0] === this.currentItem[0]) {
 
3408                         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") };
 
3411                 if(!helper[0].style.width || o.forceHelperSize) {
 
3412                         helper.width(this.currentItem.width());
 
3414                 if(!helper[0].style.height || o.forceHelperSize) {
 
3415                         helper.height(this.currentItem.height());
 
3422         _adjustOffsetFromHelper: function(obj) {
 
3423                 if (typeof obj === "string") {
 
3424                         obj = obj.split(" ");
 
3426                 if ($.isArray(obj)) {
 
3427                         obj = {left: +obj[0], top: +obj[1] || 0};
 
3429                 if ("left" in obj) {
 
3430                         this.offset.click.left = obj.left + this.margins.left;
 
3432                 if ("right" in obj) {
 
3433                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 
3436                         this.offset.click.top = obj.top + this.margins.top;
 
3438                 if ("bottom" in obj) {
 
3439                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 
3443         _getParentOffset: function() {
 
3446                 //Get the offsetParent and cache its position
 
3447                 this.offsetParent = this.helper.offsetParent();
 
3448                 var po = this.offsetParent.offset();
 
3450                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
 
3451                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
 
3452                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
 
3453                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
 
3454                 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
 
3455                         po.left += this.scrollParent.scrollLeft();
 
3456                         po.top += this.scrollParent.scrollTop();
 
3459                 // This needs to be actually done for all browsers, since pageX/pageY includes this information
 
3460                 // with an ugly IE fix
 
3461                 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
 
3462                         po = { top: 0, left: 0 };
 
3466                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
 
3467                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
 
3472         _getRelativeOffset: function() {
 
3474                 if(this.cssPosition === "relative") {
 
3475                         var p = this.currentItem.position();
 
3477                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
 
3478                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
 
3481                         return { top: 0, left: 0 };
 
3486         _cacheMargins: function() {
 
3488                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
 
3489                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
 
3493         _cacheHelperProportions: function() {
 
3494                 this.helperProportions = {
 
3495                         width: this.helper.outerWidth(),
 
3496                         height: this.helper.outerHeight()
 
3500         _setContainment: function() {
 
3504                 if(o.containment === "parent") {
 
3505                         o.containment = this.helper[0].parentNode;
 
3507                 if(o.containment === "document" || o.containment === "window") {
 
3508                         this.containment = [
 
3509                                 0 - this.offset.relative.left - this.offset.parent.left,
 
3510                                 0 - this.offset.relative.top - this.offset.parent.top,
 
3511                                 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
 
3512                                 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
 
3516                 if(!(/^(document|window|parent)$/).test(o.containment)) {
 
3517                         ce = $(o.containment)[0];
 
3518                         co = $(o.containment).offset();
 
3519                         over = ($(ce).css("overflow") !== "hidden");
 
3521                         this.containment = [
 
3522                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
 
3523                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
 
3524                                 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,
 
3525                                 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
 
3531         _convertPositionTo: function(d, pos) {
 
3534                         pos = this.position;
 
3536                 var mod = d === "absolute" ? 1 : -1,
 
3537                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
 
3538                         scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 
3542                                 pos.top +                                                                                                                               // The absolute mouse position
 
3543                                 this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
 
3544                                 this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
 
3545                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
 
3548                                 pos.left +                                                                                                                              // The absolute mouse position
 
3549                                 this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
 
3550                                 this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
 
3551                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
 
3557         _generatePosition: function(event) {
 
3561                         pageX = event.pageX,
 
3562                         pageY = event.pageY,
 
3563                         scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
 
3565                 // This is another very weird special case that only happens for relative elements:
 
3566                 // 1. If the css position is relative
 
3567                 // 2. and the scroll parent is the document or similar to the offset parent
 
3568                 // we have to refresh the relative offset during the scroll so there are no jumps
 
3569                 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
 
3570                         this.offset.relative = this._getRelativeOffset();
 
3574                  * - Position constraining -
 
3575                  * Constrain the position to a mix of grid, containment.
 
3578                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
 
3580                         if(this.containment) {
 
3581                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
 
3582                                         pageX = this.containment[0] + this.offset.click.left;
 
3584                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
 
3585                                         pageY = this.containment[1] + this.offset.click.top;
 
3587                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
 
3588                                         pageX = this.containment[2] + this.offset.click.left;
 
3590                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
 
3591                                         pageY = this.containment[3] + this.offset.click.top;
 
3596                                 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
 
3597                                 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;
 
3599                                 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
 
3600                                 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;
 
3607                                 pageY -                                                                                                                         // The absolute mouse position
 
3608                                 this.offset.click.top -                                                                                                 // Click offset (relative to the element)
 
3609                                 this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
 
3610                                 this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
 
3611                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
 
3614                                 pageX -                                                                                                                         // The absolute mouse position
 
3615                                 this.offset.click.left -                                                                                                // Click offset (relative to the element)
 
3616                                 this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
 
3617                                 this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
 
3618                                 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
 
3624         _rearrange: function(event, i, a, hardRefresh) {
 
3626                 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));
 
3628                 //Various things done here to improve the performance:
 
3629                 // 1. we create a setTimeout, that calls refreshPositions
 
3630                 // 2. on the instance, we have a counter variable, that get's higher after every append
 
3631                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
 
3632                 // 4. this lets only the last addition to the timeout stack through
 
3633                 this.counter = this.counter ? ++this.counter : 1;
 
3634                 var counter = this.counter;
 
3636                 this._delay(function() {
 
3637                         if(counter === this.counter) {
 
3638                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
 
3644         _clear: function(event, noPropagation) {
 
3646                 this.reverting = false;
 
3647                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
 
3648                 // everything else normalized again
 
3650                         delayedTriggers = [];
 
3652                 // We first have to update the dom position of the actual currentItem
 
3653                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
 
3654                 if(!this._noFinalSort && this.currentItem.parent().length) {
 
3655                         this.placeholder.before(this.currentItem);
 
3657                 this._noFinalSort = null;
 
3659                 if(this.helper[0] === this.currentItem[0]) {
 
3660                         for(i in this._storedCSS) {
 
3661                                 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
 
3662                                         this._storedCSS[i] = "";
 
3665                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
 
3667                         this.currentItem.show();
 
3670                 if(this.fromOutside && !noPropagation) {
 
3671                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
 
3673                 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
 
3674                         delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
 
3677                 // Check if the items Container has Changed and trigger appropriate
 
3679                 if (this !== this.currentContainer) {
 
3680                         if(!noPropagation) {
 
3681                                 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
 
3682                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
 
3683                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
 
3688                 //Post events to containers
 
3689                 for (i = this.containers.length - 1; i >= 0; i--){
 
3690                         if(!noPropagation) {
 
3691                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
 
3693                         if(this.containers[i].containerCache.over) {
 
3694                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
 
3695                                 this.containers[i].containerCache.over = 0;
 
3699                 //Do what was originally in plugins
 
3700                 if(this._storedCursor) {
 
3701                         $("body").css("cursor", this._storedCursor);
 
3703                 if(this._storedOpacity) {
 
3704                         this.helper.css("opacity", this._storedOpacity);
 
3706                 if(this._storedZIndex) {
 
3707                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
 
3710                 this.dragging = false;
 
3711                 if(this.cancelHelperRemoval) {
 
3712                         if(!noPropagation) {
 
3713                                 this._trigger("beforeStop", event, this._uiHash());
 
3714                                 for (i=0; i < delayedTriggers.length; i++) {
 
3715                                         delayedTriggers[i].call(this, event);
 
3716                                 } //Trigger all delayed events
 
3717                                 this._trigger("stop", event, this._uiHash());
 
3720                         this.fromOutside = false;
 
3724                 if(!noPropagation) {
 
3725                         this._trigger("beforeStop", event, this._uiHash());
 
3728                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
 
3729                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
 
3731                 if(this.helper[0] !== this.currentItem[0]) {
 
3732                         this.helper.remove();
 
3736                 if(!noPropagation) {
 
3737                         for (i=0; i < delayedTriggers.length; i++) {
 
3738                                 delayedTriggers[i].call(this, event);
 
3739                         } //Trigger all delayed events
 
3740                         this._trigger("stop", event, this._uiHash());
 
3743                 this.fromOutside = false;
 
3748         _trigger: function() {
 
3749                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
 
3754         _uiHash: function(_inst) {
 
3755                 var inst = _inst || this;
 
3757                         helper: inst.helper,
 
3758                         placeholder: inst.placeholder || $([]),
 
3759                         position: inst.position,
 
3760                         originalPosition: inst.originalPosition,
 
3761                         offset: inst.positionAbs,
 
3762                         item: inst.currentItem,
 
3763                         sender: _inst ? _inst.element : null
 
3770 ;(jQuery.effects || (function($, undefined) {
 
3772 var dataSpace = "ui-effects-";
 
3779  * jQuery Color Animations v2.1.2
 
3780  * https://github.com/jquery/jquery-color
 
3782  * Copyright 2013 jQuery Foundation and other contributors
 
3783  * Released under the MIT license.
 
3784  * http://jquery.org/license
 
3786  * Date: Wed Jan 16 08:47:09 2013 -0600
 
3788 (function( jQuery, undefined ) {
 
3790         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
 
3792         // plusequals test for += 100 -= 100
 
3793         rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
 
3794         // a set of RE's that can match strings and generate color tuples.
 
3796                         re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
 
3797                         parse: function( execResult ) {
 
3806                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
 
3807                         parse: function( execResult ) {
 
3809                                         execResult[ 1 ] * 2.55,
 
3810                                         execResult[ 2 ] * 2.55,
 
3811                                         execResult[ 3 ] * 2.55,
 
3816                         // this regex ignores A-F because it's compared against an already lowercased string
 
3817                         re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
 
3818                         parse: function( execResult ) {
 
3820                                         parseInt( execResult[ 1 ], 16 ),
 
3821                                         parseInt( execResult[ 2 ], 16 ),
 
3822                                         parseInt( execResult[ 3 ], 16 )
 
3826                         // this regex ignores A-F because it's compared against an already lowercased string
 
3827                         re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
 
3828                         parse: function( execResult ) {
 
3830                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
 
3831                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
 
3832                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
 
3836                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
 
3838                         parse: function( execResult ) {
 
3841                                         execResult[ 2 ] / 100,
 
3842                                         execResult[ 3 ] / 100,
 
3849         color = jQuery.Color = function( color, green, blue, alpha ) {
 
3850                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
 
3900         support = color.support = {},
 
3902         // element for support tests
 
3903         supportElem = jQuery( "<p>" )[ 0 ],
 
3905         // colors = jQuery.Color.names
 
3908         // local aliases of functions called often
 
3911 // determine rgba support immediately
 
3912 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
 
3913 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
 
3915 // define cache name and alpha properties
 
3916 // for rgba and hsla spaces
 
3917 each( spaces, function( spaceName, space ) {
 
3918         space.cache = "_" + spaceName;
 
3919         space.props.alpha = {
 
3926 function clamp( value, prop, allowEmpty ) {
 
3927         var type = propTypes[ prop.type ] || {};
 
3929         if ( value == null ) {
 
3930                 return (allowEmpty || !prop.def) ? null : prop.def;
 
3933         // ~~ is an short way of doing floor for positive numbers
 
3934         value = type.floor ? ~~value : parseFloat( value );
 
3936         // IE will pass in empty strings as value for alpha,
 
3937         // which will hit this case
 
3938         if ( isNaN( value ) ) {
 
3943                 // we add mod before modding to make sure that negatives values
 
3944                 // get converted properly: -10 -> 350
 
3945                 return (value + type.mod) % type.mod;
 
3948         // for now all property types without mod have min and max
 
3949         return 0 > value ? 0 : type.max < value ? type.max : value;
 
3952 function stringParse( string ) {
 
3954                 rgba = inst._rgba = [];
 
3956         string = string.toLowerCase();
 
3958         each( stringParsers, function( i, parser ) {
 
3960                         match = parser.re.exec( string ),
 
3961                         values = match && parser.parse( match ),
 
3962                         spaceName = parser.space || "rgba";
 
3965                         parsed = inst[ spaceName ]( values );
 
3967                         // if this was an rgba parse the assignment might happen twice
 
3969                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
 
3970                         rgba = inst._rgba = parsed._rgba;
 
3972                         // exit each( stringParsers ) here because we matched
 
3977         // Found a stringParser that handled it
 
3978         if ( rgba.length ) {
 
3980                 // if this came from a parsed string, force "transparent" when alpha is 0
 
3981                 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
 
3982                 if ( rgba.join() === "0,0,0,0" ) {
 
3983                         jQuery.extend( rgba, colors.transparent );
 
3989         return colors[ string ];
 
3992 color.fn = jQuery.extend( color.prototype, {
 
3993         parse: function( red, green, blue, alpha ) {
 
3994                 if ( red === undefined ) {
 
3995                         this._rgba = [ null, null, null, null ];
 
3998                 if ( red.jquery || red.nodeType ) {
 
3999                         red = jQuery( red ).css( green );
 
4004                         type = jQuery.type( red ),
 
4005                         rgba = this._rgba = [];
 
4007                 // more than 1 argument specified - assume ( red, green, blue, alpha )
 
4008                 if ( green !== undefined ) {
 
4009                         red = [ red, green, blue, alpha ];
 
4013                 if ( type === "string" ) {
 
4014                         return this.parse( stringParse( red ) || colors._default );
 
4017                 if ( type === "array" ) {
 
4018                         each( spaces.rgba.props, function( key, prop ) {
 
4019                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
 
4024                 if ( type === "object" ) {
 
4025                         if ( red instanceof color ) {
 
4026                                 each( spaces, function( spaceName, space ) {
 
4027                                         if ( red[ space.cache ] ) {
 
4028                                                 inst[ space.cache ] = red[ space.cache ].slice();
 
4032                                 each( spaces, function( spaceName, space ) {
 
4033                                         var cache = space.cache;
 
4034                                         each( space.props, function( key, prop ) {
 
4036                                                 // if the cache doesn't exist, and we know how to convert
 
4037                                                 if ( !inst[ cache ] && space.to ) {
 
4039                                                         // if the value was null, we don't need to copy it
 
4040                                                         // if the key was alpha, we don't need to copy it either
 
4041                                                         if ( key === "alpha" || red[ key ] == null ) {
 
4044                                                         inst[ cache ] = space.to( inst._rgba );
 
4047                                                 // this is the only case where we allow nulls for ALL properties.
 
4048                                                 // call clamp with alwaysAllowEmpty
 
4049                                                 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
 
4052                                         // everything defined but alpha?
 
4053                                         if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
 
4054                                                 // use the default of 1
 
4055                                                 inst[ cache ][ 3 ] = 1;
 
4057                                                         inst._rgba = space.from( inst[ cache ] );
 
4065         is: function( compare ) {
 
4066                 var is = color( compare ),
 
4070                 each( spaces, function( _, space ) {
 
4072                                 isCache = is[ space.cache ];
 
4074                                 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
 
4075                                 each( space.props, function( _, prop ) {
 
4076                                         if ( isCache[ prop.idx ] != null ) {
 
4077                                                 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
 
4086         _space: function() {
 
4089                 each( spaces, function( spaceName, space ) {
 
4090                         if ( inst[ space.cache ] ) {
 
4091                                 used.push( spaceName );
 
4096         transition: function( other, distance ) {
 
4097                 var end = color( other ),
 
4098                         spaceName = end._space(),
 
4099                         space = spaces[ spaceName ],
 
4100                         startColor = this.alpha() === 0 ? color( "transparent" ) : this,
 
4101                         start = startColor[ space.cache ] || space.to( startColor._rgba ),
 
4102                         result = start.slice();
 
4104                 end = end[ space.cache ];
 
4105                 each( space.props, function( key, prop ) {
 
4106                         var index = prop.idx,
 
4107                                 startValue = start[ index ],
 
4108                                 endValue = end[ index ],
 
4109                                 type = propTypes[ prop.type ] || {};
 
4111                         // if null, don't override start value
 
4112                         if ( endValue === null ) {
 
4115                         // if null - use end
 
4116                         if ( startValue === null ) {
 
4117                                 result[ index ] = endValue;
 
4120                                         if ( endValue - startValue > type.mod / 2 ) {
 
4121                                                 startValue += type.mod;
 
4122                                         } else if ( startValue - endValue > type.mod / 2 ) {
 
4123                                                 startValue -= type.mod;
 
4126                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
 
4129                 return this[ spaceName ]( result );
 
4131         blend: function( opaque ) {
 
4132                 // if we are already opaque - return ourself
 
4133                 if ( this._rgba[ 3 ] === 1 ) {
 
4137                 var rgb = this._rgba.slice(),
 
4139                         blend = color( opaque )._rgba;
 
4141                 return color( jQuery.map( rgb, function( v, i ) {
 
4142                         return ( 1 - a ) * blend[ i ] + a * v;
 
4145         toRgbaString: function() {
 
4146                 var prefix = "rgba(",
 
4147                         rgba = jQuery.map( this._rgba, function( v, i ) {
 
4148                                 return v == null ? ( i > 2 ? 1 : 0 ) : v;
 
4151                 if ( rgba[ 3 ] === 1 ) {
 
4156                 return prefix + rgba.join() + ")";
 
4158         toHslaString: function() {
 
4159                 var prefix = "hsla(",
 
4160                         hsla = jQuery.map( this.hsla(), function( v, i ) {
 
4167                                         v = Math.round( v * 100 ) + "%";
 
4172                 if ( hsla[ 3 ] === 1 ) {
 
4176                 return prefix + hsla.join() + ")";
 
4178         toHexString: function( includeAlpha ) {
 
4179                 var rgba = this._rgba.slice(),
 
4182                 if ( includeAlpha ) {
 
4183                         rgba.push( ~~( alpha * 255 ) );
 
4186                 return "#" + jQuery.map( rgba, function( v ) {
 
4188                         // default to 0 when nulls exist
 
4189                         v = ( v || 0 ).toString( 16 );
 
4190                         return v.length === 1 ? "0" + v : v;
 
4193         toString: function() {
 
4194                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
 
4197 color.fn.parse.prototype = color.fn;
 
4199 // hsla conversions adapted from:
 
4200 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
 
4202 function hue2rgb( p, q, h ) {
 
4205                 return p + (q - p) * h * 6;
 
4211                 return p + (q - p) * ((2/3) - h) * 6;
 
4216 spaces.hsla.to = function ( rgba ) {
 
4217         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
 
4218                 return [ null, null, null, rgba[ 3 ] ];
 
4220         var r = rgba[ 0 ] / 255,
 
4221                 g = rgba[ 1 ] / 255,
 
4222                 b = rgba[ 2 ] / 255,
 
4224                 max = Math.max( r, g, b ),
 
4225                 min = Math.min( r, g, b ),
 
4231         if ( min === max ) {
 
4233         } else if ( r === max ) {
 
4234                 h = ( 60 * ( g - b ) / diff ) + 360;
 
4235         } else if ( g === max ) {
 
4236                 h = ( 60 * ( b - r ) / diff ) + 120;
 
4238                 h = ( 60 * ( r - g ) / diff ) + 240;
 
4241         // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
 
4242         // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
 
4245         } else if ( l <= 0.5 ) {
 
4248                 s = diff / ( 2 - add );
 
4250         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
 
4253 spaces.hsla.from = function ( hsla ) {
 
4254         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
 
4255                 return [ null, null, null, hsla[ 3 ] ];
 
4257         var h = hsla[ 0 ] / 360,
 
4261                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
 
4265                 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
 
4266                 Math.round( hue2rgb( p, q, h ) * 255 ),
 
4267                 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
 
4273 each( spaces, function( spaceName, space ) {
 
4274         var props = space.props,
 
4275                 cache = space.cache,
 
4279         // makes rgba() and hsla()
 
4280         color.fn[ spaceName ] = function( value ) {
 
4282                 // generate a cache for this space if it doesn't exist
 
4283                 if ( to && !this[ cache ] ) {
 
4284                         this[ cache ] = to( this._rgba );
 
4286                 if ( value === undefined ) {
 
4287                         return this[ cache ].slice();
 
4291                         type = jQuery.type( value ),
 
4292                         arr = ( type === "array" || type === "object" ) ? value : arguments,
 
4293                         local = this[ cache ].slice();
 
4295                 each( props, function( key, prop ) {
 
4296                         var val = arr[ type === "object" ? key : prop.idx ];
 
4297                         if ( val == null ) {
 
4298                                 val = local[ prop.idx ];
 
4300                         local[ prop.idx ] = clamp( val, prop );
 
4304                         ret = color( from( local ) );
 
4305                         ret[ cache ] = local;
 
4308                         return color( local );
 
4312         // makes red() green() blue() alpha() hue() saturation() lightness()
 
4313         each( props, function( key, prop ) {
 
4314                 // alpha is included in more than one space
 
4315                 if ( color.fn[ key ] ) {
 
4318                 color.fn[ key ] = function( value ) {
 
4319                         var vtype = jQuery.type( value ),
 
4320                                 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
 
4321                                 local = this[ fn ](),
 
4322                                 cur = local[ prop.idx ],
 
4325                         if ( vtype === "undefined" ) {
 
4329                         if ( vtype === "function" ) {
 
4330                                 value = value.call( this, cur );
 
4331                                 vtype = jQuery.type( value );
 
4333                         if ( value == null && prop.empty ) {
 
4336                         if ( vtype === "string" ) {
 
4337                                 match = rplusequals.exec( value );
 
4339                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
 
4342                         local[ prop.idx ] = value;
 
4343                         return this[ fn ]( local );
 
4348 // add cssHook and .fx.step function for each named hook.
 
4349 // accept a space separated string of properties
 
4350 color.hook = function( hook ) {
 
4351         var hooks = hook.split( " " );
 
4352         each( hooks, function( i, hook ) {
 
4353                 jQuery.cssHooks[ hook ] = {
 
4354                         set: function( elem, value ) {
 
4355                                 var parsed, curElem,
 
4356                                         backgroundColor = "";
 
4358                                 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
 
4359                                         value = color( parsed || value );
 
4360                                         if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
 
4361                                                 curElem = hook === "backgroundColor" ? elem.parentNode : elem;
 
4363                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
 
4364                                                         curElem && curElem.style
 
4367                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
 
4368                                                                 curElem = curElem.parentNode;
 
4373                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
 
4378                                         value = value.toRgbaString();
 
4381                                         elem.style[ hook ] = value;
 
4383                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
 
4387                 jQuery.fx.step[ hook ] = function( fx ) {
 
4388                         if ( !fx.colorInit ) {
 
4389                                 fx.start = color( fx.elem, hook );
 
4390                                 fx.end = color( fx.end );
 
4391                                 fx.colorInit = true;
 
4393                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
 
4399 color.hook( stepHooks );
 
4401 jQuery.cssHooks.borderColor = {
 
4402         expand: function( value ) {
 
4405                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
 
4406                         expanded[ "border" + part + "Color" ] = value;
 
4412 // Basic color names only.
 
4413 // Usage of any of the other color names requires adding yourself or including
 
4414 // jquery.color.svg-names.js.
 
4415 colors = jQuery.Color.names = {
 
4416         // 4.1. Basic color keywords
 
4434         // 4.2.3. "transparent" color keyword
 
4435         transparent: [ null, null, null, 0 ],
 
4443 /******************************************************************************/
 
4444 /****************************** CLASS ANIMATIONS ******************************/
 
4445 /******************************************************************************/
 
4448 var classAnimationActions = [ "add", "remove", "toggle" ],
 
4461 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
 
4462         $.fx.step[ prop ] = function( fx ) {
 
4463                 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
 
4464                         jQuery.style( fx.elem, prop, fx.end );
 
4470 function getElementStyles( elem ) {
 
4472                 style = elem.ownerDocument.defaultView ?
 
4473                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
 
4477         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
 
4481                         if ( typeof style[ key ] === "string" ) {
 
4482                                 styles[ $.camelCase( key ) ] = style[ key ];
 
4485         // support: Opera, IE <9
 
4487                 for ( key in style ) {
 
4488                         if ( typeof style[ key ] === "string" ) {
 
4489                                 styles[ key ] = style[ key ];
 
4498 function styleDifference( oldStyle, newStyle ) {
 
4502         for ( name in newStyle ) {
 
4503                 value = newStyle[ name ];
 
4504                 if ( oldStyle[ name ] !== value ) {
 
4505                         if ( !shorthandStyles[ name ] ) {
 
4506                                 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
 
4507                                         diff[ name ] = value;
 
4516 // support: jQuery <1.8
 
4517 if ( !$.fn.addBack ) {
 
4518         $.fn.addBack = function( selector ) {
 
4519                 return this.add( selector == null ?
 
4520                         this.prevObject : this.prevObject.filter( selector )
 
4525 $.effects.animateClass = function( value, duration, easing, callback ) {
 
4526         var o = $.speed( duration, easing, callback );
 
4528         return this.queue( function() {
 
4529                 var animated = $( this ),
 
4530                         baseClass = animated.attr( "class" ) || "",
 
4532                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
 
4534                 // map the animated objects to store the original styles.
 
4535                 allAnimations = allAnimations.map(function() {
 
4539                                 start: getElementStyles( this )
 
4543                 // apply class change
 
4544                 applyClassChange = function() {
 
4545                         $.each( classAnimationActions, function(i, action) {
 
4546                                 if ( value[ action ] ) {
 
4547                                         animated[ action + "Class" ]( value[ action ] );
 
4553                 // map all animated objects again - calculate new styles and diff
 
4554                 allAnimations = allAnimations.map(function() {
 
4555                         this.end = getElementStyles( this.el[ 0 ] );
 
4556                         this.diff = styleDifference( this.start, this.end );
 
4560                 // apply original class
 
4561                 animated.attr( "class", baseClass );
 
4563                 // map all animated objects again - this time collecting a promise
 
4564                 allAnimations = allAnimations.map(function() {
 
4565                         var styleInfo = this,
 
4567                                 opts = $.extend({}, o, {
 
4569                                         complete: function() {
 
4570                                                 dfd.resolve( styleInfo );
 
4574                         this.el.animate( this.diff, opts );
 
4575                         return dfd.promise();
 
4578                 // once all animations have completed:
 
4579                 $.when.apply( $, allAnimations.get() ).done(function() {
 
4581                         // set the final class
 
4584                         // for each animated element,
 
4585                         // clear all css properties that were animated
 
4586                         $.each( arguments, function() {
 
4588                                 $.each( this.diff, function(key) {
 
4593                         // this is guarnteed to be there if you use jQuery.speed()
 
4594                         // it also handles dequeuing the next anim...
 
4595                         o.complete.call( animated[ 0 ] );
 
4601         _addClass: $.fn.addClass,
 
4602         addClass: function( classNames, speed, easing, callback ) {
 
4604                         $.effects.animateClass.call( this,
 
4605                                 { add: classNames }, speed, easing, callback ) :
 
4606                         this._addClass( classNames );
 
4609         _removeClass: $.fn.removeClass,
 
4610         removeClass: function( classNames, speed, easing, callback ) {
 
4612                         $.effects.animateClass.call( this,
 
4613                                 { remove: classNames }, speed, easing, callback ) :
 
4614                         this._removeClass( classNames );
 
4617         _toggleClass: $.fn.toggleClass,
 
4618         toggleClass: function( classNames, force, speed, easing, callback ) {
 
4619                 if ( typeof force === "boolean" || force === undefined ) {
 
4621                                 // without speed parameter
 
4622                                 return this._toggleClass( classNames, force );
 
4624                                 return $.effects.animateClass.call( this,
 
4625                                         (force ? { add: classNames } : { remove: classNames }),
 
4626                                         speed, easing, callback );
 
4629                         // without force parameter
 
4630                         return $.effects.animateClass.call( this,
 
4631                                 { toggle: classNames }, force, speed, easing );
 
4635         switchClass: function( remove, add, speed, easing, callback) {
 
4636                 return $.effects.animateClass.call( this, {
 
4639                 }, speed, easing, callback );
 
4645 /******************************************************************************/
 
4646 /*********************************** EFFECTS **********************************/
 
4647 /******************************************************************************/
 
4651 $.extend( $.effects, {
 
4654         // Saves a set of properties in a data storage
 
4655         save: function( element, set ) {
 
4656                 for( var i=0; i < set.length; i++ ) {
 
4657                         if ( set[ i ] !== null ) {
 
4658                                 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
 
4663         // Restores a set of previously saved properties from a data storage
 
4664         restore: function( element, set ) {
 
4666                 for( i=0; i < set.length; i++ ) {
 
4667                         if ( set[ i ] !== null ) {
 
4668                                 val = element.data( dataSpace + set[ i ] );
 
4669                                 // support: jQuery 1.6.2
 
4670                                 // http://bugs.jquery.com/ticket/9917
 
4671                                 // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
 
4672                                 // We can't differentiate between "" and 0 here, so we just assume
 
4673                                 // empty string since it's likely to be a more common value...
 
4674                                 if ( val === undefined ) {
 
4677                                 element.css( set[ i ], val );
 
4682         setMode: function( el, mode ) {
 
4683                 if (mode === "toggle") {
 
4684                         mode = el.is( ":hidden" ) ? "show" : "hide";
 
4689         // Translates a [top,left] array into a baseline value
 
4690         // this should be a little more flexible in the future to handle a string & hash
 
4691         getBaseline: function( origin, original ) {
 
4693                 switch ( origin[ 0 ] ) {
 
4694                         case "top": y = 0; break;
 
4695                         case "middle": y = 0.5; break;
 
4696                         case "bottom": y = 1; break;
 
4697                         default: y = origin[ 0 ] / original.height;
 
4699                 switch ( origin[ 1 ] ) {
 
4700                         case "left": x = 0; break;
 
4701                         case "center": x = 0.5; break;
 
4702                         case "right": x = 1; break;
 
4703                         default: x = origin[ 1 ] / original.width;
 
4711         // Wraps the element around a wrapper that copies position properties
 
4712         createWrapper: function( element ) {
 
4714                 // if the element is already wrapped, return it
 
4715                 if ( element.parent().is( ".ui-effects-wrapper" )) {
 
4716                         return element.parent();
 
4721                                 width: element.outerWidth(true),
 
4722                                 height: element.outerHeight(true),
 
4723                                 "float": element.css( "float" )
 
4725                         wrapper = $( "<div></div>" )
 
4726                                 .addClass( "ui-effects-wrapper" )
 
4729                                         background: "transparent",
 
4734                         // Store the size in case width/height are defined in % - Fixes #5245
 
4736                                 width: element.width(),
 
4737                                 height: element.height()
 
4739                         active = document.activeElement;
 
4742                 // Firefox incorrectly exposes anonymous content
 
4743                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
 
4747                         active = document.body;
 
4750                 element.wrap( wrapper );
 
4752                 // Fixes #7595 - Elements lose focus when wrapped.
 
4753                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
 
4754                         $( active ).focus();
 
4757                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
 
4759                 // transfer positioning properties to the wrapper
 
4760                 if ( element.css( "position" ) === "static" ) {
 
4761                         wrapper.css({ position: "relative" });
 
4762                         element.css({ position: "relative" });
 
4765                                 position: element.css( "position" ),
 
4766                                 zIndex: element.css( "z-index" )
 
4768                         $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
 
4769                                 props[ pos ] = element.css( pos );
 
4770                                 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
 
4771                                         props[ pos ] = "auto";
 
4775                                 position: "relative",
 
4784                 return wrapper.css( props ).show();
 
4787         removeWrapper: function( element ) {
 
4788                 var active = document.activeElement;
 
4790                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
 
4791                         element.parent().replaceWith( element );
 
4793                         // Fixes #7595 - Elements lose focus when wrapped.
 
4794                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
 
4795                                 $( active ).focus();
 
4803         setTransition: function( element, list, factor, value ) {
 
4804                 value = value || {};
 
4805                 $.each( list, function( i, x ) {
 
4806                         var unit = element.cssUnit( x );
 
4807                         if ( unit[ 0 ] > 0 ) {
 
4808                                 value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
 
4815 // return an effect options object for the given parameters:
 
4816 function _normalizeArguments( effect, options, speed, callback ) {
 
4818         // allow passing all options as the first parameter
 
4819         if ( $.isPlainObject( effect ) ) {
 
4821                 effect = effect.effect;
 
4824         // convert to an object
 
4825         effect = { effect: effect };
 
4827         // catch (effect, null, ...)
 
4828         if ( options == null ) {
 
4832         // catch (effect, callback)
 
4833         if ( $.isFunction( options ) ) {
 
4839         // catch (effect, speed, ?)
 
4840         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
 
4846         // catch (effect, options, callback)
 
4847         if ( $.isFunction( speed ) ) {
 
4852         // add options to effect
 
4854                 $.extend( effect, options );
 
4857         speed = speed || options.duration;
 
4858         effect.duration = $.fx.off ? 0 :
 
4859                 typeof speed === "number" ? speed :
 
4860                 speed in $.fx.speeds ? $.fx.speeds[ speed ] :
 
4861                 $.fx.speeds._default;
 
4863         effect.complete = callback || options.complete;
 
4868 function standardSpeed( speed ) {
 
4869         // valid standard speeds
 
4870         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
 
4874         // invalid strings - treat as "normal" speed
 
4875         return typeof speed === "string" && !$.effects.effect[ speed ];
 
4879         effect: function( /* effect, options, speed, callback */ ) {
 
4880                 var args = _normalizeArguments.apply( this, arguments ),
 
4883                         effectMethod = $.effects.effect[ args.effect ];
 
4885                 if ( $.fx.off || !effectMethod ) {
 
4886                         // delegate to the original method (e.g., .show()) if possible
 
4888                                 return this[ mode ]( args.duration, args.complete );
 
4890                                 return this.each( function() {
 
4891                                         if ( args.complete ) {
 
4892                                                 args.complete.call( this );
 
4898                 function run( next ) {
 
4899                         var elem = $( this ),
 
4900                                 complete = args.complete,
 
4904                                 if ( $.isFunction( complete ) ) {
 
4905                                         complete.call( elem[0] );
 
4907                                 if ( $.isFunction( next ) ) {
 
4912                         // if the element is hiddden and mode is hide,
 
4913                         // or element is visible and mode is show
 
4914                         if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
 
4917                                 effectMethod.call( elem[0], args, done );
 
4921                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
 
4925         show: function( speed ) {
 
4926                 if ( standardSpeed( speed ) ) {
 
4927                         return this._show.apply( this, arguments );
 
4929                         var args = _normalizeArguments.apply( this, arguments );
 
4931                         return this.effect.call( this, args );
 
4936         hide: function( speed ) {
 
4937                 if ( standardSpeed( speed ) ) {
 
4938                         return this._hide.apply( this, arguments );
 
4940                         var args = _normalizeArguments.apply( this, arguments );
 
4942                         return this.effect.call( this, args );
 
4946         // jQuery core overloads toggle and creates _toggle
 
4947         __toggle: $.fn.toggle,
 
4948         toggle: function( speed ) {
 
4949                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
 
4950                         return this.__toggle.apply( this, arguments );
 
4952                         var args = _normalizeArguments.apply( this, arguments );
 
4953                         args.mode = "toggle";
 
4954                         return this.effect.call( this, args );
 
4959         cssUnit: function(key) {
 
4960                 var style = this.css( key ),
 
4963                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
 
4964                         if ( style.indexOf( unit ) > 0 ) {
 
4965                                 val = [ parseFloat( style ), unit ];
 
4974 /******************************************************************************/
 
4975 /*********************************** EASING ***********************************/
 
4976 /******************************************************************************/
 
4980 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
 
4982 var baseEasings = {};
 
4984 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
 
4985         baseEasings[ name ] = function( p ) {
 
4986                 return Math.pow( p, i + 2 );
 
4990 $.extend( baseEasings, {
 
4991         Sine: function ( p ) {
 
4992                 return 1 - Math.cos( p * Math.PI / 2 );
 
4994         Circ: function ( p ) {
 
4995                 return 1 - Math.sqrt( 1 - p * p );
 
4997         Elastic: function( p ) {
 
4998                 return p === 0 || p === 1 ? p :
 
4999                         -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
 
5001         Back: function( p ) {
 
5002                 return p * p * ( 3 * p - 2 );
 
5004         Bounce: function ( p ) {
 
5008                 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
 
5009                 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
 
5013 $.each( baseEasings, function( name, easeIn ) {
 
5014         $.easing[ "easeIn" + name ] = easeIn;
 
5015         $.easing[ "easeOut" + name ] = function( p ) {
 
5016                 return 1 - easeIn( 1 - p );
 
5018         $.easing[ "easeInOut" + name ] = function( p ) {
 
5020                         easeIn( p * 2 ) / 2 :
 
5021                         1 - easeIn( p * -2 + 2 ) / 2;