d31460a8cde33cae67d7c7d2619c90704b92385a
[edumed.git] / edumed / static / catalogue / js / jquery-ui-1.10.0.custom.js
1 /*! jQuery UI - v1.10.0 - 2013-01-24
2 * http://jqueryui.com
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 */
5
6 (function( $, undefined ) {
7
8 var uuid = 0,
9         runiqueId = /^ui-id-\d+$/;
10
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
14 $.ui = $.ui || {};
15 if ( $.ui.version ) {
16         return;
17 }
18
19 $.extend( $.ui, {
20         version: "1.10.0",
21
22         keyCode: {
23                 BACKSPACE: 8,
24                 COMMA: 188,
25                 DELETE: 46,
26                 DOWN: 40,
27                 END: 35,
28                 ENTER: 13,
29                 ESCAPE: 27,
30                 HOME: 36,
31                 LEFT: 37,
32                 NUMPAD_ADD: 107,
33                 NUMPAD_DECIMAL: 110,
34                 NUMPAD_DIVIDE: 111,
35                 NUMPAD_ENTER: 108,
36                 NUMPAD_MULTIPLY: 106,
37                 NUMPAD_SUBTRACT: 109,
38                 PAGE_DOWN: 34,
39                 PAGE_UP: 33,
40                 PERIOD: 190,
41                 RIGHT: 39,
42                 SPACE: 32,
43                 TAB: 9,
44                 UP: 38
45         }
46 });
47
48 // plugins
49 $.fn.extend({
50         _focus: $.fn.focus,
51         focus: function( delay, fn ) {
52                 return typeof delay === "number" ?
53                         this.each(function() {
54                                 var elem = this;
55                                 setTimeout(function() {
56                                         $( elem ).focus();
57                                         if ( fn ) {
58                                                 fn.call( elem );
59                                         }
60                                 }, delay );
61                         }) :
62                         this._focus.apply( this, arguments );
63         },
64
65         scrollParent: function() {
66                 var scrollParent;
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"));
70                         }).eq(0);
71                 } else {
72                         scrollParent = this.parents().filter(function() {
73                                 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
74                         }).eq(0);
75                 }
76
77                 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
78         },
79
80         zIndex: function( zIndex ) {
81                 if ( zIndex !== undefined ) {
82                         return this.css( "zIndex", zIndex );
83                 }
84
85                 if ( this.length ) {
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 ) {
99                                                 return value;
100                                         }
101                                 }
102                                 elem = elem.parent();
103                         }
104                 }
105
106                 return 0;
107         },
108
109         uniqueId: function() {
110                 return this.each(function() {
111                         if ( !this.id ) {
112                                 this.id = "ui-id-" + (++uuid);
113                         }
114                 });
115         },
116
117         removeUniqueId: function() {
118                 return this.each(function() {
119                         if ( runiqueId.test( this.id ) ) {
120                                 $( this ).removeAttr( "id" );
121                         }
122                 });
123         }
124 });
125
126 // selectors
127 function focusable( element, isTabIndexNotNaN ) {
128         var map, mapName, img,
129                 nodeName = element.nodeName.toLowerCase();
130         if ( "area" === nodeName ) {
131                 map = element.parentNode;
132                 mapName = map.name;
133                 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
134                         return false;
135                 }
136                 img = $( "img[usemap=#" + mapName + "]" )[0];
137                 return !!img && visible( img );
138         }
139         return ( /input|select|textarea|button|object/.test( nodeName ) ?
140                 !element.disabled :
141                 "a" === nodeName ?
142                         element.href || isTabIndexNotNaN :
143                         isTabIndexNotNaN) &&
144                 // the element and all of its ancestors must be visible
145                 visible( element );
146 }
147
148 function visible( element ) {
149         return $.expr.filters.visible( element ) &&
150                 !$( element ).parents().addBack().filter(function() {
151                         return $.css( this, "visibility" ) === "hidden";
152                 }).length;
153 }
154
155 $.extend( $.expr[ ":" ], {
156         data: $.expr.createPseudo ?
157                 $.expr.createPseudo(function( dataName ) {
158                         return function( elem ) {
159                                 return !!$.data( elem, dataName );
160                         };
161                 }) :
162                 // support: jQuery <1.8
163                 function( elem, i, match ) {
164                         return !!$.data( elem, match[ 3 ] );
165                 },
166
167         focusable: function( element ) {
168                 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
169         },
170
171         tabbable: function( element ) {
172                 var tabIndex = $.attr( element, "tabindex" ),
173                         isTabIndexNaN = isNaN( tabIndex );
174                 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
175         }
176 });
177
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(),
183                         orig = {
184                                 innerWidth: $.fn.innerWidth,
185                                 innerHeight: $.fn.innerHeight,
186                                 outerWidth: $.fn.outerWidth,
187                                 outerHeight: $.fn.outerHeight
188                         };
189
190                 function reduce( elem, size, border, margin ) {
191                         $.each( side, function() {
192                                 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
193                                 if ( border ) {
194                                         size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
195                                 }
196                                 if ( margin ) {
197                                         size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
198                                 }
199                         });
200                         return size;
201                 }
202
203                 $.fn[ "inner" + name ] = function( size ) {
204                         if ( size === undefined ) {
205                                 return orig[ "inner" + name ].call( this );
206                         }
207
208                         return this.each(function() {
209                                 $( this ).css( type, reduce( this, size ) + "px" );
210                         });
211                 };
212
213                 $.fn[ "outer" + name] = function( size, margin ) {
214                         if ( typeof size !== "number" ) {
215                                 return orig[ "outer" + name ].call( this, size );
216                         }
217
218                         return this.each(function() {
219                                 $( this).css( type, reduce( this, size, true, margin ) + "px" );
220                         });
221                 };
222         });
223 }
224
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 )
230                 );
231         };
232 }
233
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 ) );
240                         } else {
241                                 return removeData.call( this );
242                         }
243                 };
244         })( $.fn.removeData );
245 }
246
247
248
249
250
251 // deprecated
252 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
253
254 $.support.selectstart = "onselectstart" in document.createElement( "div" );
255 $.fn.extend({
256         disableSelection: function() {
257                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
258                         ".ui-disableSelection", function( event ) {
259                                 event.preventDefault();
260                         });
261         },
262
263         enableSelection: function() {
264                 return this.unbind( ".ui-disableSelection" );
265         }
266 });
267
268 $.extend( $.ui, {
269         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
270         plugin: {
271                 add: function( module, option, set ) {
272                         var i,
273                                 proto = $.ui[ module ].prototype;
274                         for ( i in set ) {
275                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
276                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
277                         }
278                 },
279                 call: function( instance, name, args ) {
280                         var i,
281                                 set = instance.plugins[ name ];
282                         if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
283                                 return;
284                         }
285
286                         for ( i = 0; i < set.length; i++ ) {
287                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
288                                         set[ i ][ 1 ].apply( instance.element, args );
289                                 }
290                         }
291                 }
292         },
293
294         // only used by resizable
295         hasScroll: function( el, a ) {
296
297                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
298                 if ( $( el ).css( "overflow" ) === "hidden") {
299                         return false;
300                 }
301
302                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
303                         has = false;
304
305                 if ( el[ scroll ] > 0 ) {
306                         return true;
307                 }
308
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
311                 // set the scroll
312                 el[ scroll ] = 1;
313                 has = ( el[ scroll ] > 0 );
314                 el[ scroll ] = 0;
315                 return has;
316         }
317 });
318
319 })( jQuery );
320 (function( $, undefined ) {
321
322 var uuid = 0,
323         slice = Array.prototype.slice,
324         _cleanData = $.cleanData;
325 $.cleanData = function( elems ) {
326         for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
327                 try {
328                         $( elem ).triggerHandler( "remove" );
329                 // http://bugs.jquery.com/ticket/8235
330                 } catch( e ) {}
331         }
332         _cleanData( elems );
333 };
334
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 ];
341
342         name = name.split( "." )[ 1 ];
343         fullName = namespace + "-" + name;
344
345         if ( !prototype ) {
346                 prototype = base;
347                 base = $.Widget;
348         }
349
350         // create selector for plugin
351         $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
352                 return !!$.data( elem, fullName );
353         };
354
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 );
361                 }
362
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 );
367                 }
368         };
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: []
378         });
379
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
383         // inheriting from
384         basePrototype.options = $.widget.extend( {}, basePrototype.options );
385         $.each( prototype, function( prop, value ) {
386                 if ( !$.isFunction( value ) ) {
387                         proxiedPrototype[ prop ] = value;
388                         return;
389                 }
390                 proxiedPrototype[ prop ] = (function() {
391                         var _super = function() {
392                                         return base.prototype[ prop ].apply( this, arguments );
393                                 },
394                                 _superApply = function( args ) {
395                                         return base.prototype[ prop ].apply( this, args );
396                                 };
397                         return function() {
398                                 var __super = this._super,
399                                         __superApply = this._superApply,
400                                         returnValue;
401
402                                 this._super = _super;
403                                 this._superApply = _superApply;
404
405                                 returnValue = value.apply( this, arguments );
406
407                                 this._super = __super;
408                                 this._superApply = __superApply;
409
410                                 return returnValue;
411                         };
412                 })();
413         });
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,
422                 widgetName: name,
423                 widgetFullName: fullName
424         });
425
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;
433
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 );
437                 });
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;
441         } else {
442                 base._childConstructors.push( constructor );
443         }
444
445         $.widget.bridge( name, constructor );
446 };
447
448 $.widget.extend = function( target ) {
449         var input = slice.call( arguments, 1 ),
450                 inputIndex = 0,
451                 inputLength = input.length,
452                 key,
453                 value;
454         for ( ; inputIndex < inputLength; inputIndex++ ) {
455                 for ( key in input[ inputIndex ] ) {
456                         value = input[ inputIndex ][ key ];
457                         if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
458                                 // Clone objects
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
465                                 } else {
466                                         target[ key ] = value;
467                                 }
468                         }
469                 }
470         }
471         return target;
472 };
473
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 ),
479                         returnValue = this;
480
481                 // allow multiple hashes to be passed on init
482                 options = !isMethodCall && args.length ?
483                         $.widget.extend.apply( null, [ options ].concat(args) ) :
484                         options;
485
486                 if ( isMethodCall ) {
487                         this.each(function() {
488                                 var methodValue,
489                                         instance = $.data( this, fullName );
490                                 if ( !instance ) {
491                                         return $.error( "cannot call methods on " + name + " prior to initialization; " +
492                                                 "attempted to call method '" + options + "'" );
493                                 }
494                                 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
495                                         return $.error( "no such method '" + options + "' for " + name + " widget instance" );
496                                 }
497                                 methodValue = instance[ options ].apply( instance, args );
498                                 if ( methodValue !== instance && methodValue !== undefined ) {
499                                         returnValue = methodValue && methodValue.jquery ?
500                                                 returnValue.pushStack( methodValue.get() ) :
501                                                 methodValue;
502                                         return false;
503                                 }
504                         });
505                 } else {
506                         this.each(function() {
507                                 var instance = $.data( this, fullName );
508                                 if ( instance ) {
509                                         instance.option( options || {} )._init();
510                                 } else {
511                                         $.data( this, fullName, new object( options, this ) );
512                                 }
513                         });
514                 }
515
516                 return returnValue;
517         };
518 };
519
520 $.Widget = function( /* options, element */ ) {};
521 $.Widget._childConstructors = [];
522
523 $.Widget.prototype = {
524         widgetName: "widget",
525         widgetEventPrefix: "",
526         defaultElement: "<div>",
527         options: {
528                 disabled: false,
529
530                 // callbacks
531                 create: null
532         },
533         _createWidget: function( options, element ) {
534                 element = $( element || this.defaultElement || this )[ 0 ];
535                 this.element = $( element );
536                 this.uuid = uuid++;
537                 this.eventNamespace = "." + this.widgetName + this.uuid;
538                 this.options = $.widget.extend( {},
539                         this.options,
540                         this._getCreateOptions(),
541                         options );
542
543                 this.bindings = $();
544                 this.hoverable = $();
545                 this.focusable = $();
546
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 ) {
552                                                 this.destroy();
553                                         }
554                                 }
555                         });
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 );
562                 }
563
564                 this._create();
565                 this._trigger( "create", null, this._getCreateEventData() );
566                 this._init();
567         },
568         _getCreateOptions: $.noop,
569         _getCreateEventData: $.noop,
570         _create: $.noop,
571         _init: $.noop,
572
573         destroy: function() {
574                 this._destroy();
575                 // we can probably remove the unbind calls in 2.0
576                 // all event bindings should go through this._on()
577                 this.element
578                         .unbind( this.eventNamespace )
579                         // 1.9 BC for #7810
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 ) );
586                 this.widget()
587                         .unbind( this.eventNamespace )
588                         .removeAttr( "aria-disabled" )
589                         .removeClass(
590                                 this.widgetFullName + "-disabled " +
591                                 "ui-state-disabled" );
592
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" );
597         },
598         _destroy: $.noop,
599
600         widget: function() {
601                 return this.element;
602         },
603
604         option: function( key, value ) {
605                 var options = key,
606                         parts,
607                         curOption,
608                         i;
609
610                 if ( arguments.length === 0 ) {
611                         // don't return a reference to the internal hash
612                         return $.widget.extend( {}, this.options );
613                 }
614
615                 if ( typeof key === "string" ) {
616                         // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
617                         options = {};
618                         parts = key.split( "." );
619                         key = parts.shift();
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 ] ];
625                                 }
626                                 key = parts.pop();
627                                 if ( value === undefined ) {
628                                         return curOption[ key ] === undefined ? null : curOption[ key ];
629                                 }
630                                 curOption[ key ] = value;
631                         } else {
632                                 if ( value === undefined ) {
633                                         return this.options[ key ] === undefined ? null : this.options[ key ];
634                                 }
635                                 options[ key ] = value;
636                         }
637                 }
638
639                 this._setOptions( options );
640
641                 return this;
642         },
643         _setOptions: function( options ) {
644                 var key;
645
646                 for ( key in options ) {
647                         this._setOption( key, options[ key ] );
648                 }
649
650                 return this;
651         },
652         _setOption: function( key, value ) {
653                 this.options[ key ] = value;
654
655                 if ( key === "disabled" ) {
656                         this.widget()
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" );
661                 }
662
663                 return this;
664         },
665
666         enable: function() {
667                 return this._setOption( "disabled", false );
668         },
669         disable: function() {
670                 return this._setOption( "disabled", true );
671         },
672
673         _on: function( suppressDisabledCheck, element, handlers ) {
674                 var delegateElement,
675                         instance = this;
676
677                 // no suppressDisabledCheck flag, shuffle arguments
678                 if ( typeof suppressDisabledCheck !== "boolean" ) {
679                         handlers = element;
680                         element = suppressDisabledCheck;
681                         suppressDisabledCheck = false;
682                 }
683
684                 // no element argument, shuffle and use this.element
685                 if ( !handlers ) {
686                         handlers = element;
687                         element = this.element;
688                         delegateElement = this.widget();
689                 } else {
690                         // accept selectors, DOM elements
691                         element = delegateElement = $( element );
692                         this.bindings = this.bindings.add( element );
693                 }
694
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" ) ) ) {
703                                         return;
704                                 }
705                                 return ( typeof handler === "string" ? instance[ handler ] : handler )
706                                         .apply( instance, arguments );
707                         }
708
709                         // copy the guid so direct unbinding works
710                         if ( typeof handler !== "string" ) {
711                                 handlerProxy.guid = handler.guid =
712                                         handler.guid || handlerProxy.guid || $.guid++;
713                         }
714
715                         var match = event.match( /^(\w+)\s*(.*)$/ ),
716                                 eventName = match[1] + instance.eventNamespace,
717                                 selector = match[2];
718                         if ( selector ) {
719                                 delegateElement.delegate( selector, eventName, handlerProxy );
720                         } else {
721                                 element.bind( eventName, handlerProxy );
722                         }
723                 });
724         },
725
726         _off: function( element, eventName ) {
727                 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
728                 element.unbind( eventName ).undelegate( eventName );
729         },
730
731         _delay: function( handler, delay ) {
732                 function handlerProxy() {
733                         return ( typeof handler === "string" ? instance[ handler ] : handler )
734                                 .apply( instance, arguments );
735                 }
736                 var instance = this;
737                 return setTimeout( handlerProxy, delay || 0 );
738         },
739
740         _hoverable: function( element ) {
741                 this.hoverable = this.hoverable.add( element );
742                 this._on( element, {
743                         mouseenter: function( event ) {
744                                 $( event.currentTarget ).addClass( "ui-state-hover" );
745                         },
746                         mouseleave: function( event ) {
747                                 $( event.currentTarget ).removeClass( "ui-state-hover" );
748                         }
749                 });
750         },
751
752         _focusable: function( element ) {
753                 this.focusable = this.focusable.add( element );
754                 this._on( element, {
755                         focusin: function( event ) {
756                                 $( event.currentTarget ).addClass( "ui-state-focus" );
757                         },
758                         focusout: function( event ) {
759                                 $( event.currentTarget ).removeClass( "ui-state-focus" );
760                         }
761                 });
762         },
763
764         _trigger: function( type, event, data ) {
765                 var prop, orig,
766                         callback = this.options[ type ];
767
768                 data = data || {};
769                 event = $.Event( event );
770                 event.type = ( type === this.widgetEventPrefix ?
771                         type :
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 ];
776
777                 // copy original event properties over to the new event
778                 orig = event.originalEvent;
779                 if ( orig ) {
780                         for ( prop in orig ) {
781                                 if ( !( prop in event ) ) {
782                                         event[ prop ] = orig[ prop ];
783                                 }
784                         }
785                 }
786
787                 this.element.trigger( event, data );
788                 return !( $.isFunction( callback ) &&
789                         callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
790                         event.isDefaultPrevented() );
791         }
792 };
793
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 };
798                 }
799                 var hasOptions,
800                         effectName = !options ?
801                                 method :
802                                 options === true || typeof options === "number" ?
803                                         defaultEffect :
804                                         options.effect || defaultEffect;
805                 options = options || {};
806                 if ( typeof options === "number" ) {
807                         options = { duration: options };
808                 }
809                 hasOptions = !$.isEmptyObject( options );
810                 options.complete = callback;
811                 if ( options.delay ) {
812                         element.delay( options.delay );
813                 }
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 );
818                 } else {
819                         element.queue(function( next ) {
820                                 $( this )[ method ]();
821                                 if ( callback ) {
822                                         callback.call( element[ 0 ] );
823                                 }
824                                 next();
825                         });
826                 }
827         };
828 });
829
830 })( jQuery );
831 (function( $, undefined ) {
832
833 var mouseHandled = false;
834 $( document ).mouseup( function() {
835         mouseHandled = false;
836 });
837
838 $.widget("ui.mouse", {
839         version: "1.10.0",
840         options: {
841                 cancel: "input,textarea,button,select,option",
842                 distance: 1,
843                 delay: 0
844         },
845         _mouseInit: function() {
846                 var that = this;
847
848                 this.element
849                         .bind("mousedown."+this.widgetName, function(event) {
850                                 return that._mouseDown(event);
851                         })
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();
856                                         return false;
857                                 }
858                         });
859
860                 this.started = false;
861         },
862
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 ) {
868                         $(document)
869                                 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
870                                 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
871                 }
872         },
873
874         _mouseDown: function(event) {
875                 // don't let more than one widget handle mouseStart
876                 if( mouseHandled ) { return; }
877
878                 // we may have missed mouseup (out of window)
879                 (this._mouseStarted && this._mouseUp(event));
880
881                 this._mouseDownEvent = event;
882
883                 var that = this,
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)) {
889                         return true;
890                 }
891
892                 this.mouseDelayMet = !this.options.delay;
893                 if (!this.mouseDelayMet) {
894                         this._mouseDelayTimer = setTimeout(function() {
895                                 that.mouseDelayMet = true;
896                         }, this.options.delay);
897                 }
898
899                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
900                         this._mouseStarted = (this._mouseStart(event) !== false);
901                         if (!this._mouseStarted) {
902                                 event.preventDefault();
903                                 return true;
904                         }
905                 }
906
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");
910                 }
911
912                 // these delegates are required to keep context
913                 this._mouseMoveDelegate = function(event) {
914                         return that._mouseMove(event);
915                 };
916                 this._mouseUpDelegate = function(event) {
917                         return that._mouseUp(event);
918                 };
919                 $(document)
920                         .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
921                         .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
922
923                 event.preventDefault();
924
925                 mouseHandled = true;
926                 return true;
927         },
928
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);
933                 }
934
935                 if (this._mouseStarted) {
936                         this._mouseDrag(event);
937                         return event.preventDefault();
938                 }
939
940                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
941                         this._mouseStarted =
942                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
943                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
944                 }
945
946                 return !this._mouseStarted;
947         },
948
949         _mouseUp: function(event) {
950                 $(document)
951                         .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
952                         .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
953
954                 if (this._mouseStarted) {
955                         this._mouseStarted = false;
956
957                         if (event.target === this._mouseDownEvent.target) {
958                                 $.data(event.target, this.widgetName + ".preventClickEvent", true);
959                         }
960
961                         this._mouseStop(event);
962                 }
963
964                 return false;
965         },
966
967         _mouseDistanceMet: function(event) {
968                 return (Math.max(
969                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
970                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
971                         ) >= this.options.distance
972                 );
973         },
974
975         _mouseDelayMet: function(/* event */) {
976                 return this.mouseDelayMet;
977         },
978
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; }
984 });
985
986 })(jQuery);
987 (function( $, undefined ) {
988
989 $.widget("ui.draggable", $.ui.mouse, {
990         version: "1.10.0",
991         widgetEventPrefix: "drag",
992         options: {
993                 addClasses: true,
994                 appendTo: "parent",
995                 axis: false,
996                 connectToSortable: false,
997                 containment: false,
998                 cursor: "auto",
999                 cursorAt: false,
1000                 grid: false,
1001                 handle: false,
1002                 helper: "original",
1003                 iframeFix: false,
1004                 opacity: false,
1005                 refreshPositions: false,
1006                 revert: false,
1007                 revertDuration: 500,
1008                 scope: "default",
1009                 scroll: true,
1010                 scrollSensitivity: 20,
1011                 scrollSpeed: 20,
1012                 snap: false,
1013                 snapMode: "both",
1014                 snapTolerance: 20,
1015                 stack: false,
1016                 zIndex: false,
1017
1018                 // callbacks
1019                 drag: null,
1020                 start: null,
1021                 stop: null
1022         },
1023         _create: function() {
1024
1025                 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1026                         this.element[0].style.position = "relative";
1027                 }
1028                 if (this.options.addClasses){
1029                         this.element.addClass("ui-draggable");
1030                 }
1031                 if (this.options.disabled){
1032                         this.element.addClass("ui-draggable-disabled");
1033                 }
1034
1035                 this._mouseInit();
1036
1037         },
1038
1039         _destroy: function() {
1040                 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1041                 this._mouseDestroy();
1042         },
1043
1044         _mouseCapture: function(event) {
1045
1046                 var o = this.options;
1047
1048                 // among others, prevent a drag on a resizable-handle
1049                 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1050                         return false;
1051                 }
1052
1053                 //Quit if we're not on a valid handle
1054                 this.handle = this._getHandle(event);
1055                 if (!this.handle) {
1056                         return false;
1057                 }
1058
1059                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1060                         $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1061                         .css({
1062                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1063                                 position: "absolute", opacity: "0.001", zIndex: 1000
1064                         })
1065                         .css($(this).offset())
1066                         .appendTo("body");
1067                 });
1068
1069                 return true;
1070
1071         },
1072
1073         _mouseStart: function(event) {
1074
1075                 var o = this.options;
1076
1077                 //Create and append the visible helper
1078                 this.helper = this._createHelper(event);
1079
1080                 this.helper.addClass("ui-draggable-dragging");
1081
1082                 //Cache the helper size
1083                 this._cacheHelperProportions();
1084
1085                 //If ddmanager is used for droppables, set the global draggable
1086                 if($.ui.ddmanager) {
1087                         $.ui.ddmanager.current = this;
1088                 }
1089
1090                 /*
1091                  * - Position generation -
1092                  * This block generates everything position related - it's the core of draggables.
1093                  */
1094
1095                 //Cache the margins of the original element
1096                 this._cacheMargins();
1097
1098                 //Store the helper's css position
1099                 this.cssPosition = this.helper.css("position");
1100                 this.scrollParent = this.helper.scrollParent();
1101
1102                 //The element's absolute position on the page minus margins
1103                 this.offset = this.positionAbs = this.element.offset();
1104                 this.offset = {
1105                         top: this.offset.top - this.margins.top,
1106                         left: this.offset.left - this.margins.left
1107                 };
1108
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
1113                         },
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
1116                 });
1117
1118                 //Generate the original position
1119                 this.originalPosition = this.position = this._generatePosition(event);
1120                 this.originalPageX = event.pageX;
1121                 this.originalPageY = event.pageY;
1122
1123                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1124                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1125
1126                 //Set a containment if given in the options
1127                 if(o.containment) {
1128                         this._setContainment();
1129                 }
1130
1131                 //Trigger event + callbacks
1132                 if(this._trigger("start", event) === false) {
1133                         this._clear();
1134                         return false;
1135                 }
1136
1137                 //Recache the helper size
1138                 this._cacheHelperProportions();
1139
1140                 //Prepare the droppable offsets
1141                 if ($.ui.ddmanager && !o.dropBehaviour) {
1142                         $.ui.ddmanager.prepareOffsets(this, event);
1143                 }
1144
1145
1146                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1147
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);
1151                 }
1152
1153                 return true;
1154         },
1155
1156         _mouseDrag: function(event, noPropagation) {
1157
1158                 //Compute the helpers position
1159                 this.position = this._generatePosition(event);
1160                 this.positionAbs = this._convertPositionTo("absolute");
1161
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) {
1166                                 this._mouseUp({});
1167                                 return false;
1168                         }
1169                         this.position = ui.position;
1170                 }
1171
1172                 if(!this.options.axis || this.options.axis !== "y") {
1173                         this.helper[0].style.left = this.position.left+"px";
1174                 }
1175                 if(!this.options.axis || this.options.axis !== "x") {
1176                         this.helper[0].style.top = this.position.top+"px";
1177                 }
1178                 if($.ui.ddmanager) {
1179                         $.ui.ddmanager.drag(this, event);
1180                 }
1181
1182                 return false;
1183         },
1184
1185         _mouseStop: function(event) {
1186
1187                 //If we are using droppables, inform the manager about the drop
1188                 var element,
1189                         that = this,
1190                         elementInDom = false,
1191                         dropped = false;
1192                 if ($.ui.ddmanager && !this.options.dropBehaviour) {
1193                         dropped = $.ui.ddmanager.drop(this, event);
1194                 }
1195
1196                 //if a drop comes from outside (a sortable)
1197                 if(this.dropped) {
1198                         dropped = this.dropped;
1199                         this.dropped = false;
1200                 }
1201
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;
1207                         }
1208                 }
1209                 if ( !elementInDom && this.options.helper === "original" ) {
1210                         return false;
1211                 }
1212
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) {
1216                                         that._clear();
1217                                 }
1218                         });
1219                 } else {
1220                         if(this._trigger("stop", event) !== false) {
1221                                 this._clear();
1222                         }
1223                 }
1224
1225                 return false;
1226         },
1227
1228         _mouseUp: function(event) {
1229                 //Remove frame helpers
1230                 $("div.ui-draggable-iframeFix").each(function() {
1231                         this.parentNode.removeChild(this);
1232                 });
1233
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);
1237                 }
1238
1239                 return $.ui.mouse.prototype._mouseUp.call(this, event);
1240         },
1241
1242         cancel: function() {
1243
1244                 if(this.helper.is(".ui-draggable-dragging")) {
1245                         this._mouseUp({});
1246                 } else {
1247                         this._clear();
1248                 }
1249
1250                 return this;
1251
1252         },
1253
1254         _getHandle: function(event) {
1255
1256                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1257                 $(this.options.handle, this.element)
1258                         .find("*")
1259                         .addBack()
1260                         .each(function() {
1261                                 if(this === event.target) {
1262                                         handle = true;
1263                                 }
1264                         });
1265
1266                 return handle;
1267
1268         },
1269
1270         _createHelper: function(event) {
1271
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);
1274
1275                 if(!helper.parents("body").length) {
1276                         helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1277                 }
1278
1279                 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1280                         helper.css("position", "absolute");
1281                 }
1282
1283                 return helper;
1284
1285         },
1286
1287         _adjustOffsetFromHelper: function(obj) {
1288                 if (typeof obj === "string") {
1289                         obj = obj.split(" ");
1290                 }
1291                 if ($.isArray(obj)) {
1292                         obj = {left: +obj[0], top: +obj[1] || 0};
1293                 }
1294                 if ("left" in obj) {
1295                         this.offset.click.left = obj.left + this.margins.left;
1296                 }
1297                 if ("right" in obj) {
1298                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1299                 }
1300                 if ("top" in obj) {
1301                         this.offset.click.top = obj.top + this.margins.top;
1302                 }
1303                 if ("bottom" in obj) {
1304                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1305                 }
1306         },
1307
1308         _getParentOffset: function() {
1309
1310                 //Get the offsetParent and cache its position
1311                 this.offsetParent = this.helper.offsetParent();
1312                 var po = this.offsetParent.offset();
1313
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();
1321                 }
1322
1323                 //This needs to be actually done for all browsers, since pageX/pageY includes this information
1324                 //Ugly IE fix
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 };
1328                 }
1329
1330                 return {
1331                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1332                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1333                 };
1334
1335         },
1336
1337         _getRelativeOffset: function() {
1338
1339                 if(this.cssPosition === "relative") {
1340                         var p = this.element.position();
1341                         return {
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()
1344                         };
1345                 } else {
1346                         return { top: 0, left: 0 };
1347                 }
1348
1349         },
1350
1351         _cacheMargins: function() {
1352                 this.margins = {
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)
1357                 };
1358         },
1359
1360         _cacheHelperProportions: function() {
1361                 this.helperProportions = {
1362                         width: this.helper.outerWidth(),
1363                         height: this.helper.outerHeight()
1364                 };
1365         },
1366
1367         _setContainment: function() {
1368
1369                 var over, c, ce,
1370                         o = this.options;
1371
1372                 if(o.containment === "parent") {
1373                         o.containment = this.helper[0].parentNode;
1374                 }
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
1381                         ];
1382                 }
1383
1384                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
1385                         c = $(o.containment);
1386                         ce = c[0];
1387
1388                         if(!ce) {
1389                                 return;
1390                         }
1391
1392                         over = ($(ce).css("overflow") !== "hidden");
1393
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
1399                         ];
1400                         this.relative_container = c;
1401
1402                 } else if(o.containment.constructor === Array) {
1403                         this.containment = o.containment;
1404                 }
1405
1406         },
1407
1408         _convertPositionTo: function(d, pos) {
1409
1410                 if(!pos) {
1411                         pos = this.position;
1412                 }
1413
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);
1416
1417                 return {
1418                         top: (
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)
1423                         ),
1424                         left: (
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)
1429                         )
1430                 };
1431
1432         },
1433
1434         _generatePosition: function(event) {
1435
1436                 var containment, co, top, left,
1437                         o = this.options,
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;
1442
1443                 /*
1444                  * - Position constraining -
1445                  * Constrain the position to a mix of grid, containment.
1446                  */
1447
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 ];
1456                         }
1457                         else {
1458                                 containment = this.containment;
1459                         }
1460
1461                                 if(event.pageX - this.offset.click.left < containment[0]) {
1462                                         pageX = containment[0] + this.offset.click.left;
1463                                 }
1464                                 if(event.pageY - this.offset.click.top < containment[1]) {
1465                                         pageY = containment[1] + this.offset.click.top;
1466                                 }
1467                                 if(event.pageX - this.offset.click.left > containment[2]) {
1468                                         pageX = containment[2] + this.offset.click.left;
1469                                 }
1470                                 if(event.pageY - this.offset.click.top > containment[3]) {
1471                                         pageY = containment[3] + this.offset.click.top;
1472                                 }
1473                         }
1474
1475                         if(o.grid) {
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;
1479
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;
1482                         }
1483
1484                 }
1485
1486                 return {
1487                         top: (
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() ) ))
1493                         ),
1494                         left: (
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() ))
1500                         )
1501                 };
1502
1503         },
1504
1505         _clear: function() {
1506                 this.helper.removeClass("ui-draggable-dragging");
1507                 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1508                         this.helper.remove();
1509                 }
1510                 this.helper = null;
1511                 this.cancelHelperRemoval = false;
1512         },
1513
1514         // From now on bulk stuff - mainly helpers
1515
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");
1522                 }
1523                 return $.Widget.prototype._trigger.call(this, type, event, ui);
1524         },
1525
1526         plugins: {},
1527
1528         _uiHash: function() {
1529                 return {
1530                         helper: this.helper,
1531                         position: this.position,
1532                         originalPosition: this.originalPosition,
1533                         offset: this.positionAbs
1534                 };
1535         }
1536
1537 });
1538
1539 $.ui.plugin.add("draggable", "connectToSortable", {
1540         start: function(event, ui) {
1541
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({
1549                                         instance: sortable,
1550                                         shouldRevert: sortable.options.revert
1551                                 });
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);
1554                         }
1555                 });
1556
1557         },
1558         stop: function(event, ui) {
1559
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 });
1563
1564                 $.each(inst.sortables, function() {
1565                         if(this.instance.isOver) {
1566
1567                                 this.instance.isOver = 0;
1568
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)
1571
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;
1575                                 }
1576
1577                                 //Trigger the stop of the sortable
1578                                 this.instance._mouseStop(event);
1579
1580                                 this.instance.options.helper = this.instance.options._helper;
1581
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" });
1585                                 }
1586
1587                         } else {
1588                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1589                                 this.instance._trigger("deactivate", event, uiSortable);
1590                         }
1591
1592                 });
1593
1594         },
1595         drag: function(event, ui) {
1596
1597                 var inst = $(this).data("ui-draggable"), that = this;
1598
1599                 $.each(inst.sortables, function() {
1600
1601                         var innermostIntersecting = false,
1602                                 thisSortable = this;
1603
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;
1608
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])
1618                                         ) {
1619                                                 innermostIntersecting = false;
1620                                         }
1621                                         return innermostIntersecting;
1622                                 });
1623                         }
1624
1625
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) {
1629
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]; };
1637
1638                                         event.target = this.instance.currentItem[0];
1639                                         this.instance._mouseCapture(event, true);
1640                                         this.instance._mouseStart(event, true, true);
1641
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;
1647
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;
1653
1654                                 }
1655
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);
1659                                 }
1660
1661                         } else {
1662
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) {
1666
1667                                         this.instance.isOver = 0;
1668                                         this.instance.cancelHelperRemoval = true;
1669
1670                                         //Prevent reverting on this forced stop
1671                                         this.instance.options.revert = false;
1672
1673                                         // The out event needs to be triggered independently
1674                                         this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1675
1676                                         this.instance._mouseStop(event, true);
1677                                         this.instance.options.helper = this.instance.options._helper;
1678
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();
1683                                         }
1684
1685                                         inst._trigger("fromSortable", event);
1686                                         inst.dropped = false; //draggable revert needs that
1687                                 }
1688
1689                         }
1690
1691                 });
1692
1693         }
1694 });
1695
1696 $.ui.plugin.add("draggable", "cursor", {
1697         start: function() {
1698                 var t = $("body"), o = $(this).data("ui-draggable").options;
1699                 if (t.css("cursor")) {
1700                         o._cursor = t.css("cursor");
1701                 }
1702                 t.css("cursor", o.cursor);
1703         },
1704         stop: function() {
1705                 var o = $(this).data("ui-draggable").options;
1706                 if (o._cursor) {
1707                         $("body").css("cursor", o._cursor);
1708                 }
1709         }
1710 });
1711
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");
1717                 }
1718                 t.css("opacity", o.opacity);
1719         },
1720         stop: function(event, ui) {
1721                 var o = $(this).data("ui-draggable").options;
1722                 if(o._opacity) {
1723                         $(ui.helper).css("opacity", o._opacity);
1724                 }
1725         }
1726 });
1727
1728 $.ui.plugin.add("draggable", "scroll", {
1729         start: function() {
1730                 var i = $(this).data("ui-draggable");
1731                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1732                         i.overflowOffset = i.scrollParent.offset();
1733                 }
1734         },
1735         drag: function( event ) {
1736
1737                 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1738
1739                 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1740
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;
1746                                 }
1747                         }
1748
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;
1754                                 }
1755                         }
1756
1757                 } else {
1758
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);
1764                                 }
1765                         }
1766
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);
1772                                 }
1773                         }
1774
1775                 }
1776
1777                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1778                         $.ui.ddmanager.prepareOffsets(i, event);
1779                 }
1780
1781         }
1782 });
1783
1784 $.ui.plugin.add("draggable", "snap", {
1785         start: function() {
1786
1787                 var i = $(this).data("ui-draggable"),
1788                         o = i.options;
1789
1790                 i.snapElements = [];
1791
1792                 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1793                         var $t = $(this),
1794                                 $o = $t.offset();
1795                         if(this !== i.element[0]) {
1796                                 i.snapElements.push({
1797                                         item: this,
1798                                         width: $t.outerWidth(), height: $t.outerHeight(),
1799                                         top: $o.top, left: $o.left
1800                                 });
1801                         }
1802                 });
1803
1804         },
1805         drag: function(event, ui) {
1806
1807                 var ts, bs, ls, rs, l, r, t, b, i, first,
1808                         inst = $(this).data("ui-draggable"),
1809                         o = inst.options,
1810                         d = o.snapTolerance,
1811                         x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1812                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1813
1814                 for (i = inst.snapElements.length - 1; i >= 0; i--){
1815
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;
1820
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 })));
1825                                 }
1826                                 inst.snapElements[i].snapping = false;
1827                                 continue;
1828                         }
1829
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;
1835                                 if(ts) {
1836                                         ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1837                                 }
1838                                 if(bs) {
1839                                         ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1840                                 }
1841                                 if(ls) {
1842                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1843                                 }
1844                                 if(rs) {
1845                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1846                                 }
1847                         }
1848
1849                         first = (ts || bs || ls || rs);
1850
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;
1856                                 if(ts) {
1857                                         ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1858                                 }
1859                                 if(bs) {
1860                                         ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1861                                 }
1862                                 if(ls) {
1863                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1864                                 }
1865                                 if(rs) {
1866                                         ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1867                                 }
1868                         }
1869
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 })));
1872                         }
1873                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1874
1875                 }
1876
1877         }
1878 });
1879
1880 $.ui.plugin.add("draggable", "stack", {
1881         start: function() {
1882
1883                 var min,
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);
1887                         });
1888
1889                 if (!group.length) { return; }
1890
1891                 min = parseInt(group[0].style.zIndex, 10) || 0;
1892                 $(group).each(function(i) {
1893                         this.style.zIndex = min + i;
1894                 });
1895
1896                 this[0].style.zIndex = min + group.length;
1897
1898         }
1899 });
1900
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");
1906                 }
1907                 t.css("zIndex", o.zIndex);
1908         },
1909         stop: function(event, ui) {
1910                 var o = $(this).data("ui-draggable").options;
1911                 if(o._zIndex) {
1912                         $(ui.helper).css("zIndex", o._zIndex);
1913                 }
1914         }
1915 });
1916
1917 })(jQuery);
1918 (function( $, undefined ) {
1919
1920 function isOverAxis( x, reference, size ) {
1921         return ( x > reference ) && ( x < ( reference + size ) );
1922 }
1923
1924 $.widget("ui.droppable", {
1925         version: "1.10.0",
1926         widgetEventPrefix: "drop",
1927         options: {
1928                 accept: "*",
1929                 activeClass: false,
1930                 addClasses: true,
1931                 greedy: false,
1932                 hoverClass: false,
1933                 scope: "default",
1934                 tolerance: "intersect",
1935
1936                 // callbacks
1937                 activate: null,
1938                 deactivate: null,
1939                 drop: null,
1940                 out: null,
1941                 over: null
1942         },
1943         _create: function() {
1944
1945                 var o = this.options,
1946                         accept = o.accept;
1947
1948                 this.isover = false;
1949                 this.isout = true;
1950
1951                 this.accept = $.isFunction(accept) ? accept : function(d) {
1952                         return d.is(accept);
1953                 };
1954
1955                 //Store the droppable's proportions
1956                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1957
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);
1961
1962                 (o.addClasses && this.element.addClass("ui-droppable"));
1963
1964         },
1965
1966         _destroy: function() {
1967                 var i = 0,
1968                         drop = $.ui.ddmanager.droppables[this.options.scope];
1969
1970                 for ( ; i < drop.length; i++ ) {
1971                         if ( drop[i] === this ) {
1972                                 drop.splice(i, 1);
1973                         }
1974                 }
1975
1976                 this.element.removeClass("ui-droppable ui-droppable-disabled");
1977         },
1978
1979         _setOption: function(key, value) {
1980
1981                 if(key === "accept") {
1982                         this.accept = $.isFunction(value) ? value : function(d) {
1983                                 return d.is(value);
1984                         };
1985                 }
1986                 $.Widget.prototype._setOption.apply(this, arguments);
1987         },
1988
1989         _activate: function(event) {
1990                 var draggable = $.ui.ddmanager.current;
1991                 if(this.options.activeClass) {
1992                         this.element.addClass(this.options.activeClass);
1993                 }
1994                 if(draggable){
1995                         this._trigger("activate", event, this.ui(draggable));
1996                 }
1997         },
1998
1999         _deactivate: function(event) {
2000                 var draggable = $.ui.ddmanager.current;
2001                 if(this.options.activeClass) {
2002                         this.element.removeClass(this.options.activeClass);
2003                 }
2004                 if(draggable){
2005                         this._trigger("deactivate", event, this.ui(draggable));
2006                 }
2007         },
2008
2009         _over: function(event) {
2010
2011                 var draggable = $.ui.ddmanager.current;
2012
2013                 // Bail if draggable and droppable are same element
2014                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2015                         return;
2016                 }
2017
2018                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2019                         if(this.options.hoverClass) {
2020                                 this.element.addClass(this.options.hoverClass);
2021                         }
2022                         this._trigger("over", event, this.ui(draggable));
2023                 }
2024
2025         },
2026
2027         _out: function(event) {
2028
2029                 var draggable = $.ui.ddmanager.current;
2030
2031                 // Bail if draggable and droppable are same element
2032                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2033                         return;
2034                 }
2035
2036                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2037                         if(this.options.hoverClass) {
2038                                 this.element.removeClass(this.options.hoverClass);
2039                         }
2040                         this._trigger("out", event, this.ui(draggable));
2041                 }
2042
2043         },
2044
2045         _drop: function(event,custom) {
2046
2047                 var draggable = custom || $.ui.ddmanager.current,
2048                         childrenIntersection = false;
2049
2050                 // Bail if draggable and droppable are same element
2051                 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2052                         return false;
2053                 }
2054
2055                 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2056                         var inst = $.data(this, "ui-droppable");
2057                         if(
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; }
2064                 });
2065                 if(childrenIntersection) {
2066                         return false;
2067                 }
2068
2069                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2070                         if(this.options.activeClass) {
2071                                 this.element.removeClass(this.options.activeClass);
2072                         }
2073                         if(this.options.hoverClass) {
2074                                 this.element.removeClass(this.options.hoverClass);
2075                         }
2076                         this._trigger("drop", event, this.ui(draggable));
2077                         return this.element;
2078                 }
2079
2080                 return false;
2081
2082         },
2083
2084         ui: function(c) {
2085                 return {
2086                         draggable: (c.currentItem || c.element),
2087                         helper: c.helper,
2088                         position: c.position,
2089                         offset: c.positionAbs
2090                 };
2091         }
2092
2093 });
2094
2095 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2096
2097         if (!droppable.offset) {
2098                 return false;
2099         }
2100
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;
2106
2107         switch (toleranceMode) {
2108                 case "fit":
2109                         return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2110                 case "intersect":
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
2115                 case "pointer":
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 );
2119                 case "touch":
2120                         return (
2121                                 (y1 >= t && y1 <= b) || // Top edge touching
2122                                 (y2 >= t && y2 <= b) || // Bottom edge touching
2123                                 (y1 < t && y2 > b)              // Surrounded vertically
2124                         ) && (
2125                                 (x1 >= l && x1 <= r) || // Left edge touching
2126                                 (x2 >= l && x2 <= r) || // Right edge touching
2127                                 (x1 < l && x2 > r)              // Surrounded horizontally
2128                         );
2129                 default:
2130                         return false;
2131                 }
2132
2133 };
2134
2135 /*
2136         This manager tracks offsets of draggables and droppables
2137 */
2138 $.ui.ddmanager = {
2139         current: null,
2140         droppables: { "default": [] },
2141         prepareOffsets: function(t, event) {
2142
2143                 var i, j,
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();
2147
2148                 droppablesLoop: for (i = 0; i < m.length; i++) {
2149
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)))) {
2152                                 continue;
2153                         }
2154
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;
2160                                 }
2161                         }
2162
2163                         m[i].visible = m[i].element.css("display") !== "none";
2164                         if(!m[i].visible) {
2165                                 continue;
2166                         }
2167
2168                         //Activate the droppable if used directly from draggables
2169                         if(type === "mousedown") {
2170                                 m[i]._activate.call(m[i], event);
2171                         }
2172
2173                         m[i].offset = m[i].element.offset();
2174                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2175
2176                 }
2177
2178         },
2179         drop: function(draggable, event) {
2180
2181                 var dropped = false;
2182                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2183
2184                         if(!this.options) {
2185                                 return;
2186                         }
2187                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2188                                 dropped = this._drop.call(this, event) || dropped;
2189                         }
2190
2191                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2192                                 this.isout = true;
2193                                 this.isover = false;
2194                                 this._deactivate.call(this, event);
2195                         }
2196
2197                 });
2198                 return dropped;
2199
2200         },
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 );
2206                         }
2207                 });
2208         },
2209         drag: function(draggable, event) {
2210
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);
2214                 }
2215
2216                 //Run through all droppables and check their positions based on specific tolerance options
2217                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2218
2219                         if(this.options.disabled || this.greedyChild || !this.visible) {
2220                                 return;
2221                         }
2222
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);
2226                         if(!c) {
2227                                 return;
2228                         }
2229
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;
2235                                 });
2236
2237                                 if (parent.length) {
2238                                         parentInstance = $.data(parent[0], "ui-droppable");
2239                                         parentInstance.greedyChild = (c === "isover");
2240                                 }
2241                         }
2242
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);
2248                         }
2249
2250                         this[c] = true;
2251                         this[c === "isout" ? "isover" : "isout"] = false;
2252                         this[c === "isover" ? "_over" : "_out"].call(this, event);
2253
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);
2259                         }
2260                 });
2261
2262         },
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 );
2268                 }
2269         }
2270 };
2271
2272 })(jQuery);
2273 (function( $, undefined ) {
2274
2275 $.widget("ui.selectable", $.ui.mouse, {
2276         version: "1.10.0",
2277         options: {
2278                 appendTo: "body",
2279                 autoRefresh: true,
2280                 distance: 0,
2281                 filter: "*",
2282                 tolerance: "touch",
2283
2284                 // callbacks
2285                 selected: null,
2286                 selecting: null,
2287                 start: null,
2288                 stop: null,
2289                 unselected: null,
2290                 unselecting: null
2291         },
2292         _create: function() {
2293                 var selectees,
2294                         that = this;
2295
2296                 this.element.addClass("ui-selectable");
2297
2298                 this.dragged = false;
2299
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", {
2308                                         element: this,
2309                                         $element: $this,
2310                                         left: pos.left,
2311                                         top: pos.top,
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")
2318                                 });
2319                         });
2320                 };
2321                 this.refresh();
2322
2323                 this.selectees = selectees.addClass("ui-selectee");
2324
2325                 this._mouseInit();
2326
2327                 this.helper = $("<div class='ui-selectable-helper'></div>");
2328         },
2329
2330         _destroy: function() {
2331                 this.selectees
2332                         .removeClass("ui-selectee")
2333                         .removeData("selectable-item");
2334                 this.element
2335                         .removeClass("ui-selectable ui-selectable-disabled");
2336                 this._mouseDestroy();
2337         },
2338
2339         _mouseStart: function(event) {
2340                 var that = this,
2341                         options = this.options;
2342
2343                 this.opos = [event.pageX, event.pageY];
2344
2345                 if (this.options.disabled) {
2346                         return;
2347                 }
2348
2349                 this.selectees = $(options.filter, this.element[0]);
2350
2351                 this._trigger("start", event);
2352
2353                 $(options.appendTo).append(this.helper);
2354                 // position helper (lasso)
2355                 this.helper.css({
2356                         "left": event.pageX,
2357                         "top": event.pageY,
2358                         "width": 0,
2359                         "height": 0
2360                 });
2361
2362                 if (options.autoRefresh) {
2363                         this.refresh();
2364                 }
2365
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
2377                                 });
2378                         }
2379                 });
2380
2381                 $(event.target).parents().addBack().each(function() {
2382                         var doSelect,
2383                                 selectee = $.data(this, "selectable-item");
2384                         if (selectee) {
2385                                 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
2386                                 selectee.$element
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
2393                                 if (doSelect) {
2394                                         that._trigger("selecting", event, {
2395                                                 selecting: selectee.element
2396                                         });
2397                                 } else {
2398                                         that._trigger("unselecting", event, {
2399                                                 unselecting: selectee.element
2400                                         });
2401                                 }
2402                                 return false;
2403                         }
2404                 });
2405
2406         },
2407
2408         _mouseDrag: function(event) {
2409
2410                 this.dragged = true;
2411
2412                 if (this.options.disabled) {
2413                         return;
2414                 }
2415
2416                 var tmp,
2417                         that = this,
2418                         options = this.options,
2419                         x1 = this.opos[0],
2420                         y1 = this.opos[1],
2421                         x2 = event.pageX,
2422                         y2 = event.pageY;
2423
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});
2427
2428                 this.selectees.each(function() {
2429                         var selectee = $.data(this, "selectable-item"),
2430                                 hit = false;
2431
2432                         //prevent helper from being selected if appendTo: selectable
2433                         if (!selectee || selectee.element === that.element[0]) {
2434                                 return;
2435                         }
2436
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);
2441                         }
2442
2443                         if (hit) {
2444                                 // SELECT
2445                                 if (selectee.selected) {
2446                                         selectee.$element.removeClass("ui-selected");
2447                                         selectee.selected = false;
2448                                 }
2449                                 if (selectee.unselecting) {
2450                                         selectee.$element.removeClass("ui-unselecting");
2451                                         selectee.unselecting = false;
2452                                 }
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
2459                                         });
2460                                 }
2461                         } else {
2462                                 // UNSELECT
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;
2469                                         } else {
2470                                                 selectee.$element.removeClass("ui-selecting");
2471                                                 selectee.selecting = false;
2472                                                 if (selectee.startselected) {
2473                                                         selectee.$element.addClass("ui-unselecting");
2474                                                         selectee.unselecting = true;
2475                                                 }
2476                                                 // selectable UNSELECTING callback
2477                                                 that._trigger("unselecting", event, {
2478                                                         unselecting: selectee.element
2479                                                 });
2480                                         }
2481                                 }
2482                                 if (selectee.selected) {
2483                                         if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
2484                                                 selectee.$element.removeClass("ui-selected");
2485                                                 selectee.selected = false;
2486
2487                                                 selectee.$element.addClass("ui-unselecting");
2488                                                 selectee.unselecting = true;
2489                                                 // selectable UNSELECTING callback
2490                                                 that._trigger("unselecting", event, {
2491                                                         unselecting: selectee.element
2492                                                 });
2493                                         }
2494                                 }
2495                         }
2496                 });
2497
2498                 return false;
2499         },
2500
2501         _mouseStop: function(event) {
2502                 var that = this;
2503
2504                 this.dragged = false;
2505
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
2513                         });
2514                 });
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
2523                         });
2524                 });
2525                 this._trigger("stop", event);
2526
2527                 this.helper.remove();
2528
2529                 return false;
2530         }
2531
2532 });
2533
2534 })(jQuery);
2535 (function( $, undefined ) {
2536
2537 /*jshint loopfunc: true */
2538
2539 function isOverAxis( x, reference, size ) {
2540         return ( x > reference ) && ( x < ( reference + size ) );
2541 }
2542
2543 $.widget("ui.sortable", $.ui.mouse, {
2544         version: "1.10.0",
2545         widgetEventPrefix: "sort",
2546         ready: false,
2547         options: {
2548                 appendTo: "parent",
2549                 axis: false,
2550                 connectWith: false,
2551                 containment: false,
2552                 cursor: "auto",
2553                 cursorAt: false,
2554                 dropOnEmpty: true,
2555                 forcePlaceholderSize: false,
2556                 forceHelperSize: false,
2557                 grid: false,
2558                 handle: false,
2559                 helper: "original",
2560                 items: "> *",
2561                 opacity: false,
2562                 placeholder: false,
2563                 revert: false,
2564                 scroll: true,
2565                 scrollSensitivity: 20,
2566                 scrollSpeed: 20,
2567                 scope: "default",
2568                 tolerance: "intersect",
2569                 zIndex: 1000,
2570
2571                 // callbacks
2572                 activate: null,
2573                 beforeStop: null,
2574                 change: null,
2575                 deactivate: null,
2576                 out: null,
2577                 over: null,
2578                 receive: null,
2579                 remove: null,
2580                 sort: null,
2581                 start: null,
2582                 stop: null,
2583                 update: null
2584         },
2585         _create: function() {
2586
2587                 var o = this.options;
2588                 this.containerCache = {};
2589                 this.element.addClass("ui-sortable");
2590
2591                 //Get the items
2592                 this.refresh();
2593
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;
2596
2597                 //Let's determine the parent's offset
2598                 this.offset = this.element.offset();
2599
2600                 //Initialize mouse events for interaction
2601                 this._mouseInit();
2602
2603                 //We're ready to go
2604                 this.ready = true;
2605
2606         },
2607
2608         _destroy: function() {
2609                 this.element
2610                         .removeClass("ui-sortable ui-sortable-disabled");
2611                 this._mouseDestroy();
2612
2613                 for ( var i = this.items.length - 1; i >= 0; i-- ) {
2614                         this.items[i].item.removeData(this.widgetName + "-item");
2615                 }
2616
2617                 return this;
2618         },
2619
2620         _setOption: function(key, value){
2621                 if ( key === "disabled" ) {
2622                         this.options[ key ] = value;
2623
2624                         this.widget().toggleClass( "ui-sortable-disabled", !!value );
2625                 } else {
2626                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
2627                         $.Widget.prototype._setOption.apply(this, arguments);
2628                 }
2629         },
2630
2631         _mouseCapture: function(event, overrideHandle) {
2632                 var currentItem = null,
2633                         validHandle = false,
2634                         that = this;
2635
2636                 if (this.reverting) {
2637                         return false;
2638                 }
2639
2640                 if(this.options.disabled || this.options.type === "static") {
2641                         return false;
2642                 }
2643
2644                 //We have to refresh the items data once first
2645                 this._refreshItems(event);
2646
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);
2651                                 return false;
2652                         }
2653                 });
2654                 if($.data(event.target, that.widgetName + "-item") === that) {
2655                         currentItem = $(event.target);
2656                 }
2657
2658                 if(!currentItem) {
2659                         return false;
2660                 }
2661                 if(this.options.handle && !overrideHandle) {
2662                         $(this.options.handle, currentItem).find("*").addBack().each(function() {
2663                                 if(this === event.target) {
2664                                         validHandle = true;
2665                                 }
2666                         });
2667                         if(!validHandle) {
2668                                 return false;
2669                         }
2670                 }
2671
2672                 this.currentItem = currentItem;
2673                 this._removeCurrentsFromItems();
2674                 return true;
2675
2676         },
2677
2678         _mouseStart: function(event, overrideHandle, noActivation) {
2679
2680                 var i,
2681                         o = this.options;
2682
2683                 this.currentContainer = this;
2684
2685                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
2686                 this.refreshPositions();
2687
2688                 //Create and append the visible helper
2689                 this.helper = this._createHelper(event);
2690
2691                 //Cache the helper size
2692                 this._cacheHelperProportions();
2693
2694                 /*
2695                  * - Position generation -
2696                  * This block generates everything position related - it's the core of draggables.
2697                  */
2698
2699                 //Cache the margins of the original element
2700                 this._cacheMargins();
2701
2702                 //Get the next scrolling parent
2703                 this.scrollParent = this.helper.scrollParent();
2704
2705                 //The element's absolute position on the page minus margins
2706                 this.offset = this.currentItem.offset();
2707                 this.offset = {
2708                         top: this.offset.top - this.margins.top,
2709                         left: this.offset.left - this.margins.left
2710                 };
2711
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
2716                         },
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
2719                 });
2720
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");
2725
2726                 //Generate the original position
2727                 this.originalPosition = this._generatePosition(event);
2728                 this.originalPageX = event.pageX;
2729                 this.originalPageY = event.pageY;
2730
2731                 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
2732                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
2733
2734                 //Cache the former DOM position
2735                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
2736
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();
2740                 }
2741
2742                 //Create the placeholder
2743                 this._createPlaceholder();
2744
2745                 //Set a containment if given in the options
2746                 if(o.containment) {
2747                         this._setContainment();
2748                 }
2749
2750                 if(o.cursor) { // cursor option
2751                         if ($("body").css("cursor")) {
2752                                 this._storedCursor = $("body").css("cursor");
2753                         }
2754                         $("body").css("cursor", o.cursor);
2755                 }
2756
2757                 if(o.opacity) { // opacity option
2758                         if (this.helper.css("opacity")) {
2759                                 this._storedOpacity = this.helper.css("opacity");
2760                         }
2761                         this.helper.css("opacity", o.opacity);
2762                 }
2763
2764                 if(o.zIndex) { // zIndex option
2765                         if (this.helper.css("zIndex")) {
2766                                 this._storedZIndex = this.helper.css("zIndex");
2767                         }
2768                         this.helper.css("zIndex", o.zIndex);
2769                 }
2770
2771                 //Prepare scrolling
2772                 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
2773                         this.overflowOffset = this.scrollParent.offset();
2774                 }
2775
2776                 //Call callbacks
2777                 this._trigger("start", event, this._uiHash());
2778
2779                 //Recache the helper size
2780                 if(!this._preserveHelperProportions) {
2781                         this._cacheHelperProportions();
2782                 }
2783
2784
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 ) );
2789                         }
2790                 }
2791
2792                 //Prepare possible droppables
2793                 if($.ui.ddmanager) {
2794                         $.ui.ddmanager.current = this;
2795                 }
2796
2797                 if ($.ui.ddmanager && !o.dropBehaviour) {
2798                         $.ui.ddmanager.prepareOffsets(this, event);
2799                 }
2800
2801                 this.dragging = true;
2802
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
2805                 return true;
2806
2807         },
2808
2809         _mouseDrag: function(event) {
2810                 var i, item, itemElement, intersection,
2811                         o = this.options,
2812                         scrolled = false;
2813
2814                 //Compute the helpers position
2815                 this.position = this._generatePosition(event);
2816                 this.positionAbs = this._convertPositionTo("absolute");
2817
2818                 if (!this.lastPositionAbs) {
2819                         this.lastPositionAbs = this.positionAbs;
2820                 }
2821
2822                 //Do scrolling
2823                 if(this.options.scroll) {
2824                         if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
2825
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;
2830                                 }
2831
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;
2836                                 }
2837
2838                         } else {
2839
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);
2844                                 }
2845
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);
2850                                 }
2851
2852                         }
2853
2854                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2855                                 $.ui.ddmanager.prepareOffsets(this, event);
2856                         }
2857                 }
2858
2859                 //Regenerate the absolute position used for position checks
2860                 this.positionAbs = this._convertPositionTo("absolute");
2861
2862                 //Set the helper position
2863                 if(!this.options.axis || this.options.axis !== "y") {
2864                         this.helper[0].style.left = this.position.left+"px";
2865                 }
2866                 if(!this.options.axis || this.options.axis !== "x") {
2867                         this.helper[0].style.top = this.position.top+"px";
2868                 }
2869
2870                 //Rearrange
2871                 for (i = this.items.length - 1; i >= 0; i--) {
2872
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) {
2878                                 continue;
2879                         }
2880
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.
2885                         //
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) {
2889                                 continue;
2890                         }
2891
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)
2899                         ) {
2900
2901                                 this.direction = intersection === 1 ? "down" : "up";
2902
2903                                 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
2904                                         this._rearrange(event, item);
2905                                 } else {
2906                                         break;
2907                                 }
2908
2909                                 this._trigger("change", event, this._uiHash());
2910                                 break;
2911                         }
2912                 }
2913
2914                 //Post events to containers
2915                 this._contactContainers(event);
2916
2917                 //Interconnect with droppables
2918                 if($.ui.ddmanager) {
2919                         $.ui.ddmanager.drag(this, event);
2920                 }
2921
2922                 //Call callbacks
2923                 this._trigger("sort", event, this._uiHash());
2924
2925                 this.lastPositionAbs = this.positionAbs;
2926                 return false;
2927
2928         },
2929
2930         _mouseStop: function(event, noPropagation) {
2931
2932                 if(!event) {
2933                         return;
2934                 }
2935
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);
2939                 }
2940
2941                 if(this.options.revert) {
2942                         var that = this,
2943                                 cur = this.placeholder.offset();
2944
2945                         this.reverting = true;
2946
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() {
2951                                 that._clear(event);
2952                         });
2953                 } else {
2954                         this._clear(event, noPropagation);
2955                 }
2956
2957                 return false;
2958
2959         },
2960
2961         cancel: function() {
2962
2963                 if(this.dragging) {
2964
2965                         this._mouseUp({ target: null });
2966
2967                         if(this.options.helper === "original") {
2968                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
2969                         } else {
2970                                 this.currentItem.show();
2971                         }
2972
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;
2979                                 }
2980                         }
2981
2982                 }
2983
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]);
2988                         }
2989                         if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
2990                                 this.helper.remove();
2991                         }
2992
2993                         $.extend(this, {
2994                                 helper: null,
2995                                 dragging: false,
2996                                 reverting: false,
2997                                 _noFinalSort: null
2998                         });
2999
3000                         if(this.domPosition.prev) {
3001                                 $(this.domPosition.prev).after(this.currentItem);
3002                         } else {
3003                                 $(this.domPosition.parent).prepend(this.currentItem);
3004                         }
3005                 }
3006
3007                 return this;
3008
3009         },
3010
3011         serialize: function(o) {
3012
3013                 var items = this._getItemsAsjQuery(o && o.connected),
3014                         str = [];
3015                 o = o || {};
3016
3017                 $(items).each(function() {
3018                         var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
3019                         if (res) {
3020                                 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
3021                         }
3022                 });
3023
3024                 if(!str.length && o.key) {
3025                         str.push(o.key + "=");
3026                 }
3027
3028                 return str.join("&");
3029
3030         },
3031
3032         toArray: function(o) {
3033
3034                 var items = this._getItemsAsjQuery(o && o.connected),
3035                         ret = [];
3036
3037                 o = o || {};
3038
3039                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
3040                 return ret;
3041
3042         },
3043
3044         /* Be careful with the following core functions */
3045         _intersectsWith: function(item) {
3046
3047                 var x1 = this.positionAbs.left,
3048                         x2 = x1 + this.helperProportions.width,
3049                         y1 = this.positionAbs.top,
3050                         y2 = y1 + this.helperProportions.height,
3051                         l = item.left,
3052                         r = l + item.width,
3053                         t = item.top,
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;
3058
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"])
3062                 ) {
3063                         return isOverElement;
3064                 } else {
3065
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
3070
3071                 }
3072         },
3073
3074         _intersectsWithPointer: function(item) {
3075
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();
3081
3082                 if (!isOverElement) {
3083                         return false;
3084                 }
3085
3086                 return this.floating ?
3087                         ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
3088                         : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
3089
3090         },
3091
3092         _intersectsWithSides: function(item) {
3093
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();
3098
3099                 if (this.floating && horizontalDirection) {
3100                         return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
3101                 } else {
3102                         return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
3103                 }
3104
3105         },
3106
3107         _getDragVerticalDirection: function() {
3108                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
3109                 return delta !== 0 && (delta > 0 ? "down" : "up");
3110         },
3111
3112         _getDragHorizontalDirection: function() {
3113                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
3114                 return delta !== 0 && (delta > 0 ? "right" : "left");
3115         },
3116
3117         refresh: function(event) {
3118                 this._refreshItems(event);
3119                 this.refreshPositions();
3120                 return this;
3121         },
3122
3123         _connectWith: function() {
3124                 var options = this.options;
3125                 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
3126         },
3127
3128         _getItemsAsjQuery: function(connected) {
3129
3130                 var i, j, cur, inst,
3131                         items = [],
3132                         queries = [],
3133                         connectWith = this._connectWith();
3134
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]);
3142                                         }
3143                                 }
3144                         }
3145                 }
3146
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]);
3148
3149                 for (i = queries.length - 1; i >= 0; i--){
3150                         queries[i][0].each(function() {
3151                                 items.push(this);
3152                         });
3153                 }
3154
3155                 return $(items);
3156
3157         },
3158
3159         _removeCurrentsFromItems: function() {
3160
3161                 var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3162
3163                 this.items = $.grep(this.items, function (item) {
3164                         for (var j=0; j < list.length; j++) {
3165                                 if(list[j] === item.item[0]) {
3166                                         return false;
3167                                 }
3168                         }
3169                         return true;
3170                 });
3171
3172         },
3173
3174         _refreshItems: function(event) {
3175
3176                 this.items = [];
3177                 this.containers = [this];
3178
3179                 var i, j, cur, inst, targetData, _queries, item, queriesLength,
3180                         items = this.items,
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();
3183
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);
3192                                         }
3193                                 }
3194                         }
3195                 }
3196
3197                 for (i = queries.length - 1; i >= 0; i--) {
3198                         targetData = queries[i][1];
3199                         _queries = queries[i][0];
3200
3201                         for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3202                                 item = $(_queries[j]);
3203
3204                                 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
3205
3206                                 items.push({
3207                                         item: item,
3208                                         instance: targetData,
3209                                         width: 0, height: 0,
3210                                         left: 0, top: 0
3211                                 });
3212                         }
3213                 }
3214
3215         },
3216
3217         refreshPositions: function(fast) {
3218
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();
3222                 }
3223
3224                 var i, item, t, p;
3225
3226                 for (i = this.items.length - 1; i >= 0; i--){
3227                         item = this.items[i];
3228
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]) {
3231                                 continue;
3232                         }
3233
3234                         t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3235
3236                         if (!fast) {
3237                                 item.width = t.outerWidth();
3238                                 item.height = t.outerHeight();
3239                         }
3240
3241                         p = t.offset();
3242                         item.left = p.left;
3243                         item.top = p.top;
3244                 }
3245
3246                 if(this.options.custom && this.options.custom.refreshContainers) {
3247                         this.options.custom.refreshContainers.call(this);
3248                 } else {
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();
3255                         }
3256                 }
3257
3258                 return this;
3259         },
3260
3261         _createPlaceholder: function(that) {
3262                 that = that || this;
3263                 var className,
3264                         o = that.options;
3265
3266                 if(!o.placeholder || o.placeholder.constructor === String) {
3267                         className = o.placeholder;
3268                         o.placeholder = {
3269                                 element: function() {
3270
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];
3274
3275                                         if(!className) {
3276                                                 el.style.visibility = "hidden";
3277                                         }
3278
3279                                         return el;
3280                                 },
3281                                 update: function(container, p) {
3282
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) {
3286                                                 return;
3287                                         }
3288
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)); }
3292                                 }
3293                         };
3294                 }
3295
3296                 //Create the placeholder
3297                 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
3298
3299                 //Append it after the actual current item
3300                 that.currentItem.after(that.placeholder);
3301
3302                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3303                 o.placeholder.update(that, that.placeholder);
3304
3305         },
3306
3307         _contactContainers: function(event) {
3308                 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
3309                         innermostContainer = null,
3310                         innermostIndex = null;
3311
3312                 // get innermost container that intersects with item
3313                 for (i = this.containers.length - 1; i >= 0; i--) {
3314
3315                         // never consider a container that's located within the item itself
3316                         if($.contains(this.currentItem[0], this.containers[i].element[0])) {
3317                                 continue;
3318                         }
3319
3320                         if(this._intersectsWith(this.containers[i].containerCache)) {
3321
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])) {
3324                                         continue;
3325                                 }
3326
3327                                 innermostContainer = this.containers[i];
3328                                 innermostIndex = i;
3329
3330                         } else {
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;
3335                                 }
3336                         }
3337
3338                 }
3339
3340                 // if no intersecting containers found, return
3341                 if(!innermostContainer) {
3342                         return;
3343                 }
3344
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;
3349                 } else {
3350
3351                         //When entering a new container, we will find the item with the least distance and append our item near it
3352                         dist = 10000;
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])) {
3359                                         continue;
3360                                 }
3361                                 if(this.items[j].item[0] === this.currentItem[0]) {
3362                                         continue;
3363                                 }
3364                                 cur = this.items[j].item.offset()[posProperty];
3365                                 nearBottom = false;
3366                                 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
3367                                         nearBottom = true;
3368                                         cur += this.items[j][sizeProperty];
3369                                 }
3370
3371                                 if(Math.abs(cur - base) < dist) {
3372                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3373                                         this.direction = nearBottom ? "up": "down";
3374                                 }
3375                         }
3376
3377                         //Check if dropOnEmpty is enabled
3378                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
3379                                 return;
3380                         }
3381
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));
3386
3387                         //Update the placeholder
3388                         this.options.placeholder.update(this.currentContainer, this.placeholder);
3389
3390                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3391                         this.containers[innermostIndex].containerCache.over = 1;
3392                 }
3393
3394
3395         },
3396
3397         _createHelper: function(event) {
3398
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);
3401
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]);
3405                 }
3406
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") };
3409                 }
3410
3411                 if(!helper[0].style.width || o.forceHelperSize) {
3412                         helper.width(this.currentItem.width());
3413                 }
3414                 if(!helper[0].style.height || o.forceHelperSize) {
3415                         helper.height(this.currentItem.height());
3416                 }
3417
3418                 return helper;
3419
3420         },
3421
3422         _adjustOffsetFromHelper: function(obj) {
3423                 if (typeof obj === "string") {
3424                         obj = obj.split(" ");
3425                 }
3426                 if ($.isArray(obj)) {
3427                         obj = {left: +obj[0], top: +obj[1] || 0};
3428                 }
3429                 if ("left" in obj) {
3430                         this.offset.click.left = obj.left + this.margins.left;
3431                 }
3432                 if ("right" in obj) {
3433                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3434                 }
3435                 if ("top" in obj) {
3436                         this.offset.click.top = obj.top + this.margins.top;
3437                 }
3438                 if ("bottom" in obj) {
3439                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3440                 }
3441         },
3442
3443         _getParentOffset: function() {
3444
3445
3446                 //Get the offsetParent and cache its position
3447                 this.offsetParent = this.helper.offsetParent();
3448                 var po = this.offsetParent.offset();
3449
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();
3457                 }
3458
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 };
3463                 }
3464
3465                 return {
3466                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3467                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3468                 };
3469
3470         },
3471
3472         _getRelativeOffset: function() {
3473
3474                 if(this.cssPosition === "relative") {
3475                         var p = this.currentItem.position();
3476                         return {
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()
3479                         };
3480                 } else {
3481                         return { top: 0, left: 0 };
3482                 }
3483
3484         },
3485
3486         _cacheMargins: function() {
3487                 this.margins = {
3488                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3489                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3490                 };
3491         },
3492
3493         _cacheHelperProportions: function() {
3494                 this.helperProportions = {
3495                         width: this.helper.outerWidth(),
3496                         height: this.helper.outerHeight()
3497                 };
3498         },
3499
3500         _setContainment: function() {
3501
3502                 var ce, co, over,
3503                         o = this.options;
3504                 if(o.containment === "parent") {
3505                         o.containment = this.helper[0].parentNode;
3506                 }
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
3513                         ];
3514                 }
3515
3516                 if(!(/^(document|window|parent)$/).test(o.containment)) {
3517                         ce = $(o.containment)[0];
3518                         co = $(o.containment).offset();
3519                         over = ($(ce).css("overflow") !== "hidden");
3520
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
3526                         ];
3527                 }
3528
3529         },
3530
3531         _convertPositionTo: function(d, pos) {
3532
3533                 if(!pos) {
3534                         pos = this.position;
3535                 }
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);
3539
3540                 return {
3541                         top: (
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)
3546                         ),
3547                         left: (
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)
3552                         )
3553                 };
3554
3555         },
3556
3557         _generatePosition: function(event) {
3558
3559                 var top, left,
3560                         o = this.options,
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);
3564
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();
3571                 }
3572
3573                 /*
3574                  * - Position constraining -
3575                  * Constrain the position to a mix of grid, containment.
3576                  */
3577
3578                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3579
3580                         if(this.containment) {
3581                                 if(event.pageX - this.offset.click.left < this.containment[0]) {
3582                                         pageX = this.containment[0] + this.offset.click.left;
3583                                 }
3584                                 if(event.pageY - this.offset.click.top < this.containment[1]) {
3585                                         pageY = this.containment[1] + this.offset.click.top;
3586                                 }
3587                                 if(event.pageX - this.offset.click.left > this.containment[2]) {
3588                                         pageX = this.containment[2] + this.offset.click.left;
3589                                 }
3590                                 if(event.pageY - this.offset.click.top > this.containment[3]) {
3591                                         pageY = this.containment[3] + this.offset.click.top;
3592                                 }
3593                         }
3594
3595                         if(o.grid) {
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;
3598
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;
3601                         }
3602
3603                 }
3604
3605                 return {
3606                         top: (
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() ) ))
3612                         ),
3613                         left: (
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() ))
3619                         )
3620                 };
3621
3622         },
3623
3624         _rearrange: function(event, i, a, hardRefresh) {
3625
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));
3627
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;
3635
3636                 this._delay(function() {
3637                         if(counter === this.counter) {
3638                                 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3639                         }
3640                 });
3641
3642         },
3643
3644         _clear: function(event, noPropagation) {
3645
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
3649                 var i,
3650                         delayedTriggers = [];
3651
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);
3656                 }
3657                 this._noFinalSort = null;
3658
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] = "";
3663                                 }
3664                         }
3665                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3666                 } else {
3667                         this.currentItem.show();
3668                 }
3669
3670                 if(this.fromOutside && !noPropagation) {
3671                         delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3672                 }
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
3675                 }
3676
3677                 // Check if the items Container has Changed and trigger appropriate
3678                 // events.
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));
3684                         }
3685                 }
3686
3687
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]));
3692                         }
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;
3696                         }
3697                 }
3698
3699                 //Do what was originally in plugins
3700                 if(this._storedCursor) {
3701                         $("body").css("cursor", this._storedCursor);
3702                 }
3703                 if(this._storedOpacity) {
3704                         this.helper.css("opacity", this._storedOpacity);
3705                 }
3706                 if(this._storedZIndex) {
3707                         this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
3708                 }
3709
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());
3718                         }
3719
3720                         this.fromOutside = false;
3721                         return false;
3722                 }
3723
3724                 if(!noPropagation) {
3725                         this._trigger("beforeStop", event, this._uiHash());
3726                 }
3727
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]);
3730
3731                 if(this.helper[0] !== this.currentItem[0]) {
3732                         this.helper.remove();
3733                 }
3734                 this.helper = null;
3735
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());
3741                 }
3742
3743                 this.fromOutside = false;
3744                 return true;
3745
3746         },
3747
3748         _trigger: function() {
3749                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
3750                         this.cancel();
3751                 }
3752         },
3753
3754         _uiHash: function(_inst) {
3755                 var inst = _inst || this;
3756                 return {
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
3764                 };
3765         }
3766
3767 });
3768
3769 })(jQuery);
3770 ;(jQuery.effects || (function($, undefined) {
3771
3772 var dataSpace = "ui-effects-";
3773
3774 $.effects = {
3775         effect: {}
3776 };
3777
3778 /*!
3779  * jQuery Color Animations v2.1.2
3780  * https://github.com/jquery/jquery-color
3781  *
3782  * Copyright 2013 jQuery Foundation and other contributors
3783  * Released under the MIT license.
3784  * http://jquery.org/license
3785  *
3786  * Date: Wed Jan 16 08:47:09 2013 -0600
3787  */
3788 (function( jQuery, undefined ) {
3789
3790         var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
3791
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.
3795         stringParsers = [{
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 ) {
3798                                 return [
3799                                         execResult[ 1 ],
3800                                         execResult[ 2 ],
3801                                         execResult[ 3 ],
3802                                         execResult[ 4 ]
3803                                 ];
3804                         }
3805                 }, {
3806                         re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
3807                         parse: function( execResult ) {
3808                                 return [
3809                                         execResult[ 1 ] * 2.55,
3810                                         execResult[ 2 ] * 2.55,
3811                                         execResult[ 3 ] * 2.55,
3812                                         execResult[ 4 ]
3813                                 ];
3814                         }
3815                 }, {
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 ) {
3819                                 return [
3820                                         parseInt( execResult[ 1 ], 16 ),
3821                                         parseInt( execResult[ 2 ], 16 ),
3822                                         parseInt( execResult[ 3 ], 16 )
3823                                 ];
3824                         }
3825                 }, {
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 ) {
3829                                 return [
3830                                         parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
3831                                         parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
3832                                         parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
3833                                 ];
3834                         }
3835                 }, {
3836                         re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
3837                         space: "hsla",
3838                         parse: function( execResult ) {
3839                                 return [
3840                                         execResult[ 1 ],
3841                                         execResult[ 2 ] / 100,
3842                                         execResult[ 3 ] / 100,
3843                                         execResult[ 4 ]
3844                                 ];
3845                         }
3846                 }],
3847
3848         // jQuery.Color( )
3849         color = jQuery.Color = function( color, green, blue, alpha ) {
3850                 return new jQuery.Color.fn.parse( color, green, blue, alpha );
3851         },
3852         spaces = {
3853                 rgba: {
3854                         props: {
3855                                 red: {
3856                                         idx: 0,
3857                                         type: "byte"
3858                                 },
3859                                 green: {
3860                                         idx: 1,
3861                                         type: "byte"
3862                                 },
3863                                 blue: {
3864                                         idx: 2,
3865                                         type: "byte"
3866                                 }
3867                         }
3868                 },
3869
3870                 hsla: {
3871                         props: {
3872                                 hue: {
3873                                         idx: 0,
3874                                         type: "degrees"
3875                                 },
3876                                 saturation: {
3877                                         idx: 1,
3878                                         type: "percent"
3879                                 },
3880                                 lightness: {
3881                                         idx: 2,
3882                                         type: "percent"
3883                                 }
3884                         }
3885                 }
3886         },
3887         propTypes = {
3888                 "byte": {
3889                         floor: true,
3890                         max: 255
3891                 },
3892                 "percent": {
3893                         max: 1
3894                 },
3895                 "degrees": {
3896                         mod: 360,
3897                         floor: true
3898                 }
3899         },
3900         support = color.support = {},
3901
3902         // element for support tests
3903         supportElem = jQuery( "<p>" )[ 0 ],
3904
3905         // colors = jQuery.Color.names
3906         colors,
3907
3908         // local aliases of functions called often
3909         each = jQuery.each;
3910
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;
3914
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 = {
3920                 idx: 3,
3921                 type: "percent",
3922                 def: 1
3923         };
3924 });
3925
3926 function clamp( value, prop, allowEmpty ) {
3927         var type = propTypes[ prop.type ] || {};
3928
3929         if ( value == null ) {
3930                 return (allowEmpty || !prop.def) ? null : prop.def;
3931         }
3932
3933         // ~~ is an short way of doing floor for positive numbers
3934         value = type.floor ? ~~value : parseFloat( value );
3935
3936         // IE will pass in empty strings as value for alpha,
3937         // which will hit this case
3938         if ( isNaN( value ) ) {
3939                 return prop.def;
3940         }
3941
3942         if ( type.mod ) {
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;
3946         }
3947
3948         // for now all property types without mod have min and max
3949         return 0 > value ? 0 : type.max < value ? type.max : value;
3950 }
3951
3952 function stringParse( string ) {
3953         var inst = color(),
3954                 rgba = inst._rgba = [];
3955
3956         string = string.toLowerCase();
3957
3958         each( stringParsers, function( i, parser ) {
3959                 var parsed,
3960                         match = parser.re.exec( string ),
3961                         values = match && parser.parse( match ),
3962                         spaceName = parser.space || "rgba";
3963
3964                 if ( values ) {
3965                         parsed = inst[ spaceName ]( values );
3966
3967                         // if this was an rgba parse the assignment might happen twice
3968                         // oh well....
3969                         inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
3970                         rgba = inst._rgba = parsed._rgba;
3971
3972                         // exit each( stringParsers ) here because we matched
3973                         return false;
3974                 }
3975         });
3976
3977         // Found a stringParser that handled it
3978         if ( rgba.length ) {
3979
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 );
3984                 }
3985                 return inst;
3986         }
3987
3988         // named colors
3989         return colors[ string ];
3990 }
3991
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 ];
3996                         return this;
3997                 }
3998                 if ( red.jquery || red.nodeType ) {
3999                         red = jQuery( red ).css( green );
4000                         green = undefined;
4001                 }
4002
4003                 var inst = this,
4004                         type = jQuery.type( red ),
4005                         rgba = this._rgba = [];
4006
4007                 // more than 1 argument specified - assume ( red, green, blue, alpha )
4008                 if ( green !== undefined ) {
4009                         red = [ red, green, blue, alpha ];
4010                         type = "array";
4011                 }
4012
4013                 if ( type === "string" ) {
4014                         return this.parse( stringParse( red ) || colors._default );
4015                 }
4016
4017                 if ( type === "array" ) {
4018                         each( spaces.rgba.props, function( key, prop ) {
4019                                 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
4020                         });
4021                         return this;
4022                 }
4023
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();
4029                                         }
4030                                 });
4031                         } else {
4032                                 each( spaces, function( spaceName, space ) {
4033                                         var cache = space.cache;
4034                                         each( space.props, function( key, prop ) {
4035
4036                                                 // if the cache doesn't exist, and we know how to convert
4037                                                 if ( !inst[ cache ] && space.to ) {
4038
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 ) {
4042                                                                 return;
4043                                                         }
4044                                                         inst[ cache ] = space.to( inst._rgba );
4045                                                 }
4046
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 );
4050                                         });
4051
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;
4056                                                 if ( space.from ) {
4057                                                         inst._rgba = space.from( inst[ cache ] );
4058                                                 }
4059                                         }
4060                                 });
4061                         }
4062                         return this;
4063                 }
4064         },
4065         is: function( compare ) {
4066                 var is = color( compare ),
4067                         same = true,
4068                         inst = this;
4069
4070                 each( spaces, function( _, space ) {
4071                         var localCache,
4072                                 isCache = is[ space.cache ];
4073                         if (isCache) {
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 ] );
4078                                                 return same;
4079                                         }
4080                                 });
4081                         }
4082                         return same;
4083                 });
4084                 return same;
4085         },
4086         _space: function() {
4087                 var used = [],
4088                         inst = this;
4089                 each( spaces, function( spaceName, space ) {
4090                         if ( inst[ space.cache ] ) {
4091                                 used.push( spaceName );
4092                         }
4093                 });
4094                 return used.pop();
4095         },
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();
4103
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 ] || {};
4110
4111                         // if null, don't override start value
4112                         if ( endValue === null ) {
4113                                 return;
4114                         }
4115                         // if null - use end
4116                         if ( startValue === null ) {
4117                                 result[ index ] = endValue;
4118                         } else {
4119                                 if ( type.mod ) {
4120                                         if ( endValue - startValue > type.mod / 2 ) {
4121                                                 startValue += type.mod;
4122                                         } else if ( startValue - endValue > type.mod / 2 ) {
4123                                                 startValue -= type.mod;
4124                                         }
4125                                 }
4126                                 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
4127                         }
4128                 });
4129                 return this[ spaceName ]( result );
4130         },
4131         blend: function( opaque ) {
4132                 // if we are already opaque - return ourself
4133                 if ( this._rgba[ 3 ] === 1 ) {
4134                         return this;
4135                 }
4136
4137                 var rgb = this._rgba.slice(),
4138                         a = rgb.pop(),
4139                         blend = color( opaque )._rgba;
4140
4141                 return color( jQuery.map( rgb, function( v, i ) {
4142                         return ( 1 - a ) * blend[ i ] + a * v;
4143                 }));
4144         },
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;
4149                         });
4150
4151                 if ( rgba[ 3 ] === 1 ) {
4152                         rgba.pop();
4153                         prefix = "rgb(";
4154                 }
4155
4156                 return prefix + rgba.join() + ")";
4157         },
4158         toHslaString: function() {
4159                 var prefix = "hsla(",
4160                         hsla = jQuery.map( this.hsla(), function( v, i ) {
4161                                 if ( v == null ) {
4162                                         v = i > 2 ? 1 : 0;
4163                                 }
4164
4165                                 // catch 1 and 2
4166                                 if ( i && i < 3 ) {
4167                                         v = Math.round( v * 100 ) + "%";
4168                                 }
4169                                 return v;
4170                         });
4171
4172                 if ( hsla[ 3 ] === 1 ) {
4173                         hsla.pop();
4174                         prefix = "hsl(";
4175                 }
4176                 return prefix + hsla.join() + ")";
4177         },
4178         toHexString: function( includeAlpha ) {
4179                 var rgba = this._rgba.slice(),
4180                         alpha = rgba.pop();
4181
4182                 if ( includeAlpha ) {
4183                         rgba.push( ~~( alpha * 255 ) );
4184                 }
4185
4186                 return "#" + jQuery.map( rgba, function( v ) {
4187
4188                         // default to 0 when nulls exist
4189                         v = ( v || 0 ).toString( 16 );
4190                         return v.length === 1 ? "0" + v : v;
4191                 }).join("");
4192         },
4193         toString: function() {
4194                 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
4195         }
4196 });
4197 color.fn.parse.prototype = color.fn;
4198
4199 // hsla conversions adapted from:
4200 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
4201
4202 function hue2rgb( p, q, h ) {
4203         h = ( h + 1 ) % 1;
4204         if ( h * 6 < 1 ) {
4205                 return p + (q - p) * h * 6;
4206         }
4207         if ( h * 2 < 1) {
4208                 return q;
4209         }
4210         if ( h * 3 < 2 ) {
4211                 return p + (q - p) * ((2/3) - h) * 6;
4212         }
4213         return p;
4214 }
4215
4216 spaces.hsla.to = function ( rgba ) {
4217         if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
4218                 return [ null, null, null, rgba[ 3 ] ];
4219         }
4220         var r = rgba[ 0 ] / 255,
4221                 g = rgba[ 1 ] / 255,
4222                 b = rgba[ 2 ] / 255,
4223                 a = rgba[ 3 ],
4224                 max = Math.max( r, g, b ),
4225                 min = Math.min( r, g, b ),
4226                 diff = max - min,
4227                 add = max + min,
4228                 l = add * 0.5,
4229                 h, s;
4230
4231         if ( min === max ) {
4232                 h = 0;
4233         } else if ( r === max ) {
4234                 h = ( 60 * ( g - b ) / diff ) + 360;
4235         } else if ( g === max ) {
4236                 h = ( 60 * ( b - r ) / diff ) + 120;
4237         } else {
4238                 h = ( 60 * ( r - g ) / diff ) + 240;
4239         }
4240
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)
4243         if ( diff === 0 ) {
4244                 s = 0;
4245         } else if ( l <= 0.5 ) {
4246                 s = diff / add;
4247         } else {
4248                 s = diff / ( 2 - add );
4249         }
4250         return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
4251 };
4252
4253 spaces.hsla.from = function ( hsla ) {
4254         if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
4255                 return [ null, null, null, hsla[ 3 ] ];
4256         }
4257         var h = hsla[ 0 ] / 360,
4258                 s = hsla[ 1 ],
4259                 l = hsla[ 2 ],
4260                 a = hsla[ 3 ],
4261                 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
4262                 p = 2 * l - q;
4263
4264         return [
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 ),
4268                 a
4269         ];
4270 };
4271
4272
4273 each( spaces, function( spaceName, space ) {
4274         var props = space.props,
4275                 cache = space.cache,
4276                 to = space.to,
4277                 from = space.from;
4278
4279         // makes rgba() and hsla()
4280         color.fn[ spaceName ] = function( value ) {
4281
4282                 // generate a cache for this space if it doesn't exist
4283                 if ( to && !this[ cache ] ) {
4284                         this[ cache ] = to( this._rgba );
4285                 }
4286                 if ( value === undefined ) {
4287                         return this[ cache ].slice();
4288                 }
4289
4290                 var ret,
4291                         type = jQuery.type( value ),
4292                         arr = ( type === "array" || type === "object" ) ? value : arguments,
4293                         local = this[ cache ].slice();
4294
4295                 each( props, function( key, prop ) {
4296                         var val = arr[ type === "object" ? key : prop.idx ];
4297                         if ( val == null ) {
4298                                 val = local[ prop.idx ];
4299                         }
4300                         local[ prop.idx ] = clamp( val, prop );
4301                 });
4302
4303                 if ( from ) {
4304                         ret = color( from( local ) );
4305                         ret[ cache ] = local;
4306                         return ret;
4307                 } else {
4308                         return color( local );
4309                 }
4310         };
4311
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 ] ) {
4316                         return;
4317                 }
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 ],
4323                                 match;
4324
4325                         if ( vtype === "undefined" ) {
4326                                 return cur;
4327                         }
4328
4329                         if ( vtype === "function" ) {
4330                                 value = value.call( this, cur );
4331                                 vtype = jQuery.type( value );
4332                         }
4333                         if ( value == null && prop.empty ) {
4334                                 return this;
4335                         }
4336                         if ( vtype === "string" ) {
4337                                 match = rplusequals.exec( value );
4338                                 if ( match ) {
4339                                         value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
4340                                 }
4341                         }
4342                         local[ prop.idx ] = value;
4343                         return this[ fn ]( local );
4344                 };
4345         });
4346 });
4347
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 = "";
4357
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;
4362                                                 while (
4363                                                         (backgroundColor === "" || backgroundColor === "transparent") &&
4364                                                         curElem && curElem.style
4365                                                 ) {
4366                                                         try {
4367                                                                 backgroundColor = jQuery.css( curElem, "backgroundColor" );
4368                                                                 curElem = curElem.parentNode;
4369                                                         } catch ( e ) {
4370                                                         }
4371                                                 }
4372
4373                                                 value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
4374                                                         backgroundColor :
4375                                                         "_default" );
4376                                         }
4377
4378                                         value = value.toRgbaString();
4379                                 }
4380                                 try {
4381                                         elem.style[ hook ] = value;
4382                                 } catch( e ) {
4383                                         // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
4384                                 }
4385                         }
4386                 };
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;
4392                         }
4393                         jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
4394                 };
4395         });
4396
4397 };
4398
4399 color.hook( stepHooks );
4400
4401 jQuery.cssHooks.borderColor = {
4402         expand: function( value ) {
4403                 var expanded = {};
4404
4405                 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
4406                         expanded[ "border" + part + "Color" ] = value;
4407                 });
4408                 return expanded;
4409         }
4410 };
4411
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
4417         aqua: "#00ffff",
4418         black: "#000000",
4419         blue: "#0000ff",
4420         fuchsia: "#ff00ff",
4421         gray: "#808080",
4422         green: "#008000",
4423         lime: "#00ff00",
4424         maroon: "#800000",
4425         navy: "#000080",
4426         olive: "#808000",
4427         purple: "#800080",
4428         red: "#ff0000",
4429         silver: "#c0c0c0",
4430         teal: "#008080",
4431         white: "#ffffff",
4432         yellow: "#ffff00",
4433
4434         // 4.2.3. "transparent" color keyword
4435         transparent: [ null, null, null, 0 ],
4436
4437         _default: "#ffffff"
4438 };
4439
4440 })( jQuery );
4441
4442
4443 /******************************************************************************/
4444 /****************************** CLASS ANIMATIONS ******************************/
4445 /******************************************************************************/
4446 (function() {
4447
4448 var classAnimationActions = [ "add", "remove", "toggle" ],
4449         shorthandStyles = {
4450                 border: 1,
4451                 borderBottom: 1,
4452                 borderColor: 1,
4453                 borderLeft: 1,
4454                 borderRight: 1,
4455                 borderTop: 1,
4456                 borderWidth: 1,
4457                 margin: 1,
4458                 padding: 1
4459         };
4460
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 );
4465                         fx.setAttr = true;
4466                 }
4467         };
4468 });
4469
4470 function getElementStyles( elem ) {
4471         var key, len,
4472                 style = elem.ownerDocument.defaultView ?
4473                         elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
4474                         elem.currentStyle,
4475                 styles = {};
4476
4477         if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
4478                 len = style.length;
4479                 while ( len-- ) {
4480                         key = style[ len ];
4481                         if ( typeof style[ key ] === "string" ) {
4482                                 styles[ $.camelCase( key ) ] = style[ key ];
4483                         }
4484                 }
4485         // support: Opera, IE <9
4486         } else {
4487                 for ( key in style ) {
4488                         if ( typeof style[ key ] === "string" ) {
4489                                 styles[ key ] = style[ key ];
4490                         }
4491                 }
4492         }
4493
4494         return styles;
4495 }
4496
4497
4498 function styleDifference( oldStyle, newStyle ) {
4499         var diff = {},
4500                 name, value;
4501
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;
4508                                 }
4509                         }
4510                 }
4511         }
4512
4513         return diff;
4514 }
4515
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 )
4521                 );
4522         };
4523 }
4524
4525 $.effects.animateClass = function( value, duration, easing, callback ) {
4526         var o = $.speed( duration, easing, callback );
4527
4528         return this.queue( function() {
4529                 var animated = $( this ),
4530                         baseClass = animated.attr( "class" ) || "",
4531                         applyClassChange,
4532                         allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
4533
4534                 // map the animated objects to store the original styles.
4535                 allAnimations = allAnimations.map(function() {
4536                         var el = $( this );
4537                         return {
4538                                 el: el,
4539                                 start: getElementStyles( this )
4540                         };
4541                 });
4542
4543                 // apply class change
4544                 applyClassChange = function() {
4545                         $.each( classAnimationActions, function(i, action) {
4546                                 if ( value[ action ] ) {
4547                                         animated[ action + "Class" ]( value[ action ] );
4548                                 }
4549                         });
4550                 };
4551                 applyClassChange();
4552
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 );
4557                         return this;
4558                 });
4559
4560                 // apply original class
4561                 animated.attr( "class", baseClass );
4562
4563                 // map all animated objects again - this time collecting a promise
4564                 allAnimations = allAnimations.map(function() {
4565                         var styleInfo = this,
4566                                 dfd = $.Deferred(),
4567                                 opts = $.extend({}, o, {
4568                                         queue: false,
4569                                         complete: function() {
4570                                                 dfd.resolve( styleInfo );
4571                                         }
4572                                 });
4573
4574                         this.el.animate( this.diff, opts );
4575                         return dfd.promise();
4576                 });
4577
4578                 // once all animations have completed:
4579                 $.when.apply( $, allAnimations.get() ).done(function() {
4580
4581                         // set the final class
4582                         applyClassChange();
4583
4584                         // for each animated element,
4585                         // clear all css properties that were animated
4586                         $.each( arguments, function() {
4587                                 var el = this.el;
4588                                 $.each( this.diff, function(key) {
4589                                         el.css( key, "" );
4590                                 });
4591                         });
4592
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 ] );
4596                 });
4597         });
4598 };
4599
4600 $.fn.extend({
4601         _addClass: $.fn.addClass,
4602         addClass: function( classNames, speed, easing, callback ) {
4603                 return speed ?
4604                         $.effects.animateClass.call( this,
4605                                 { add: classNames }, speed, easing, callback ) :
4606                         this._addClass( classNames );
4607         },
4608
4609         _removeClass: $.fn.removeClass,
4610         removeClass: function( classNames, speed, easing, callback ) {
4611                 return speed ?
4612                         $.effects.animateClass.call( this,
4613                                 { remove: classNames }, speed, easing, callback ) :
4614                         this._removeClass( classNames );
4615         },
4616
4617         _toggleClass: $.fn.toggleClass,
4618         toggleClass: function( classNames, force, speed, easing, callback ) {
4619                 if ( typeof force === "boolean" || force === undefined ) {
4620                         if ( !speed ) {
4621                                 // without speed parameter
4622                                 return this._toggleClass( classNames, force );
4623                         } else {
4624                                 return $.effects.animateClass.call( this,
4625                                         (force ? { add: classNames } : { remove: classNames }),
4626                                         speed, easing, callback );
4627                         }
4628                 } else {
4629                         // without force parameter
4630                         return $.effects.animateClass.call( this,
4631                                 { toggle: classNames }, force, speed, easing );
4632                 }
4633         },
4634
4635         switchClass: function( remove, add, speed, easing, callback) {
4636                 return $.effects.animateClass.call( this, {
4637                         add: add,
4638                         remove: remove
4639                 }, speed, easing, callback );
4640         }
4641 });
4642
4643 })();
4644
4645 /******************************************************************************/
4646 /*********************************** EFFECTS **********************************/
4647 /******************************************************************************/
4648
4649 (function() {
4650
4651 $.extend( $.effects, {
4652         version: "1.10.0",
4653
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 ] ] );
4659                         }
4660                 }
4661         },
4662
4663         // Restores a set of previously saved properties from a data storage
4664         restore: function( element, set ) {
4665                 var val, i;
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 ) {
4675                                         val = "";
4676                                 }
4677                                 element.css( set[ i ], val );
4678                         }
4679                 }
4680         },
4681
4682         setMode: function( el, mode ) {
4683                 if (mode === "toggle") {
4684                         mode = el.is( ":hidden" ) ? "show" : "hide";
4685                 }
4686                 return mode;
4687         },
4688
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 ) {
4692                 var y, x;
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;
4698                 }
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;
4704                 }
4705                 return {
4706                         x: x,
4707                         y: y
4708                 };
4709         },
4710
4711         // Wraps the element around a wrapper that copies position properties
4712         createWrapper: function( element ) {
4713
4714                 // if the element is already wrapped, return it
4715                 if ( element.parent().is( ".ui-effects-wrapper" )) {
4716                         return element.parent();
4717                 }
4718
4719                 // wrap the element
4720                 var props = {
4721                                 width: element.outerWidth(true),
4722                                 height: element.outerHeight(true),
4723                                 "float": element.css( "float" )
4724                         },
4725                         wrapper = $( "<div></div>" )
4726                                 .addClass( "ui-effects-wrapper" )
4727                                 .css({
4728                                         fontSize: "100%",
4729                                         background: "transparent",
4730                                         border: "none",
4731                                         margin: 0,
4732                                         padding: 0
4733                                 }),
4734                         // Store the size in case width/height are defined in % - Fixes #5245
4735                         size = {
4736                                 width: element.width(),
4737                                 height: element.height()
4738                         },
4739                         active = document.activeElement;
4740
4741                 // support: Firefox
4742                 // Firefox incorrectly exposes anonymous content
4743                 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
4744                 try {
4745                         active.id;
4746                 } catch( e ) {
4747                         active = document.body;
4748                 }
4749
4750                 element.wrap( wrapper );
4751
4752                 // Fixes #7595 - Elements lose focus when wrapped.
4753                 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4754                         $( active ).focus();
4755                 }
4756
4757                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
4758
4759                 // transfer positioning properties to the wrapper
4760                 if ( element.css( "position" ) === "static" ) {
4761                         wrapper.css({ position: "relative" });
4762                         element.css({ position: "relative" });
4763                 } else {
4764                         $.extend( props, {
4765                                 position: element.css( "position" ),
4766                                 zIndex: element.css( "z-index" )
4767                         });
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";
4772                                 }
4773                         });
4774                         element.css({
4775                                 position: "relative",
4776                                 top: 0,
4777                                 left: 0,
4778                                 right: "auto",
4779                                 bottom: "auto"
4780                         });
4781                 }
4782                 element.css(size);
4783
4784                 return wrapper.css( props ).show();
4785         },
4786
4787         removeWrapper: function( element ) {
4788                 var active = document.activeElement;
4789
4790                 if ( element.parent().is( ".ui-effects-wrapper" ) ) {
4791                         element.parent().replaceWith( element );
4792
4793                         // Fixes #7595 - Elements lose focus when wrapped.
4794                         if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4795                                 $( active ).focus();
4796                         }
4797                 }
4798
4799
4800                 return element;
4801         },
4802
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 ];
4809                         }
4810                 });
4811                 return value;
4812         }
4813 });
4814
4815 // return an effect options object for the given parameters:
4816 function _normalizeArguments( effect, options, speed, callback ) {
4817
4818         // allow passing all options as the first parameter
4819         if ( $.isPlainObject( effect ) ) {
4820                 options = effect;
4821                 effect = effect.effect;
4822         }
4823
4824         // convert to an object
4825         effect = { effect: effect };
4826
4827         // catch (effect, null, ...)
4828         if ( options == null ) {
4829                 options = {};
4830         }
4831
4832         // catch (effect, callback)
4833         if ( $.isFunction( options ) ) {
4834                 callback = options;
4835                 speed = null;
4836                 options = {};
4837         }
4838
4839         // catch (effect, speed, ?)
4840         if ( typeof options === "number" || $.fx.speeds[ options ] ) {
4841                 callback = speed;
4842                 speed = options;
4843                 options = {};
4844         }
4845
4846         // catch (effect, options, callback)
4847         if ( $.isFunction( speed ) ) {
4848                 callback = speed;
4849                 speed = null;
4850         }
4851
4852         // add options to effect
4853         if ( options ) {
4854                 $.extend( effect, options );
4855         }
4856
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;
4862
4863         effect.complete = callback || options.complete;
4864
4865         return effect;
4866 }
4867
4868 function standardSpeed( speed ) {
4869         // valid standard speeds
4870         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
4871                 return true;
4872         }
4873
4874         // invalid strings - treat as "normal" speed
4875         return typeof speed === "string" && !$.effects.effect[ speed ];
4876 }
4877
4878 $.fn.extend({
4879         effect: function( /* effect, options, speed, callback */ ) {
4880                 var args = _normalizeArguments.apply( this, arguments ),
4881                         mode = args.mode,
4882                         queue = args.queue,
4883                         effectMethod = $.effects.effect[ args.effect ];
4884
4885                 if ( $.fx.off || !effectMethod ) {
4886                         // delegate to the original method (e.g., .show()) if possible
4887                         if ( mode ) {
4888                                 return this[ mode ]( args.duration, args.complete );
4889                         } else {
4890                                 return this.each( function() {
4891                                         if ( args.complete ) {
4892                                                 args.complete.call( this );
4893                                         }
4894                                 });
4895                         }
4896                 }
4897
4898                 function run( next ) {
4899                         var elem = $( this ),
4900                                 complete = args.complete,
4901                                 mode = args.mode;
4902
4903                         function done() {
4904                                 if ( $.isFunction( complete ) ) {
4905                                         complete.call( elem[0] );
4906                                 }
4907                                 if ( $.isFunction( next ) ) {
4908                                         next();
4909                                 }
4910                         }
4911
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" ) {
4915                                 done();
4916                         } else {
4917                                 effectMethod.call( elem[0], args, done );
4918                         }
4919                 }
4920
4921                 return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
4922         },
4923
4924         _show: $.fn.show,
4925         show: function( speed ) {
4926                 if ( standardSpeed( speed ) ) {
4927                         return this._show.apply( this, arguments );
4928                 } else {
4929                         var args = _normalizeArguments.apply( this, arguments );
4930                         args.mode = "show";
4931                         return this.effect.call( this, args );
4932                 }
4933         },
4934
4935         _hide: $.fn.hide,
4936         hide: function( speed ) {
4937                 if ( standardSpeed( speed ) ) {
4938                         return this._hide.apply( this, arguments );
4939                 } else {
4940                         var args = _normalizeArguments.apply( this, arguments );
4941                         args.mode = "hide";
4942                         return this.effect.call( this, args );
4943                 }
4944         },
4945
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 );
4951                 } else {
4952                         var args = _normalizeArguments.apply( this, arguments );
4953                         args.mode = "toggle";
4954                         return this.effect.call( this, args );
4955                 }
4956         },
4957
4958         // helper functions
4959         cssUnit: function(key) {
4960                 var style = this.css( key ),
4961                         val = [];
4962
4963                 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
4964                         if ( style.indexOf( unit ) > 0 ) {
4965                                 val = [ parseFloat( style ), unit ];
4966                         }
4967                 });
4968                 return val;
4969         }
4970 });
4971
4972 })();
4973
4974 /******************************************************************************/
4975 /*********************************** EASING ***********************************/
4976 /******************************************************************************/
4977
4978 (function() {
4979
4980 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
4981
4982 var baseEasings = {};
4983
4984 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
4985         baseEasings[ name ] = function( p ) {
4986                 return Math.pow( p, i + 2 );
4987         };
4988 });
4989
4990 $.extend( baseEasings, {
4991         Sine: function ( p ) {
4992                 return 1 - Math.cos( p * Math.PI / 2 );
4993         },
4994         Circ: function ( p ) {
4995                 return 1 - Math.sqrt( 1 - p * p );
4996         },
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 );
5000         },
5001         Back: function( p ) {
5002                 return p * p * ( 3 * p - 2 );
5003         },
5004         Bounce: function ( p ) {
5005                 var pow2,
5006                         bounce = 4;
5007
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 );
5010         }
5011 });
5012
5013 $.each( baseEasings, function( name, easeIn ) {
5014         $.easing[ "easeIn" + name ] = easeIn;
5015         $.easing[ "easeOut" + name ] = function( p ) {
5016                 return 1 - easeIn( 1 - p );
5017         };
5018         $.easing[ "easeInOut" + name ] = function( p ) {
5019                 return p < 0.5 ?
5020                         easeIn( p * 2 ) / 2 :
5021                         1 - easeIn( p * -2 + 2 ) / 2;
5022         };
5023 });
5024
5025 })();
5026
5027 })(jQuery));