Alternc  latest
Alternc logiel libre pour l'hébergement
jquery-ui-1.10.3.custom.js
Go to the documentation of this file.
1 /*! jQuery UI - v1.10.3 - 2013-07-17
2 * http://jqueryui.com
3 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
4 * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
5 
6 (function( $, undefined ) {
7 
8 var uuid = 0,
9  runiqueId = /^ui-id-\d+$/;
10 
11 // $.ui might exist from components with no dependencies, e.g., $.ui.position
12 $.ui = $.ui || {};
13 
14 $.extend( $.ui, {
15  version: "1.10.3",
16 
17  keyCode: {
18  BACKSPACE: 8,
19  COMMA: 188,
20  DELETE: 46,
21  DOWN: 40,
22  END: 35,
23  ENTER: 13,
24  ESCAPE: 27,
25  HOME: 36,
26  LEFT: 37,
27  NUMPAD_ADD: 107,
28  NUMPAD_DECIMAL: 110,
29  NUMPAD_DIVIDE: 111,
30  NUMPAD_ENTER: 108,
31  NUMPAD_MULTIPLY: 106,
32  NUMPAD_SUBTRACT: 109,
33  PAGE_DOWN: 34,
34  PAGE_UP: 33,
35  PERIOD: 190,
36  RIGHT: 39,
37  SPACE: 32,
38  TAB: 9,
39  UP: 38
40  }
41 });
42 
43 // plugins
44 $.fn.extend({
45  focus: (function( orig ) {
46  return function( delay, fn ) {
47  return typeof delay === "number" ?
48  this.each(function() {
49  var elem = this;
50  setTimeout(function() {
51  $( elem ).focus();
52  if ( fn ) {
53  fn.call( elem );
54  }
55  }, delay );
56  }) :
57  orig.apply( this, arguments );
58  };
59  })( $.fn.focus ),
60 
61  scrollParent: function() {
62  var scrollParent;
63  if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
64  scrollParent = this.parents().filter(function() {
65  return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
66  }).eq(0);
67  } else {
68  scrollParent = this.parents().filter(function() {
69  return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
70  }).eq(0);
71  }
72 
73  return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
74  },
75 
76  zIndex: function( zIndex ) {
77  if ( zIndex !== undefined ) {
78  return this.css( "zIndex", zIndex );
79  }
80 
81  if ( this.length ) {
82  var elem = $( this[ 0 ] ), position, value;
83  while ( elem.length && elem[ 0 ] !== document ) {
84  // Ignore z-index if position is set to a value where z-index is ignored by the browser
85  // This makes behavior of this function consistent across browsers
86  // WebKit always returns auto if the element is positioned
87  position = elem.css( "position" );
88  if ( position === "absolute" || position === "relative" || position === "fixed" ) {
89  // IE returns 0 when zIndex is not specified
90  // other browsers return a string
91  // we ignore the case of nested elements with an explicit value of 0
92  // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
93  value = parseInt( elem.css( "zIndex" ), 10 );
94  if ( !isNaN( value ) && value !== 0 ) {
95  return value;
96  }
97  }
98  elem = elem.parent();
99  }
100  }
101 
102  return 0;
103  },
104 
105  uniqueId: function() {
106  return this.each(function() {
107  if ( !this.id ) {
108  this.id = "ui-id-" + (++uuid);
109  }
110  });
111  },
112 
113  removeUniqueId: function() {
114  return this.each(function() {
115  if ( runiqueId.test( this.id ) ) {
116  $( this ).removeAttr( "id" );
117  }
118  });
119  }
120 });
121 
122 // selectors
123 function focusable( element, isTabIndexNotNaN ) {
124  var map, mapName, img,
125  nodeName = element.nodeName.toLowerCase();
126  if ( "area" === nodeName ) {
127  map = element.parentNode;
128  mapName = map.name;
129  if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
130  return false;
131  }
132  img = $( "img[usemap=#" + mapName + "]" )[0];
133  return !!img && visible( img );
134  }
135  return ( /input|select|textarea|button|object/.test( nodeName ) ?
136  !element.disabled :
137  "a" === nodeName ?
138  element.href || isTabIndexNotNaN :
139  isTabIndexNotNaN) &&
140  // the element and all of its ancestors must be visible
141  visible( element );
142 }
143 
144 function visible( element ) {
145  return $.expr.filters.visible( element ) &&
146  !$( element ).parents().addBack().filter(function() {
147  return $.css( this, "visibility" ) === "hidden";
148  }).length;
149 }
150 
151 $.extend( $.expr[ ":" ], {
152  data: $.expr.createPseudo ?
153  $.expr.createPseudo(function( dataName ) {
154  return function( elem ) {
155  return !!$.data( elem, dataName );
156  };
157  }) :
158  // support: jQuery <1.8
159  function( elem, i, match ) {
160  return !!$.data( elem, match[ 3 ] );
161  },
162 
163  focusable: function( element ) {
164  return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
165  },
166 
167  tabbable: function( element ) {
168  var tabIndex = $.attr( element, "tabindex" ),
169  isTabIndexNaN = isNaN( tabIndex );
170  return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
171  }
172 });
173 
174 // support: jQuery <1.8
175 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
176  $.each( [ "Width", "Height" ], function( i, name ) {
177  var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
178  type = name.toLowerCase(),
179  orig = {
180  innerWidth: $.fn.innerWidth,
181  innerHeight: $.fn.innerHeight,
182  outerWidth: $.fn.outerWidth,
183  outerHeight: $.fn.outerHeight
184  };
185 
186  function reduce( elem, size, border, margin ) {
187  $.each( side, function() {
188  size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
189  if ( border ) {
190  size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
191  }
192  if ( margin ) {
193  size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
194  }
195  });
196  return size;
197  }
198 
199  $.fn[ "inner" + name ] = function( size ) {
200  if ( size === undefined ) {
201  return orig[ "inner" + name ].call( this );
202  }
203 
204  return this.each(function() {
205  $( this ).css( type, reduce( this, size ) + "px" );
206  });
207  };
208 
209  $.fn[ "outer" + name] = function( size, margin ) {
210  if ( typeof size !== "number" ) {
211  return orig[ "outer" + name ].call( this, size );
212  }
213 
214  return this.each(function() {
215  $( this).css( type, reduce( this, size, true, margin ) + "px" );
216  });
217  };
218  });
219 }
220 
221 // support: jQuery <1.8
222 if ( !$.fn.addBack ) {
223  $.fn.addBack = function( selector ) {
224  return this.add( selector == null ?
225  this.prevObject : this.prevObject.filter( selector )
226  );
227  };
228 }
229 
230 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
231 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
232  $.fn.removeData = (function( removeData ) {
233  return function( key ) {
234  if ( arguments.length ) {
235  return removeData.call( this, $.camelCase( key ) );
236  } else {
237  return removeData.call( this );
238  }
239  };
240  })( $.fn.removeData );
241 }
242 
243 
244 
245 
246 
247 // deprecated
248 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
249 
250 $.support.selectstart = "onselectstart" in document.createElement( "div" );
251 $.fn.extend({
252  disableSelection: function() {
253  return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
254  ".ui-disableSelection", function( event ) {
255  event.preventDefault();
256  });
257  },
258 
259  enableSelection: function() {
260  return this.unbind( ".ui-disableSelection" );
261  }
262 });
263 
264 $.extend( $.ui, {
265  // $.ui.plugin is deprecated. Use $.widget() extensions instead.
266  plugin: {
267  add: function( module, option, set ) {
268  var i,
269  proto = $.ui[ module ].prototype;
270  for ( i in set ) {
271  proto.plugins[ i ] = proto.plugins[ i ] || [];
272  proto.plugins[ i ].push( [ option, set[ i ] ] );
273  }
274  },
275  call: function( instance, name, args ) {
276  var i,
277  set = instance.plugins[ name ];
278  if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
279  return;
280  }
281 
282  for ( i = 0; i < set.length; i++ ) {
283  if ( instance.options[ set[ i ][ 0 ] ] ) {
284  set[ i ][ 1 ].apply( instance.element, args );
285  }
286  }
287  }
288  },
289 
290  // only used by resizable
291  hasScroll: function( el, a ) {
292 
293  //If overflow is hidden, the element might have extra content, but the user wants to hide it
294  if ( $( el ).css( "overflow" ) === "hidden") {
295  return false;
296  }
297 
298  var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
299  has = false;
300 
301  if ( el[ scroll ] > 0 ) {
302  return true;
303  }
304 
305  // TODO: determine which cases actually cause this to happen
306  // if the element doesn't have the scroll set, see if it's possible to
307  // set the scroll
308  el[ scroll ] = 1;
309  has = ( el[ scroll ] > 0 );
310  el[ scroll ] = 0;
311  return has;
312  }
313 });
314 
315 })( jQuery );
316 (function( $, undefined ) {
317 
318 var uuid = 0,
319  slice = Array.prototype.slice,
320  _cleanData = $.cleanData;
321 $.cleanData = function( elems ) {
322  for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323  try {
324  $( elem ).triggerHandler( "remove" );
325  // http://bugs.jquery.com/ticket/8235
326  } catch( e ) {}
327  }
328  _cleanData( elems );
329 };
330 
331 $.widget = function( name, base, prototype ) {
332  var fullName, existingConstructor, constructor, basePrototype,
333  // proxiedPrototype allows the provided prototype to remain unmodified
334  // so that it can be used as a mixin for multiple widgets (#8876)
335  proxiedPrototype = {},
336  namespace = name.split( "." )[ 0 ];
337 
338  name = name.split( "." )[ 1 ];
339  fullName = namespace + "-" + name;
340 
341  if ( !prototype ) {
342  prototype = base;
343  base = $.Widget;
344  }
345 
346  // create selector for plugin
347  $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348  return !!$.data( elem, fullName );
349  };
350 
351  $[ namespace ] = $[ namespace ] || {};
352  existingConstructor = $[ namespace ][ name ];
353  constructor = $[ namespace ][ name ] = function( options, element ) {
354  // allow instantiation without "new" keyword
355  if ( !this._createWidget ) {
356  return new constructor( options, element );
357  }
358 
359  // allow instantiation without initializing for simple inheritance
360  // must use "new" keyword (the code above always passes args)
361  if ( arguments.length ) {
362  this._createWidget( options, element );
363  }
364  };
365  // extend with the existing constructor to carry over any static properties
366  $.extend( constructor, existingConstructor, {
367  version: prototype.version,
368  // copy the object used to create the prototype in case we need to
369  // redefine the widget later
370  _proto: $.extend( {}, prototype ),
371  // track widgets that inherit from this widget in case this widget is
372  // redefined after a widget inherits from it
373  _childConstructors: []
374  });
375 
376  basePrototype = new base();
377  // we need to make the options hash a property directly on the new instance
378  // otherwise we'll modify the options hash on the prototype that we're
379  // inheriting from
380  basePrototype.options = $.widget.extend( {}, basePrototype.options );
381  $.each( prototype, function( prop, value ) {
382  if ( !$.isFunction( value ) ) {
383  proxiedPrototype[ prop ] = value;
384  return;
385  }
386  proxiedPrototype[ prop ] = (function() {
387  var _super = function() {
388  return base.prototype[ prop ].apply( this, arguments );
389  },
390  _superApply = function( args ) {
391  return base.prototype[ prop ].apply( this, args );
392  };
393  return function() {
394  var __super = this._super,
395  __superApply = this._superApply,
396  returnValue;
397 
398  this._super = _super;
399  this._superApply = _superApply;
400 
401  returnValue = value.apply( this, arguments );
402 
403  this._super = __super;
404  this._superApply = __superApply;
405 
406  return returnValue;
407  };
408  })();
409  });
410  constructor.prototype = $.widget.extend( basePrototype, {
411  // TODO: remove support for widgetEventPrefix
412  // always use the name + a colon as the prefix, e.g., draggable:start
413  // don't prefix for widgets that aren't DOM-based
414  widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
415  }, proxiedPrototype, {
416  constructor: constructor,
417  namespace: namespace,
418  widgetName: name,
419  widgetFullName: fullName
420  });
421 
422  // If this widget is being redefined then we need to find all widgets that
423  // are inheriting from it and redefine all of them so that they inherit from
424  // the new version of this widget. We're essentially trying to replace one
425  // level in the prototype chain.
426  if ( existingConstructor ) {
427  $.each( existingConstructor._childConstructors, function( i, child ) {
428  var childPrototype = child.prototype;
429 
430  // redefine the child widget using the same prototype that was
431  // originally used, but inherit from the new version of the base
432  $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433  });
434  // remove the list of existing child constructors from the old constructor
435  // so the old child constructors can be garbage collected
436  delete existingConstructor._childConstructors;
437  } else {
438  base._childConstructors.push( constructor );
439  }
440 
441  $.widget.bridge( name, constructor );
442 };
443 
444 $.widget.extend = function( target ) {
445  var input = slice.call( arguments, 1 ),
446  inputIndex = 0,
447  inputLength = input.length,
448  key,
449  value;
450  for ( ; inputIndex < inputLength; inputIndex++ ) {
451  for ( key in input[ inputIndex ] ) {
452  value = input[ inputIndex ][ key ];
453  if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454  // Clone objects
455  if ( $.isPlainObject( value ) ) {
456  target[ key ] = $.isPlainObject( target[ key ] ) ?
457  $.widget.extend( {}, target[ key ], value ) :
458  // Don't extend strings, arrays, etc. with objects
459  $.widget.extend( {}, value );
460  // Copy everything else by reference
461  } else {
462  target[ key ] = value;
463  }
464  }
465  }
466  }
467  return target;
468 };
469 
470 $.widget.bridge = function( name, object ) {
471  var fullName = object.prototype.widgetFullName || name;
472  $.fn[ name ] = function( options ) {
473  var isMethodCall = typeof options === "string",
474  args = slice.call( arguments, 1 ),
475  returnValue = this;
476 
477  // allow multiple hashes to be passed on init
478  options = !isMethodCall && args.length ?
479  $.widget.extend.apply( null, [ options ].concat(args) ) :
480  options;
481 
482  if ( isMethodCall ) {
483  this.each(function() {
484  var methodValue,
485  instance = $.data( this, fullName );
486  if ( !instance ) {
487  return $.error( "cannot call methods on " + name + " prior to initialization; " +
488  "attempted to call method '" + options + "'" );
489  }
490  if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491  return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492  }
493  methodValue = instance[ options ].apply( instance, args );
494  if ( methodValue !== instance && methodValue !== undefined ) {
495  returnValue = methodValue && methodValue.jquery ?
496  returnValue.pushStack( methodValue.get() ) :
497  methodValue;
498  return false;
499  }
500  });
501  } else {
502  this.each(function() {
503  var instance = $.data( this, fullName );
504  if ( instance ) {
505  instance.option( options || {} )._init();
506  } else {
507  $.data( this, fullName, new object( options, this ) );
508  }
509  });
510  }
511 
512  return returnValue;
513  };
514 };
515 
516 $.Widget = function( /* options, element */ ) {};
517 $.Widget._childConstructors = [];
518 
519 $.Widget.prototype = {
520  widgetName: "widget",
521  widgetEventPrefix: "",
522  defaultElement: "<div>",
523  options: {
524  disabled: false,
525 
526  // callbacks
527  create: null
528  },
529  _createWidget: function( options, element ) {
530  element = $( element || this.defaultElement || this )[ 0 ];
531  this.element = $( element );
532  this.uuid = uuid++;
533  this.eventNamespace = "." + this.widgetName + this.uuid;
534  this.options = $.widget.extend( {},
535  this.options,
536  this._getCreateOptions(),
537  options );
538 
539  this.bindings = $();
540  this.hoverable = $();
541  this.focusable = $();
542 
543  if ( element !== this ) {
544  $.data( element, this.widgetFullName, this );
545  this._on( true, this.element, {
546  remove: function( event ) {
547  if ( event.target === element ) {
548  this.destroy();
549  }
550  }
551  });
552  this.document = $( element.style ?
553  // element within the document
554  element.ownerDocument :
555  // element is window or document
556  element.document || element );
557  this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558  }
559 
560  this._create();
561  this._trigger( "create", null, this._getCreateEventData() );
562  this._init();
563  },
564  _getCreateOptions: $.noop,
565  _getCreateEventData: $.noop,
566  _create: $.noop,
567  _init: $.noop,
568 
569  destroy: function() {
570  this._destroy();
571  // we can probably remove the unbind calls in 2.0
572  // all event bindings should go through this._on()
573  this.element
574  .unbind( this.eventNamespace )
575  // 1.9 BC for #7810
576  // TODO remove dual storage
577  .removeData( this.widgetName )
578  .removeData( this.widgetFullName )
579  // support: jquery <1.6.3
580  // http://bugs.jquery.com/ticket/9413
581  .removeData( $.camelCase( this.widgetFullName ) );
582  this.widget()
583  .unbind( this.eventNamespace )
584  .removeAttr( "aria-disabled" )
585  .removeClass(
586  this.widgetFullName + "-disabled " +
587  "ui-state-disabled" );
588 
589  // clean up events and states
590  this.bindings.unbind( this.eventNamespace );
591  this.hoverable.removeClass( "ui-state-hover" );
592  this.focusable.removeClass( "ui-state-focus" );
593  },
594  _destroy: $.noop,
595 
596  widget: function() {
597  return this.element;
598  },
599 
600  option: function( key, value ) {
601  var options = key,
602  parts,
603  curOption,
604  i;
605 
606  if ( arguments.length === 0 ) {
607  // don't return a reference to the internal hash
608  return $.widget.extend( {}, this.options );
609  }
610 
611  if ( typeof key === "string" ) {
612  // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613  options = {};
614  parts = key.split( "." );
615  key = parts.shift();
616  if ( parts.length ) {
617  curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618  for ( i = 0; i < parts.length - 1; i++ ) {
619  curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620  curOption = curOption[ parts[ i ] ];
621  }
622  key = parts.pop();
623  if ( value === undefined ) {
624  return curOption[ key ] === undefined ? null : curOption[ key ];
625  }
626  curOption[ key ] = value;
627  } else {
628  if ( value === undefined ) {
629  return this.options[ key ] === undefined ? null : this.options[ key ];
630  }
631  options[ key ] = value;
632  }
633  }
634 
635  this._setOptions( options );
636 
637  return this;
638  },
639  _setOptions: function( options ) {
640  var key;
641 
642  for ( key in options ) {
643  this._setOption( key, options[ key ] );
644  }
645 
646  return this;
647  },
648  _setOption: function( key, value ) {
649  this.options[ key ] = value;
650 
651  if ( key === "disabled" ) {
652  this.widget()
653  .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654  .attr( "aria-disabled", value );
655  this.hoverable.removeClass( "ui-state-hover" );
656  this.focusable.removeClass( "ui-state-focus" );
657  }
658 
659  return this;
660  },
661 
662  enable: function() {
663  return this._setOption( "disabled", false );
664  },
665  disable: function() {
666  return this._setOption( "disabled", true );
667  },
668 
669  _on: function( suppressDisabledCheck, element, handlers ) {
670  var delegateElement,
671  instance = this;
672 
673  // no suppressDisabledCheck flag, shuffle arguments
674  if ( typeof suppressDisabledCheck !== "boolean" ) {
675  handlers = element;
676  element = suppressDisabledCheck;
677  suppressDisabledCheck = false;
678  }
679 
680  // no element argument, shuffle and use this.element
681  if ( !handlers ) {
682  handlers = element;
683  element = this.element;
684  delegateElement = this.widget();
685  } else {
686  // accept selectors, DOM elements
687  element = delegateElement = $( element );
688  this.bindings = this.bindings.add( element );
689  }
690 
691  $.each( handlers, function( event, handler ) {
692  function handlerProxy() {
693  // allow widgets to customize the disabled handling
694  // - disabled as an array instead of boolean
695  // - disabled class as method for disabling individual parts
696  if ( !suppressDisabledCheck &&
697  ( instance.options.disabled === true ||
698  $( this ).hasClass( "ui-state-disabled" ) ) ) {
699  return;
700  }
701  return ( typeof handler === "string" ? instance[ handler ] : handler )
702  .apply( instance, arguments );
703  }
704 
705  // copy the guid so direct unbinding works
706  if ( typeof handler !== "string" ) {
707  handlerProxy.guid = handler.guid =
708  handler.guid || handlerProxy.guid || $.guid++;
709  }
710 
711  var match = event.match( /^(\w+)\s*(.*)$/ ),
712  eventName = match[1] + instance.eventNamespace,
713  selector = match[2];
714  if ( selector ) {
715  delegateElement.delegate( selector, eventName, handlerProxy );
716  } else {
717  element.bind( eventName, handlerProxy );
718  }
719  });
720  },
721 
722  _off: function( element, eventName ) {
723  eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724  element.unbind( eventName ).undelegate( eventName );
725  },
726 
727  _delay: function( handler, delay ) {
728  function handlerProxy() {
729  return ( typeof handler === "string" ? instance[ handler ] : handler )
730  .apply( instance, arguments );
731  }
732  var instance = this;
733  return setTimeout( handlerProxy, delay || 0 );
734  },
735 
736  _hoverable: function( element ) {
737  this.hoverable = this.hoverable.add( element );
738  this._on( element, {
739  mouseenter: function( event ) {
740  $( event.currentTarget ).addClass( "ui-state-hover" );
741  },
742  mouseleave: function( event ) {
743  $( event.currentTarget ).removeClass( "ui-state-hover" );
744  }
745  });
746  },
747 
748  _focusable: function( element ) {
749  this.focusable = this.focusable.add( element );
750  this._on( element, {
751  focusin: function( event ) {
752  $( event.currentTarget ).addClass( "ui-state-focus" );
753  },
754  focusout: function( event ) {
755  $( event.currentTarget ).removeClass( "ui-state-focus" );
756  }
757  });
758  },
759 
760  _trigger: function( type, event, data ) {
761  var prop, orig,
762  callback = this.options[ type ];
763 
764  data = data || {};
765  event = $.Event( event );
766  event.type = ( type === this.widgetEventPrefix ?
767  type :
768  this.widgetEventPrefix + type ).toLowerCase();
769  // the original event may come from any element
770  // so we need to reset the target on the new event
771  event.target = this.element[ 0 ];
772 
773  // copy original event properties over to the new event
774  orig = event.originalEvent;
775  if ( orig ) {
776  for ( prop in orig ) {
777  if ( !( prop in event ) ) {
778  event[ prop ] = orig[ prop ];
779  }
780  }
781  }
782 
783  this.element.trigger( event, data );
784  return !( $.isFunction( callback ) &&
785  callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786  event.isDefaultPrevented() );
787  }
788 };
789 
790 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791  $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792  if ( typeof options === "string" ) {
793  options = { effect: options };
794  }
795  var hasOptions,
796  effectName = !options ?
797  method :
798  options === true || typeof options === "number" ?
799  defaultEffect :
800  options.effect || defaultEffect;
801  options = options || {};
802  if ( typeof options === "number" ) {
803  options = { duration: options };
804  }
805  hasOptions = !$.isEmptyObject( options );
806  options.complete = callback;
807  if ( options.delay ) {
808  element.delay( options.delay );
809  }
810  if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811  element[ method ]( options );
812  } else if ( effectName !== method && element[ effectName ] ) {
813  element[ effectName ]( options.duration, options.easing, callback );
814  } else {
815  element.queue(function( next ) {
816  $( this )[ method ]();
817  if ( callback ) {
818  callback.call( element[ 0 ] );
819  }
820  next();
821  });
822  }
823  };
824 });
825 
826 })( jQuery );
827 (function( $, undefined ) {
828 
829 var mouseHandled = false;
830 $( document ).mouseup( function() {
831  mouseHandled = false;
832 });
833 
834 $.widget("ui.mouse", {
835  version: "1.10.3",
836  options: {
837  cancel: "input,textarea,button,select,option",
838  distance: 1,
839  delay: 0
840  },
841  _mouseInit: function() {
842  var that = this;
843 
844  this.element
845  .bind("mousedown."+this.widgetName, function(event) {
846  return that._mouseDown(event);
847  })
848  .bind("click."+this.widgetName, function(event) {
849  if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
850  $.removeData(event.target, that.widgetName + ".preventClickEvent");
851  event.stopImmediatePropagation();
852  return false;
853  }
854  });
855 
856  this.started = false;
857  },
858 
859  // TODO: make sure destroying one instance of mouse doesn't mess with
860  // other instances of mouse
861  _mouseDestroy: function() {
862  this.element.unbind("."+this.widgetName);
863  if ( this._mouseMoveDelegate ) {
864  $(document)
865  .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
866  .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
867  }
868  },
869 
870  _mouseDown: function(event) {
871  // don't let more than one widget handle mouseStart
872  if( mouseHandled ) { return; }
873 
874  // we may have missed mouseup (out of window)
875  (this._mouseStarted && this._mouseUp(event));
876 
877  this._mouseDownEvent = event;
878 
879  var that = this,
880  btnIsLeft = (event.which === 1),
881  // event.target.nodeName works around a bug in IE 8 with
882  // disabled inputs (#7620)
883  elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
884  if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
885  return true;
886  }
887 
888  this.mouseDelayMet = !this.options.delay;
889  if (!this.mouseDelayMet) {
890  this._mouseDelayTimer = setTimeout(function() {
891  that.mouseDelayMet = true;
892  }, this.options.delay);
893  }
894 
895  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
896  this._mouseStarted = (this._mouseStart(event) !== false);
897  if (!this._mouseStarted) {
898  event.preventDefault();
899  return true;
900  }
901  }
902 
903  // Click event may never have fired (Gecko & Opera)
904  if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
905  $.removeData(event.target, this.widgetName + ".preventClickEvent");
906  }
907 
908  // these delegates are required to keep context
909  this._mouseMoveDelegate = function(event) {
910  return that._mouseMove(event);
911  };
912  this._mouseUpDelegate = function(event) {
913  return that._mouseUp(event);
914  };
915  $(document)
916  .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
917  .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
918 
919  event.preventDefault();
920 
921  mouseHandled = true;
922  return true;
923  },
924 
925  _mouseMove: function(event) {
926  // IE mouseup check - mouseup happened when mouse was out of window
927  if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
928  return this._mouseUp(event);
929  }
930 
931  if (this._mouseStarted) {
932  this._mouseDrag(event);
933  return event.preventDefault();
934  }
935 
936  if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
937  this._mouseStarted =
938  (this._mouseStart(this._mouseDownEvent, event) !== false);
939  (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
940  }
941 
942  return !this._mouseStarted;
943  },
944 
945  _mouseUp: function(event) {
946  $(document)
947  .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
948  .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
949 
950  if (this._mouseStarted) {
951  this._mouseStarted = false;
952 
953  if (event.target === this._mouseDownEvent.target) {
954  $.data(event.target, this.widgetName + ".preventClickEvent", true);
955  }
956 
957  this._mouseStop(event);
958  }
959 
960  return false;
961  },
962 
963  _mouseDistanceMet: function(event) {
964  return (Math.max(
965  Math.abs(this._mouseDownEvent.pageX - event.pageX),
966  Math.abs(this._mouseDownEvent.pageY - event.pageY)
967  ) >= this.options.distance
968  );
969  },
970 
971  _mouseDelayMet: function(/* event */) {
972  return this.mouseDelayMet;
973  },
974 
975  // These are placeholder methods, to be overriden by extending plugin
976  _mouseStart: function(/* event */) {},
977  _mouseDrag: function(/* event */) {},
978  _mouseStop: function(/* event */) {},
979  _mouseCapture: function(/* event */) { return true; }
980 });
981 
982 })(jQuery);
983 (function( $, undefined ) {
984 
985 $.ui = $.ui || {};
986 
987 var cachedScrollbarWidth,
988  max = Math.max,
989  abs = Math.abs,
990  round = Math.round,
991  rhorizontal = /left|center|right/,
992  rvertical = /top|center|bottom/,
993  roffset = /[\+\-]\d+(\.[\d]+)?%?/,
994  rposition = /^\w+/,
995  rpercent = /%$/,
996  _position = $.fn.position;
997 
998 function getOffsets( offsets, width, height ) {
999  return [
1000  parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
1001  parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
1002  ];
1003 }
1004 
1005 function parseCss( element, property ) {
1006  return parseInt( $.css( element, property ), 10 ) || 0;
1007 }
1008 
1009 function getDimensions( elem ) {
1010  var raw = elem[0];
1011  if ( raw.nodeType === 9 ) {
1012  return {
1013  width: elem.width(),
1014  height: elem.height(),
1015  offset: { top: 0, left: 0 }
1016  };
1017  }
1018  if ( $.isWindow( raw ) ) {
1019  return {
1020  width: elem.width(),
1021  height: elem.height(),
1022  offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
1023  };
1024  }
1025  if ( raw.preventDefault ) {
1026  return {
1027  width: 0,
1028  height: 0,
1029  offset: { top: raw.pageY, left: raw.pageX }
1030  };
1031  }
1032  return {
1033  width: elem.outerWidth(),
1034  height: elem.outerHeight(),
1035  offset: elem.offset()
1036  };
1037 }
1038 
1039 $.position = {
1040  scrollbarWidth: function() {
1041  if ( cachedScrollbarWidth !== undefined ) {
1042  return cachedScrollbarWidth;
1043  }
1044  var w1, w2,
1045  div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
1046  innerDiv = div.children()[0];
1047 
1048  $( "body" ).append( div );
1049  w1 = innerDiv.offsetWidth;
1050  div.css( "overflow", "scroll" );
1051 
1052  w2 = innerDiv.offsetWidth;
1053 
1054  if ( w1 === w2 ) {
1055  w2 = div[0].clientWidth;
1056  }
1057 
1058  div.remove();
1059 
1060  return (cachedScrollbarWidth = w1 - w2);
1061  },
1062  getScrollInfo: function( within ) {
1063  var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ),
1064  overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ),
1065  hasOverflowX = overflowX === "scroll" ||
1066  ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
1067  hasOverflowY = overflowY === "scroll" ||
1068  ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
1069  return {
1070  width: hasOverflowY ? $.position.scrollbarWidth() : 0,
1071  height: hasOverflowX ? $.position.scrollbarWidth() : 0
1072  };
1073  },
1074  getWithinInfo: function( element ) {
1075  var withinElement = $( element || window ),
1076  isWindow = $.isWindow( withinElement[0] );
1077  return {
1078  element: withinElement,
1079  isWindow: isWindow,
1080  offset: withinElement.offset() || { left: 0, top: 0 },
1081  scrollLeft: withinElement.scrollLeft(),
1082  scrollTop: withinElement.scrollTop(),
1083  width: isWindow ? withinElement.width() : withinElement.outerWidth(),
1084  height: isWindow ? withinElement.height() : withinElement.outerHeight()
1085  };
1086  }
1087 };
1088 
1089 $.fn.position = function( options ) {
1090  if ( !options || !options.of ) {
1091  return _position.apply( this, arguments );
1092  }
1093 
1094  // make a copy, we don't want to modify arguments
1095  options = $.extend( {}, options );
1096 
1097  var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
1098  target = $( options.of ),
1099  within = $.position.getWithinInfo( options.within ),
1100  scrollInfo = $.position.getScrollInfo( within ),
1101  collision = ( options.collision || "flip" ).split( " " ),
1102  offsets = {};
1103 
1104  dimensions = getDimensions( target );
1105  if ( target[0].preventDefault ) {
1106  // force left top to allow flipping
1107  options.at = "left top";
1108  }
1109  targetWidth = dimensions.width;
1110  targetHeight = dimensions.height;
1111  targetOffset = dimensions.offset;
1112  // clone to reuse original targetOffset later
1113  basePosition = $.extend( {}, targetOffset );
1114 
1115  // force my and at to have valid horizontal and vertical positions
1116  // if a value is missing or invalid, it will be converted to center
1117  $.each( [ "my", "at" ], function() {
1118  var pos = ( options[ this ] || "" ).split( " " ),
1119  horizontalOffset,
1120  verticalOffset;
1121 
1122  if ( pos.length === 1) {
1123  pos = rhorizontal.test( pos[ 0 ] ) ?
1124  pos.concat( [ "center" ] ) :
1125  rvertical.test( pos[ 0 ] ) ?
1126  [ "center" ].concat( pos ) :
1127  [ "center", "center" ];
1128  }
1129  pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
1130  pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
1131 
1132  // calculate offsets
1133  horizontalOffset = roffset.exec( pos[ 0 ] );
1134  verticalOffset = roffset.exec( pos[ 1 ] );
1135  offsets[ this ] = [
1136  horizontalOffset ? horizontalOffset[ 0 ] : 0,
1137  verticalOffset ? verticalOffset[ 0 ] : 0
1138  ];
1139 
1140  // reduce to just the positions without the offsets
1141  options[ this ] = [
1142  rposition.exec( pos[ 0 ] )[ 0 ],
1143  rposition.exec( pos[ 1 ] )[ 0 ]
1144  ];
1145  });
1146 
1147  // normalize collision option
1148  if ( collision.length === 1 ) {
1149  collision[ 1 ] = collision[ 0 ];
1150  }
1151 
1152  if ( options.at[ 0 ] === "right" ) {
1153  basePosition.left += targetWidth;
1154  } else if ( options.at[ 0 ] === "center" ) {
1155  basePosition.left += targetWidth / 2;
1156  }
1157 
1158  if ( options.at[ 1 ] === "bottom" ) {
1159  basePosition.top += targetHeight;
1160  } else if ( options.at[ 1 ] === "center" ) {
1161  basePosition.top += targetHeight / 2;
1162  }
1163 
1164  atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
1165  basePosition.left += atOffset[ 0 ];
1166  basePosition.top += atOffset[ 1 ];
1167 
1168  return this.each(function() {
1169  var collisionPosition, using,
1170  elem = $( this ),
1171  elemWidth = elem.outerWidth(),
1172  elemHeight = elem.outerHeight(),
1173  marginLeft = parseCss( this, "marginLeft" ),
1174  marginTop = parseCss( this, "marginTop" ),
1175  collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
1176  collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
1177  position = $.extend( {}, basePosition ),
1178  myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1179 
1180  if ( options.my[ 0 ] === "right" ) {
1181  position.left -= elemWidth;
1182  } else if ( options.my[ 0 ] === "center" ) {
1183  position.left -= elemWidth / 2;
1184  }
1185 
1186  if ( options.my[ 1 ] === "bottom" ) {
1187  position.top -= elemHeight;
1188  } else if ( options.my[ 1 ] === "center" ) {
1189  position.top -= elemHeight / 2;
1190  }
1191 
1192  position.left += myOffset[ 0 ];
1193  position.top += myOffset[ 1 ];
1194 
1195  // if the browser doesn't support fractions, then round for consistent results
1196  if ( !$.support.offsetFractions ) {
1197  position.left = round( position.left );
1198  position.top = round( position.top );
1199  }
1200 
1201  collisionPosition = {
1202  marginLeft: marginLeft,
1203  marginTop: marginTop
1204  };
1205 
1206  $.each( [ "left", "top" ], function( i, dir ) {
1207  if ( $.ui.position[ collision[ i ] ] ) {
1208  $.ui.position[ collision[ i ] ][ dir ]( position, {
1209  targetWidth: targetWidth,
1210  targetHeight: targetHeight,
1211  elemWidth: elemWidth,
1212  elemHeight: elemHeight,
1213  collisionPosition: collisionPosition,
1214  collisionWidth: collisionWidth,
1215  collisionHeight: collisionHeight,
1216  offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1217  my: options.my,
1218  at: options.at,
1219  within: within,
1220  elem : elem
1221  });
1222  }
1223  });
1224 
1225  if ( options.using ) {
1226  // adds feedback as second argument to using callback, if present
1227  using = function( props ) {
1228  var left = targetOffset.left - position.left,
1229  right = left + targetWidth - elemWidth,
1230  top = targetOffset.top - position.top,
1231  bottom = top + targetHeight - elemHeight,
1232  feedback = {
1233  target: {
1234  element: target,
1235  left: targetOffset.left,
1236  top: targetOffset.top,
1237  width: targetWidth,
1238  height: targetHeight
1239  },
1240  element: {
1241  element: elem,
1242  left: position.left,
1243  top: position.top,
1244  width: elemWidth,
1245  height: elemHeight
1246  },
1247  horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1248  vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1249  };
1250  if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1251  feedback.horizontal = "center";
1252  }
1253  if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1254  feedback.vertical = "middle";
1255  }
1256  if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1257  feedback.important = "horizontal";
1258  } else {
1259  feedback.important = "vertical";
1260  }
1261  options.using.call( this, props, feedback );
1262  };
1263  }
1264 
1265  elem.offset( $.extend( position, { using: using } ) );
1266  });
1267 };
1268 
1269 $.ui.position = {
1270  fit: {
1271  left: function( position, data ) {
1272  var within = data.within,
1273  withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1274  outerWidth = within.width,
1275  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1276  overLeft = withinOffset - collisionPosLeft,
1277  overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1278  newOverRight;
1279 
1280  // element is wider than within
1281  if ( data.collisionWidth > outerWidth ) {
1282  // element is initially over the left side of within
1283  if ( overLeft > 0 && overRight <= 0 ) {
1284  newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
1285  position.left += overLeft - newOverRight;
1286  // element is initially over right side of within
1287  } else if ( overRight > 0 && overLeft <= 0 ) {
1288  position.left = withinOffset;
1289  // element is initially over both left and right sides of within
1290  } else {
1291  if ( overLeft > overRight ) {
1292  position.left = withinOffset + outerWidth - data.collisionWidth;
1293  } else {
1294  position.left = withinOffset;
1295  }
1296  }
1297  // too far left -> align with left edge
1298  } else if ( overLeft > 0 ) {
1299  position.left += overLeft;
1300  // too far right -> align with right edge
1301  } else if ( overRight > 0 ) {
1302  position.left -= overRight;
1303  // adjust based on position and margin
1304  } else {
1305  position.left = max( position.left - collisionPosLeft, position.left );
1306  }
1307  },
1308  top: function( position, data ) {
1309  var within = data.within,
1310  withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1311  outerHeight = data.within.height,
1312  collisionPosTop = position.top - data.collisionPosition.marginTop,
1313  overTop = withinOffset - collisionPosTop,
1314  overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1315  newOverBottom;
1316 
1317  // element is taller than within
1318  if ( data.collisionHeight > outerHeight ) {
1319  // element is initially over the top of within
1320  if ( overTop > 0 && overBottom <= 0 ) {
1321  newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
1322  position.top += overTop - newOverBottom;
1323  // element is initially over bottom of within
1324  } else if ( overBottom > 0 && overTop <= 0 ) {
1325  position.top = withinOffset;
1326  // element is initially over both top and bottom of within
1327  } else {
1328  if ( overTop > overBottom ) {
1329  position.top = withinOffset + outerHeight - data.collisionHeight;
1330  } else {
1331  position.top = withinOffset;
1332  }
1333  }
1334  // too far up -> align with top
1335  } else if ( overTop > 0 ) {
1336  position.top += overTop;
1337  // too far down -> align with bottom edge
1338  } else if ( overBottom > 0 ) {
1339  position.top -= overBottom;
1340  // adjust based on position and margin
1341  } else {
1342  position.top = max( position.top - collisionPosTop, position.top );
1343  }
1344  }
1345  },
1346  flip: {
1347  left: function( position, data ) {
1348  var within = data.within,
1349  withinOffset = within.offset.left + within.scrollLeft,
1350  outerWidth = within.width,
1351  offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1352  collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1353  overLeft = collisionPosLeft - offsetLeft,
1354  overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1355  myOffset = data.my[ 0 ] === "left" ?
1356  -data.elemWidth :
1357  data.my[ 0 ] === "right" ?
1358  data.elemWidth :
1359  0,
1360  atOffset = data.at[ 0 ] === "left" ?
1361  data.targetWidth :
1362  data.at[ 0 ] === "right" ?
1363  -data.targetWidth :
1364  0,
1365  offset = -2 * data.offset[ 0 ],
1366  newOverRight,
1367  newOverLeft;
1368 
1369  if ( overLeft < 0 ) {
1370  newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
1371  if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1372  position.left += myOffset + atOffset + offset;
1373  }
1374  }
1375  else if ( overRight > 0 ) {
1376  newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
1377  if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1378  position.left += myOffset + atOffset + offset;
1379  }
1380  }
1381  },
1382  top: function( position, data ) {
1383  var within = data.within,
1384  withinOffset = within.offset.top + within.scrollTop,
1385  outerHeight = within.height,
1386  offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1387  collisionPosTop = position.top - data.collisionPosition.marginTop,
1388  overTop = collisionPosTop - offsetTop,
1389  overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1390  top = data.my[ 1 ] === "top",
1391  myOffset = top ?
1392  -data.elemHeight :
1393  data.my[ 1 ] === "bottom" ?
1394  data.elemHeight :
1395  0,
1396  atOffset = data.at[ 1 ] === "top" ?
1397  data.targetHeight :
1398  data.at[ 1 ] === "bottom" ?
1399  -data.targetHeight :
1400  0,
1401  offset = -2 * data.offset[ 1 ],
1402  newOverTop,
1403  newOverBottom;
1404  if ( overTop < 0 ) {
1405  newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
1406  if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
1407  position.top += myOffset + atOffset + offset;
1408  }
1409  }
1410  else if ( overBottom > 0 ) {
1411  newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
1412  if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
1413  position.top += myOffset + atOffset + offset;
1414  }
1415  }
1416  }
1417  },
1418  flipfit: {
1419  left: function() {
1420  $.ui.position.flip.left.apply( this, arguments );
1421  $.ui.position.fit.left.apply( this, arguments );
1422  },
1423  top: function() {
1424  $.ui.position.flip.top.apply( this, arguments );
1425  $.ui.position.fit.top.apply( this, arguments );
1426  }
1427  }
1428 };
1429 
1430 // fraction support test
1431 (function () {
1432  var testElement, testElementParent, testElementStyle, offsetLeft, i,
1433  body = document.getElementsByTagName( "body" )[ 0 ],
1434  div = document.createElement( "div" );
1435 
1436  //Create a "fake body" for testing based on method used in jQuery.support
1437  testElement = document.createElement( body ? "div" : "body" );
1438  testElementStyle = {
1439  visibility: "hidden",
1440  width: 0,
1441  height: 0,
1442  border: 0,
1443  margin: 0,
1444  background: "none"
1445  };
1446  if ( body ) {
1447  $.extend( testElementStyle, {
1448  position: "absolute",
1449  left: "-1000px",
1450  top: "-1000px"
1451  });
1452  }
1453  for ( i in testElementStyle ) {
1454  testElement.style[ i ] = testElementStyle[ i ];
1455  }
1456  testElement.appendChild( div );
1457  testElementParent = body || document.documentElement;
1458  testElementParent.insertBefore( testElement, testElementParent.firstChild );
1459 
1460  div.style.cssText = "position: absolute; left: 10.7432222px;";
1461 
1462  offsetLeft = $( div ).offset().left;
1463  $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
1464 
1465  testElement.innerHTML = "";
1466  testElementParent.removeChild( testElement );
1467 })();
1468 
1469 }( jQuery ) );
1470 (function( $, undefined ) {
1471 
1472 $.widget("ui.draggable", $.ui.mouse, {
1473  version: "1.10.3",
1474  widgetEventPrefix: "drag",
1475  options: {
1476  addClasses: true,
1477  appendTo: "parent",
1478  axis: false,
1479  connectToSortable: false,
1480  containment: false,
1481  cursor: "auto",
1482  cursorAt: false,
1483  grid: false,
1484  handle: false,
1485  helper: "original",
1486  iframeFix: false,
1487  opacity: false,
1488  refreshPositions: false,
1489  revert: false,
1490  revertDuration: 500,
1491  scope: "default",
1492  scroll: true,
1493  scrollSensitivity: 20,
1494  scrollSpeed: 20,
1495  snap: false,
1496  snapMode: "both",
1497  snapTolerance: 20,
1498  stack: false,
1499  zIndex: false,
1500 
1501  // callbacks
1502  drag: null,
1503  start: null,
1504  stop: null
1505  },
1506  _create: function() {
1507 
1508  if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1509  this.element[0].style.position = "relative";
1510  }
1511  if (this.options.addClasses){
1512  this.element.addClass("ui-draggable");
1513  }
1514  if (this.options.disabled){
1515  this.element.addClass("ui-draggable-disabled");
1516  }
1517 
1518  this._mouseInit();
1519 
1520  },
1521 
1522  _destroy: function() {
1523  this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1524  this._mouseDestroy();
1525  },
1526 
1527  _mouseCapture: function(event) {
1528 
1529  var o = this.options;
1530 
1531  // among others, prevent a drag on a resizable-handle
1532  if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1533  return false;
1534  }
1535 
1536  //Quit if we're not on a valid handle
1537  this.handle = this._getHandle(event);
1538  if (!this.handle) {
1539  return false;
1540  }
1541 
1542  $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1543  $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1544  .css({
1545  width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1546  position: "absolute", opacity: "0.001", zIndex: 1000
1547  })
1548  .css($(this).offset())
1549  .appendTo("body");
1550  });
1551 
1552  return true;
1553 
1554  },
1555 
1556  _mouseStart: function(event) {
1557 
1558  var o = this.options;
1559 
1560  //Create and append the visible helper
1561  this.helper = this._createHelper(event);
1562 
1563  this.helper.addClass("ui-draggable-dragging");
1564 
1565  //Cache the helper size
1566  this._cacheHelperProportions();
1567 
1568  //If ddmanager is used for droppables, set the global draggable
1569  if($.ui.ddmanager) {
1570  $.ui.ddmanager.current = this;
1571  }
1572 
1573  /*
1574  * - Position generation -
1575  * This block generates everything position related - it's the core of draggables.
1576  */
1577 
1578  //Cache the margins of the original element
1579  this._cacheMargins();
1580 
1581  //Store the helper's css position
1582  this.cssPosition = this.helper.css( "position" );
1583  this.scrollParent = this.helper.scrollParent();
1584  this.offsetParent = this.helper.offsetParent();
1585  this.offsetParentCssPosition = this.offsetParent.css( "position" );
1586 
1587  //The element's absolute position on the page minus margins
1588  this.offset = this.positionAbs = this.element.offset();
1589  this.offset = {
1590  top: this.offset.top - this.margins.top,
1591  left: this.offset.left - this.margins.left
1592  };
1593 
1594  //Reset scroll cache
1595  this.offset.scroll = false;
1596 
1597  $.extend(this.offset, {
1598  click: { //Where the click happened, relative to the element
1599  left: event.pageX - this.offset.left,
1600  top: event.pageY - this.offset.top
1601  },
1602  parent: this._getParentOffset(),
1603  relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1604  });
1605 
1606  //Generate the original position
1607  this.originalPosition = this.position = this._generatePosition(event);
1608  this.originalPageX = event.pageX;
1609  this.originalPageY = event.pageY;
1610 
1611  //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1612  (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1613 
1614  //Set a containment if given in the options
1615  this._setContainment();
1616 
1617  //Trigger event + callbacks
1618  if(this._trigger("start", event) === false) {
1619  this._clear();
1620  return false;
1621  }
1622 
1623  //Recache the helper size
1624  this._cacheHelperProportions();
1625 
1626  //Prepare the droppable offsets
1627  if ($.ui.ddmanager && !o.dropBehaviour) {
1628  $.ui.ddmanager.prepareOffsets(this, event);
1629  }
1630 
1631 
1632  this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1633 
1634  //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1635  if ( $.ui.ddmanager ) {
1636  $.ui.ddmanager.dragStart(this, event);
1637  }
1638 
1639  return true;
1640  },
1641 
1642  _mouseDrag: function(event, noPropagation) {
1643  // reset any necessary cached properties (see #5009)
1644  if ( this.offsetParentCssPosition === "fixed" ) {
1645  this.offset.parent = this._getParentOffset();
1646  }
1647 
1648  //Compute the helpers position
1649  this.position = this._generatePosition(event);
1650  this.positionAbs = this._convertPositionTo("absolute");
1651 
1652  //Call plugins and callbacks and use the resulting position if something is returned
1653  if (!noPropagation) {
1654  var ui = this._uiHash();
1655  if(this._trigger("drag", event, ui) === false) {
1656  this._mouseUp({});
1657  return false;
1658  }
1659  this.position = ui.position;
1660  }
1661 
1662  if(!this.options.axis || this.options.axis !== "y") {
1663  this.helper[0].style.left = this.position.left+"px";
1664  }
1665  if(!this.options.axis || this.options.axis !== "x") {
1666  this.helper[0].style.top = this.position.top+"px";
1667  }
1668  if($.ui.ddmanager) {
1669  $.ui.ddmanager.drag(this, event);
1670  }
1671 
1672  return false;
1673  },
1674 
1675  _mouseStop: function(event) {
1676 
1677  //If we are using droppables, inform the manager about the drop
1678  var that = this,
1679  dropped = false;
1680  if ($.ui.ddmanager && !this.options.dropBehaviour) {
1681  dropped = $.ui.ddmanager.drop(this, event);
1682  }
1683 
1684  //if a drop comes from outside (a sortable)
1685  if(this.dropped) {
1686  dropped = this.dropped;
1687  this.dropped = false;
1688  }
1689 
1690  //if the original element is no longer in the DOM don't bother to continue (see #8269)
1691  if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1692  return false;
1693  }
1694 
1695  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))) {
1696  $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1697  if(that._trigger("stop", event) !== false) {
1698  that._clear();
1699  }
1700  });
1701  } else {
1702  if(this._trigger("stop", event) !== false) {
1703  this._clear();
1704  }
1705  }
1706 
1707  return false;
1708  },
1709 
1710  _mouseUp: function(event) {
1711  //Remove frame helpers
1712  $("div.ui-draggable-iframeFix").each(function() {
1713  this.parentNode.removeChild(this);
1714  });
1715 
1716  //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1717  if( $.ui.ddmanager ) {
1718  $.ui.ddmanager.dragStop(this, event);
1719  }
1720 
1721  return $.ui.mouse.prototype._mouseUp.call(this, event);
1722  },
1723 
1724  cancel: function() {
1725 
1726  if(this.helper.is(".ui-draggable-dragging")) {
1727  this._mouseUp({});
1728  } else {
1729  this._clear();
1730  }
1731 
1732  return this;
1733 
1734  },
1735 
1736  _getHandle: function(event) {
1737  return this.options.handle ?
1738  !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1739  true;
1740  },
1741 
1742  _createHelper: function(event) {
1743 
1744  var o = this.options,
1745  helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1746 
1747  if(!helper.parents("body").length) {
1748  helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1749  }
1750 
1751  if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1752  helper.css("position", "absolute");
1753  }
1754 
1755  return helper;
1756 
1757  },
1758 
1759  _adjustOffsetFromHelper: function(obj) {
1760  if (typeof obj === "string") {
1761  obj = obj.split(" ");
1762  }
1763  if ($.isArray(obj)) {
1764  obj = {left: +obj[0], top: +obj[1] || 0};
1765  }
1766  if ("left" in obj) {
1767  this.offset.click.left = obj.left + this.margins.left;
1768  }
1769  if ("right" in obj) {
1770  this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1771  }
1772  if ("top" in obj) {
1773  this.offset.click.top = obj.top + this.margins.top;
1774  }
1775  if ("bottom" in obj) {
1776  this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1777  }
1778  },
1779 
1780  _getParentOffset: function() {
1781 
1782  //Get the offsetParent and cache its position
1783  var po = this.offsetParent.offset();
1784 
1785  // This is a special case where we need to modify a offset calculated on start, since the following happened:
1786  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1787  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1788  // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1789  if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1790  po.left += this.scrollParent.scrollLeft();
1791  po.top += this.scrollParent.scrollTop();
1792  }
1793 
1794  //This needs to be actually done for all browsers, since pageX/pageY includes this information
1795  //Ugly IE fix
1796  if((this.offsetParent[0] === document.body) ||
1797  (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1798  po = { top: 0, left: 0 };
1799  }
1800 
1801  return {
1802  top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1803  left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1804  };
1805 
1806  },
1807 
1808  _getRelativeOffset: function() {
1809 
1810  if(this.cssPosition === "relative") {
1811  var p = this.element.position();
1812  return {
1813  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1814  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1815  };
1816  } else {
1817  return { top: 0, left: 0 };
1818  }
1819 
1820  },
1821 
1822  _cacheMargins: function() {
1823  this.margins = {
1824  left: (parseInt(this.element.css("marginLeft"),10) || 0),
1825  top: (parseInt(this.element.css("marginTop"),10) || 0),
1826  right: (parseInt(this.element.css("marginRight"),10) || 0),
1827  bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1828  };
1829  },
1830 
1831  _cacheHelperProportions: function() {
1832  this.helperProportions = {
1833  width: this.helper.outerWidth(),
1834  height: this.helper.outerHeight()
1835  };
1836  },
1837 
1838  _setContainment: function() {
1839 
1840  var over, c, ce,
1841  o = this.options;
1842 
1843  if ( !o.containment ) {
1844  this.containment = null;
1845  return;
1846  }
1847 
1848  if ( o.containment === "window" ) {
1849  this.containment = [
1850  $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1851  $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1852  $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1853  $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1854  ];
1855  return;
1856  }
1857 
1858  if ( o.containment === "document") {
1859  this.containment = [
1860  0,
1861  0,
1862  $( document ).width() - this.helperProportions.width - this.margins.left,
1863  ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1864  ];
1865  return;
1866  }
1867 
1868  if ( o.containment.constructor === Array ) {
1869  this.containment = o.containment;
1870  return;
1871  }
1872 
1873  if ( o.containment === "parent" ) {
1874  o.containment = this.helper[ 0 ].parentNode;
1875  }
1876 
1877  c = $( o.containment );
1878  ce = c[ 0 ];
1879 
1880  if( !ce ) {
1881  return;
1882  }
1883 
1884  over = c.css( "overflow" ) !== "hidden";
1885 
1886  this.containment = [
1887  ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1888  ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1889  ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1890  ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom
1891  ];
1892  this.relative_container = c;
1893  },
1894 
1895  _convertPositionTo: function(d, pos) {
1896 
1897  if(!pos) {
1898  pos = this.position;
1899  }
1900 
1901  var mod = d === "absolute" ? 1 : -1,
1902  scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1903 
1904  //Cache the scroll
1905  if (!this.offset.scroll) {
1906  this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1907  }
1908 
1909  return {
1910  top: (
1911  pos.top + // The absolute mouse position
1912  this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1913  this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1914  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1915  ),
1916  left: (
1917  pos.left + // The absolute mouse position
1918  this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1919  this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
1920  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1921  )
1922  };
1923 
1924  },
1925 
1926  _generatePosition: function(event) {
1927 
1928  var containment, co, top, left,
1929  o = this.options,
1930  scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1931  pageX = event.pageX,
1932  pageY = event.pageY;
1933 
1934  //Cache the scroll
1935  if (!this.offset.scroll) {
1936  this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1937  }
1938 
1939  /*
1940  * - Position constraining -
1941  * Constrain the position to a mix of grid, containment.
1942  */
1943 
1944  // If we are not dragging yet, we won't check for options
1945  if ( this.originalPosition ) {
1946  if ( this.containment ) {
1947  if ( this.relative_container ){
1948  co = this.relative_container.offset();
1949  containment = [
1950  this.containment[ 0 ] + co.left,
1951  this.containment[ 1 ] + co.top,
1952  this.containment[ 2 ] + co.left,
1953  this.containment[ 3 ] + co.top
1954  ];
1955  }
1956  else {
1957  containment = this.containment;
1958  }
1959 
1960  if(event.pageX - this.offset.click.left < containment[0]) {
1961  pageX = containment[0] + this.offset.click.left;
1962  }
1963  if(event.pageY - this.offset.click.top < containment[1]) {
1964  pageY = containment[1] + this.offset.click.top;
1965  }
1966  if(event.pageX - this.offset.click.left > containment[2]) {
1967  pageX = containment[2] + this.offset.click.left;
1968  }
1969  if(event.pageY - this.offset.click.top > containment[3]) {
1970  pageY = containment[3] + this.offset.click.top;
1971  }
1972  }
1973 
1974  if(o.grid) {
1975  //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1976  top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1977  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;
1978 
1979  left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1980  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;
1981  }
1982 
1983  }
1984 
1985  return {
1986  top: (
1987  pageY - // The absolute mouse position
1988  this.offset.click.top - // Click offset (relative to the element)
1989  this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
1990  this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
1991  ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1992  ),
1993  left: (
1994  pageX - // The absolute mouse position
1995  this.offset.click.left - // Click offset (relative to the element)
1996  this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
1997  this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
1998  ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1999  )
2000  };
2001 
2002  },
2003 
2004  _clear: function() {
2005  this.helper.removeClass("ui-draggable-dragging");
2006  if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
2007  this.helper.remove();
2008  }
2009  this.helper = null;
2010  this.cancelHelperRemoval = false;
2011  },
2012 
2013  // From now on bulk stuff - mainly helpers
2014 
2015  _trigger: function(type, event, ui) {
2016  ui = ui || this._uiHash();
2017  $.ui.plugin.call(this, type, [event, ui]);
2018  //The absolute position has to be recalculated after plugins
2019  if(type === "drag") {
2020  this.positionAbs = this._convertPositionTo("absolute");
2021  }
2022  return $.Widget.prototype._trigger.call(this, type, event, ui);
2023  },
2024 
2025  plugins: {},
2026 
2027  _uiHash: function() {
2028  return {
2029  helper: this.helper,
2030  position: this.position,
2031  originalPosition: this.originalPosition,
2032  offset: this.positionAbs
2033  };
2034  }
2035 
2036 });
2037 
2038 $.ui.plugin.add("draggable", "connectToSortable", {
2039  start: function(event, ui) {
2040 
2041  var inst = $(this).data("ui-draggable"), o = inst.options,
2042  uiSortable = $.extend({}, ui, { item: inst.element });
2043  inst.sortables = [];
2044  $(o.connectToSortable).each(function() {
2045  var sortable = $.data(this, "ui-sortable");
2046  if (sortable && !sortable.options.disabled) {
2047  inst.sortables.push({
2048  instance: sortable,
2049  shouldRevert: sortable.options.revert
2050  });
2051  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).
2052  sortable._trigger("activate", event, uiSortable);
2053  }
2054  });
2055 
2056  },
2057  stop: function(event, ui) {
2058 
2059  //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
2060  var inst = $(this).data("ui-draggable"),
2061  uiSortable = $.extend({}, ui, { item: inst.element });
2062 
2063  $.each(inst.sortables, function() {
2064  if(this.instance.isOver) {
2065 
2066  this.instance.isOver = 0;
2067 
2068  inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
2069  this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
2070 
2071  //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
2072  if(this.shouldRevert) {
2073  this.instance.options.revert = this.shouldRevert;
2074  }
2075 
2076  //Trigger the stop of the sortable
2077  this.instance._mouseStop(event);
2078 
2079  this.instance.options.helper = this.instance.options._helper;
2080 
2081  //If the helper has been the original item, restore properties in the sortable
2082  if(inst.options.helper === "original") {
2083  this.instance.currentItem.css({ top: "auto", left: "auto" });
2084  }
2085 
2086  } else {
2087  this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
2088  this.instance._trigger("deactivate", event, uiSortable);
2089  }
2090 
2091  });
2092 
2093  },
2094  drag: function(event, ui) {
2095 
2096  var inst = $(this).data("ui-draggable"), that = this;
2097 
2098  $.each(inst.sortables, function() {
2099 
2100  var innermostIntersecting = false,
2101  thisSortable = this;
2102 
2103  //Copy over some variables to allow calling the sortable's native _intersectsWith
2104  this.instance.positionAbs = inst.positionAbs;
2105  this.instance.helperProportions = inst.helperProportions;
2106  this.instance.offset.click = inst.offset.click;
2107 
2108  if(this.instance._intersectsWith(this.instance.containerCache)) {
2109  innermostIntersecting = true;
2110  $.each(inst.sortables, function () {
2111  this.instance.positionAbs = inst.positionAbs;
2112  this.instance.helperProportions = inst.helperProportions;
2113  this.instance.offset.click = inst.offset.click;
2114  if (this !== thisSortable &&
2115  this.instance._intersectsWith(this.instance.containerCache) &&
2116  $.contains(thisSortable.instance.element[0], this.instance.element[0])
2117  ) {
2118  innermostIntersecting = false;
2119  }
2120  return innermostIntersecting;
2121  });
2122  }
2123 
2124 
2125  if(innermostIntersecting) {
2126  //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
2127  if(!this.instance.isOver) {
2128 
2129  this.instance.isOver = 1;
2130  //Now we fake the start of dragging for the sortable instance,
2131  //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
2132  //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)
2133  this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
2134  this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
2135  this.instance.options.helper = function() { return ui.helper[0]; };
2136 
2137  event.target = this.instance.currentItem[0];
2138  this.instance._mouseCapture(event, true);
2139  this.instance._mouseStart(event, true, true);
2140 
2141  //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
2142  this.instance.offset.click.top = inst.offset.click.top;
2143  this.instance.offset.click.left = inst.offset.click.left;
2144  this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
2145  this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
2146 
2147  inst._trigger("toSortable", event);
2148  inst.dropped = this.instance.element; //draggable revert needs that
2149  //hack so receive/update callbacks work (mostly)
2150  inst.currentItem = inst.element;
2151  this.instance.fromOutside = inst;
2152 
2153  }
2154 
2155  //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
2156  if(this.instance.currentItem) {
2157  this.instance._mouseDrag(event);
2158  }
2159 
2160  } else {
2161 
2162  //If it doesn't intersect with the sortable, and it intersected before,
2163  //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
2164  if(this.instance.isOver) {
2165 
2166  this.instance.isOver = 0;
2167  this.instance.cancelHelperRemoval = true;
2168 
2169  //Prevent reverting on this forced stop
2170  this.instance.options.revert = false;
2171 
2172  // The out event needs to be triggered independently
2173  this.instance._trigger("out", event, this.instance._uiHash(this.instance));
2174 
2175  this.instance._mouseStop(event, true);
2176  this.instance.options.helper = this.instance.options._helper;
2177 
2178  //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
2179  this.instance.currentItem.remove();
2180  if(this.instance.placeholder) {
2181  this.instance.placeholder.remove();
2182  }
2183 
2184  inst._trigger("fromSortable", event);
2185  inst.dropped = false; //draggable revert needs that
2186  }
2187 
2188  }
2189 
2190  });
2191 
2192  }
2193 });
2194 
2195 $.ui.plugin.add("draggable", "cursor", {
2196  start: function() {
2197  var t = $("body"), o = $(this).data("ui-draggable").options;
2198  if (t.css("cursor")) {
2199  o._cursor = t.css("cursor");
2200  }
2201  t.css("cursor", o.cursor);
2202  },
2203  stop: function() {
2204  var o = $(this).data("ui-draggable").options;
2205  if (o._cursor) {
2206  $("body").css("cursor", o._cursor);
2207  }
2208  }
2209 });
2210 
2211 $.ui.plugin.add("draggable", "opacity", {
2212  start: function(event, ui) {
2213  var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2214  if(t.css("opacity")) {
2215  o._opacity = t.css("opacity");
2216  }
2217  t.css("opacity", o.opacity);
2218  },
2219  stop: function(event, ui) {
2220  var o = $(this).data("ui-draggable").options;
2221  if(o._opacity) {
2222  $(ui.helper).css("opacity", o._opacity);
2223  }
2224  }
2225 });
2226 
2227 $.ui.plugin.add("draggable", "scroll", {
2228  start: function() {
2229  var i = $(this).data("ui-draggable");
2230  if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2231  i.overflowOffset = i.scrollParent.offset();
2232  }
2233  },
2234  drag: function( event ) {
2235 
2236  var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
2237 
2238  if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
2239 
2240  if(!o.axis || o.axis !== "x") {
2241  if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
2242  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
2243  } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
2244  i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
2245  }
2246  }
2247 
2248  if(!o.axis || o.axis !== "y") {
2249  if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
2250  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
2251  } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
2252  i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
2253  }
2254  }
2255 
2256  } else {
2257 
2258  if(!o.axis || o.axis !== "x") {
2259  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
2260  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
2261  } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
2262  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
2263  }
2264  }
2265 
2266  if(!o.axis || o.axis !== "y") {
2267  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
2268  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
2269  } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
2270  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
2271  }
2272  }
2273 
2274  }
2275 
2276  if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
2277  $.ui.ddmanager.prepareOffsets(i, event);
2278  }
2279 
2280  }
2281 });
2282 
2283 $.ui.plugin.add("draggable", "snap", {
2284  start: function() {
2285 
2286  var i = $(this).data("ui-draggable"),
2287  o = i.options;
2288 
2289  i.snapElements = [];
2290 
2291  $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
2292  var $t = $(this),
2293  $o = $t.offset();
2294  if(this !== i.element[0]) {
2295  i.snapElements.push({
2296  item: this,
2297  width: $t.outerWidth(), height: $t.outerHeight(),
2298  top: $o.top, left: $o.left
2299  });
2300  }
2301  });
2302 
2303  },
2304  drag: function(event, ui) {
2305 
2306  var ts, bs, ls, rs, l, r, t, b, i, first,
2307  inst = $(this).data("ui-draggable"),
2308  o = inst.options,
2309  d = o.snapTolerance,
2310  x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2311  y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2312 
2313  for (i = inst.snapElements.length - 1; i >= 0; i--){
2314 
2315  l = inst.snapElements[i].left;
2316  r = l + inst.snapElements[i].width;
2317  t = inst.snapElements[i].top;
2318  b = t + inst.snapElements[i].height;
2319 
2320  if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
2321  if(inst.snapElements[i].snapping) {
2322  (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2323  }
2324  inst.snapElements[i].snapping = false;
2325  continue;
2326  }
2327 
2328  if(o.snapMode !== "inner") {
2329  ts = Math.abs(t - y2) <= d;
2330  bs = Math.abs(b - y1) <= d;
2331  ls = Math.abs(l - x2) <= d;
2332  rs = Math.abs(r - x1) <= d;
2333  if(ts) {
2334  ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2335  }
2336  if(bs) {
2337  ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
2338  }
2339  if(ls) {
2340  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
2341  }
2342  if(rs) {
2343  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
2344  }
2345  }
2346 
2347  first = (ts || bs || ls || rs);
2348 
2349  if(o.snapMode !== "outer") {
2350  ts = Math.abs(t - y1) <= d;
2351  bs = Math.abs(b - y2) <= d;
2352  ls = Math.abs(l - x1) <= d;
2353  rs = Math.abs(r - x2) <= d;
2354  if(ts) {
2355  ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
2356  }
2357  if(bs) {
2358  ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
2359  }
2360  if(ls) {
2361  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
2362  }
2363  if(rs) {
2364  ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
2365  }
2366  }
2367 
2368  if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
2369  (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
2370  }
2371  inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
2372 
2373  }
2374 
2375  }
2376 });
2377 
2378 $.ui.plugin.add("draggable", "stack", {
2379  start: function() {
2380  var min,
2381  o = this.data("ui-draggable").options,
2382  group = $.makeArray($(o.stack)).sort(function(a,b) {
2383  return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
2384  });
2385 
2386  if (!group.length) { return; }
2387 
2388  min = parseInt($(group[0]).css("zIndex"), 10) || 0;
2389  $(group).each(function(i) {
2390  $(this).css("zIndex", min + i);
2391  });
2392  this.css("zIndex", (min + group.length));
2393  }
2394 });
2395 
2396 $.ui.plugin.add("draggable", "zIndex", {
2397  start: function(event, ui) {
2398  var t = $(ui.helper), o = $(this).data("ui-draggable").options;
2399  if(t.css("zIndex")) {
2400  o._zIndex = t.css("zIndex");
2401  }
2402  t.css("zIndex", o.zIndex);
2403  },
2404  stop: function(event, ui) {
2405  var o = $(this).data("ui-draggable").options;
2406  if(o._zIndex) {
2407  $(ui.helper).css("zIndex", o._zIndex);
2408  }
2409  }
2410 });
2411 
2412 })(jQuery);
2413 (function( $, undefined ) {
2414 
2415 function isOverAxis( x, reference, size ) {
2416  return ( x > reference ) && ( x < ( reference + size ) );
2417 }
2418 
2419 $.widget("ui.droppable", {
2420  version: "1.10.3",
2421  widgetEventPrefix: "drop",
2422  options: {
2423  accept: "*",
2424  activeClass: false,
2425  addClasses: true,
2426  greedy: false,
2427  hoverClass: false,
2428  scope: "default",
2429  tolerance: "intersect",
2430 
2431  // callbacks
2432  activate: null,
2433  deactivate: null,
2434  drop: null,
2435  out: null,
2436  over: null
2437  },
2438  _create: function() {
2439 
2440  var o = this.options,
2441  accept = o.accept;
2442 
2443  this.isover = false;
2444  this.isout = true;
2445 
2446  this.accept = $.isFunction(accept) ? accept : function(d) {
2447  return d.is(accept);
2448  };
2449 
2450  //Store the droppable's proportions
2451  this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
2452 
2453  // Add the reference and positions to the manager
2454  $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
2455  $.ui.ddmanager.droppables[o.scope].push(this);
2456 
2457  (o.addClasses && this.element.addClass("ui-droppable"));
2458 
2459  },
2460 
2461  _destroy: function() {
2462  var i = 0,
2463  drop = $.ui.ddmanager.droppables[this.options.scope];
2464 
2465  for ( ; i < drop.length; i++ ) {
2466  if ( drop[i] === this ) {
2467  drop.splice(i, 1);
2468  }
2469  }
2470 
2471  this.element.removeClass("ui-droppable ui-droppable-disabled");
2472  },
2473 
2474  _setOption: function(key, value) {
2475 
2476  if(key === "accept") {
2477  this.accept = $.isFunction(value) ? value : function(d) {
2478  return d.is(value);
2479  };
2480  }
2481  $.Widget.prototype._setOption.apply(this, arguments);
2482  },
2483 
2484  _activate: function(event) {
2485  var draggable = $.ui.ddmanager.current;
2486  if(this.options.activeClass) {
2487  this.element.addClass(this.options.activeClass);
2488  }
2489  if(draggable){
2490  this._trigger("activate", event, this.ui(draggable));
2491  }
2492  },
2493 
2494  _deactivate: function(event) {
2495  var draggable = $.ui.ddmanager.current;
2496  if(this.options.activeClass) {
2497  this.element.removeClass(this.options.activeClass);
2498  }
2499  if(draggable){
2500  this._trigger("deactivate", event, this.ui(draggable));
2501  }
2502  },
2503 
2504  _over: function(event) {
2505 
2506  var draggable = $.ui.ddmanager.current;
2507 
2508  // Bail if draggable and droppable are same element
2509  if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2510  return;
2511  }
2512 
2513  if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2514  if(this.options.hoverClass) {
2515  this.element.addClass(this.options.hoverClass);
2516  }
2517  this._trigger("over", event, this.ui(draggable));
2518  }
2519 
2520  },
2521 
2522  _out: function(event) {
2523 
2524  var draggable = $.ui.ddmanager.current;
2525 
2526  // Bail if draggable and droppable are same element
2527  if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2528  return;
2529  }
2530 
2531  if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2532  if(this.options.hoverClass) {
2533  this.element.removeClass(this.options.hoverClass);
2534  }
2535  this._trigger("out", event, this.ui(draggable));
2536  }
2537 
2538  },
2539 
2540  _drop: function(event,custom) {
2541 
2542  var draggable = custom || $.ui.ddmanager.current,
2543  childrenIntersection = false;
2544 
2545  // Bail if draggable and droppable are same element
2546  if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2547  return false;
2548  }
2549 
2550  this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2551  var inst = $.data(this, "ui-droppable");
2552  if(
2553  inst.options.greedy &&
2554  !inst.options.disabled &&
2555  inst.options.scope === draggable.options.scope &&
2556  inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2557  $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2558  ) { childrenIntersection = true; return false; }
2559  });
2560  if(childrenIntersection) {
2561  return false;
2562  }
2563 
2564  if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2565  if(this.options.activeClass) {
2566  this.element.removeClass(this.options.activeClass);
2567  }
2568  if(this.options.hoverClass) {
2569  this.element.removeClass(this.options.hoverClass);
2570  }
2571  this._trigger("drop", event, this.ui(draggable));
2572  return this.element;
2573  }
2574 
2575  return false;
2576 
2577  },
2578 
2579  ui: function(c) {
2580  return {
2581  draggable: (c.currentItem || c.element),
2582  helper: c.helper,
2583  position: c.position,
2584  offset: c.positionAbs
2585  };
2586  }
2587 
2588 });
2589 
2590 $.ui.intersect = function(draggable, droppable, toleranceMode) {
2591 
2592  if (!droppable.offset) {
2593  return false;
2594  }
2595 
2596  var draggableLeft, draggableTop,
2597  x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
2598  y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
2599  l = droppable.offset.left, r = l + droppable.proportions.width,
2600  t = droppable.offset.top, b = t + droppable.proportions.height;
2601 
2602  switch (toleranceMode) {
2603  case "fit":
2604  return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2605  case "intersect":
2606  return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2607  x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2608  t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2609  y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2610  case "pointer":
2611  draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2612  draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2613  return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
2614  case "touch":
2615  return (
2616  (y1 >= t && y1 <= b) || // Top edge touching
2617  (y2 >= t && y2 <= b) || // Bottom edge touching
2618  (y1 < t && y2 > b) // Surrounded vertically
2619  ) && (
2620  (x1 >= l && x1 <= r) || // Left edge touching
2621  (x2 >= l && x2 <= r) || // Right edge touching
2622  (x1 < l && x2 > r) // Surrounded horizontally
2623  );
2624  default:
2625  return false;
2626  }
2627 
2628 };
2629 
2630 /*
2631  This manager tracks offsets of draggables and droppables
2632 */
2633 $.ui.ddmanager = {
2634  current: null,
2635  droppables: { "default": [] },
2636  prepareOffsets: function(t, event) {
2637 
2638  var i, j,
2639  m = $.ui.ddmanager.droppables[t.options.scope] || [],
2640  type = event ? event.type : null, // workaround for #2317
2641  list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2642 
2643  droppablesLoop: for (i = 0; i < m.length; i++) {
2644 
2645  //No disabled and non-accepted
2646  if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2647  continue;
2648  }
2649 
2650  // Filter out elements in the current dragged item
2651  for (j=0; j < list.length; j++) {
2652  if(list[j] === m[i].element[0]) {
2653  m[i].proportions.height = 0;
2654  continue droppablesLoop;
2655  }
2656  }
2657 
2658  m[i].visible = m[i].element.css("display") !== "none";
2659  if(!m[i].visible) {
2660  continue;
2661  }
2662 
2663  //Activate the droppable if used directly from draggables
2664  if(type === "mousedown") {
2665  m[i]._activate.call(m[i], event);
2666  }
2667 
2668  m[i].offset = m[i].element.offset();
2669  m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
2670 
2671  }
2672 
2673  },
2674  drop: function(draggable, event) {
2675 
2676  var dropped = false;
2677  // Create a copy of the droppables in case the list changes during the drop (#9116)
2678  $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2679 
2680  if(!this.options) {
2681  return;
2682  }
2683  if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2684  dropped = this._drop.call(this, event) || dropped;
2685  }
2686 
2687  if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2688  this.isout = true;
2689  this.isover = false;
2690  this._deactivate.call(this, event);
2691  }
2692 
2693  });
2694  return dropped;
2695 
2696  },
2697  dragStart: function( draggable, event ) {
2698  //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2699  draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2700  if( !draggable.options.refreshPositions ) {
2701  $.ui.ddmanager.prepareOffsets( draggable, event );
2702  }
2703  });
2704  },
2705  drag: function(draggable, event) {
2706 
2707  //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2708  if(draggable.options.refreshPositions) {
2709  $.ui.ddmanager.prepareOffsets(draggable, event);
2710  }
2711 
2712  //Run through all droppables and check their positions based on specific tolerance options
2713  $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2714 
2715  if(this.options.disabled || this.greedyChild || !this.visible) {
2716  return;
2717  }
2718 
2719  var parentInstance, scope, parent,
2720  intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2721  c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2722  if(!c) {
2723  return;
2724  }
2725 
2726  if (this.options.greedy) {
2727  // find droppable parents with same scope
2728  scope = this.options.scope;
2729  parent = this.element.parents(":data(ui-droppable)").filter(function () {
2730  return $.data(this, "ui-droppable").options.scope === scope;
2731  });
2732 
2733  if (parent.length) {
2734  parentInstance = $.data(parent[0], "ui-droppable");
2735  parentInstance.greedyChild = (c === "isover");
2736  }
2737  }
2738 
2739  // we just moved into a greedy child
2740  if (parentInstance && c === "isover") {
2741  parentInstance.isover = false;
2742  parentInstance.isout = true;
2743  parentInstance._out.call(parentInstance, event);
2744  }
2745 
2746  this[c] = true;
2747  this[c === "isout" ? "isover" : "isout"] = false;
2748  this[c === "isover" ? "_over" : "_out"].call(this, event);
2749 
2750  // we just moved out of a greedy child
2751  if (parentInstance && c === "isout") {
2752  parentInstance.isout = false;
2753  parentInstance.isover = true;
2754  parentInstance._over.call(parentInstance, event);
2755  }
2756  });
2757 
2758  },
2759  dragStop: function( draggable, event ) {
2760  draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2761  //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2762  if( !draggable.options.refreshPositions ) {
2763  $.ui.ddmanager.prepareOffsets( draggable, event );
2764  }
2765  }
2766 };
2767 
2768 })(jQuery);
2769 (function( $, undefined ) {
2770 
2771 function num(v) {
2772  return parseInt(v, 10) || 0;
2773 }
2774 
2775 function isNumber(value) {
2776  return !isNaN(parseInt(value, 10));
2777 }
2778 
2779 $.widget("ui.resizable", $.ui.mouse, {
2780  version: "1.10.3",
2781  widgetEventPrefix: "resize",
2782  options: {
2783  alsoResize: false,
2784  animate: false,
2785  animateDuration: "slow",
2786  animateEasing: "swing",
2787  aspectRatio: false,
2788  autoHide: false,
2789  containment: false,
2790  ghost: false,
2791  grid: false,
2792  handles: "e,s,se",
2793  helper: false,
2794  maxHeight: null,
2795  maxWidth: null,
2796  minHeight: 10,
2797  minWidth: 10,
2798  // See #7960
2799  zIndex: 90,
2800 
2801  // callbacks
2802  resize: null,
2803  start: null,
2804  stop: null
2805  },
2806  _create: function() {
2807 
2808  var n, i, handle, axis, hname,
2809  that = this,
2810  o = this.options;
2811  this.element.addClass("ui-resizable");
2812 
2813  $.extend(this, {
2814  _aspectRatio: !!(o.aspectRatio),
2815  aspectRatio: o.aspectRatio,
2816  originalElement: this.element,
2817  _proportionallyResizeElements: [],
2818  _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2819  });
2820 
2821  //Wrap the element if it cannot hold child nodes
2822  if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2823 
2824  //Create a wrapper element and set the wrapper to the new current internal element
2825  this.element.wrap(
2826  $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2827  position: this.element.css("position"),
2828  width: this.element.outerWidth(),
2829  height: this.element.outerHeight(),
2830  top: this.element.css("top"),
2831  left: this.element.css("left")
2832  })
2833  );
2834 
2835  //Overwrite the original this.element
2836  this.element = this.element.parent().data(
2837  "ui-resizable", this.element.data("ui-resizable")
2838  );
2839 
2840  this.elementIsWrapper = true;
2841 
2842  //Move margins to the wrapper
2843  this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2844  this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2845 
2846  //Prevent Safari textarea resize
2847  this.originalResizeStyle = this.originalElement.css("resize");
2848  this.originalElement.css("resize", "none");
2849 
2850  //Push the actual element to our proportionallyResize internal array
2851  this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2852 
2853  // avoid IE jump (hard set the margin)
2854  this.originalElement.css({ margin: this.originalElement.css("margin") });
2855 
2856  // fix handlers offset
2857  this._proportionallyResize();
2858 
2859  }
2860 
2861  this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2862  if(this.handles.constructor === String) {
2863 
2864  if ( this.handles === "all") {
2865  this.handles = "n,e,s,w,se,sw,ne,nw";
2866  }
2867 
2868  n = this.handles.split(",");
2869  this.handles = {};
2870 
2871  for(i = 0; i < n.length; i++) {
2872 
2873  handle = $.trim(n[i]);
2874  hname = "ui-resizable-"+handle;
2875  axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2876 
2877  // Apply zIndex to all handles - see #7960
2878  axis.css({ zIndex: o.zIndex });
2879 
2880  //TODO : What's going on here?
2881  if ("se" === handle) {
2882  axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2883  }
2884 
2885  //Insert into internal handles object and append to element
2886  this.handles[handle] = ".ui-resizable-"+handle;
2887  this.element.append(axis);
2888  }
2889 
2890  }
2891 
2892  this._renderAxis = function(target) {
2893 
2894  var i, axis, padPos, padWrapper;
2895 
2896  target = target || this.element;
2897 
2898  for(i in this.handles) {
2899 
2900  if(this.handles[i].constructor === String) {
2901  this.handles[i] = $(this.handles[i], this.element).show();
2902  }
2903 
2904  //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2905  if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2906 
2907  axis = $(this.handles[i], this.element);
2908 
2909  //Checking the correct pad and border
2910  padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2911 
2912  //The padding type i have to apply...
2913  padPos = [ "padding",
2914  /ne|nw|n/.test(i) ? "Top" :
2915  /se|sw|s/.test(i) ? "Bottom" :
2916  /^e$/.test(i) ? "Right" : "Left" ].join("");
2917 
2918  target.css(padPos, padWrapper);
2919 
2920  this._proportionallyResize();
2921 
2922  }
2923 
2924  //TODO: What's that good for? There's not anything to be executed left
2925  if(!$(this.handles[i]).length) {
2926  continue;
2927  }
2928  }
2929  };
2930 
2931  //TODO: make renderAxis a prototype function
2932  this._renderAxis(this.element);
2933 
2934  this._handles = $(".ui-resizable-handle", this.element)
2935  .disableSelection();
2936 
2937  //Matching axis name
2938  this._handles.mouseover(function() {
2939  if (!that.resizing) {
2940  if (this.className) {
2941  axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2942  }
2943  //Axis, default = se
2944  that.axis = axis && axis[1] ? axis[1] : "se";
2945  }
2946  });
2947 
2948  //If we want to auto hide the elements
2949  if (o.autoHide) {
2950  this._handles.hide();
2951  $(this.element)
2952  .addClass("ui-resizable-autohide")
2953  .mouseenter(function() {
2954  if (o.disabled) {
2955  return;
2956  }
2957  $(this).removeClass("ui-resizable-autohide");
2958  that._handles.show();
2959  })
2960  .mouseleave(function(){
2961  if (o.disabled) {
2962  return;
2963  }
2964  if (!that.resizing) {
2965  $(this).addClass("ui-resizable-autohide");
2966  that._handles.hide();
2967  }
2968  });
2969  }
2970 
2971  //Initialize the mouse interaction
2972  this._mouseInit();
2973 
2974  },
2975 
2976  _destroy: function() {
2977 
2978  this._mouseDestroy();
2979 
2980  var wrapper,
2981  _destroy = function(exp) {
2982  $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2983  .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2984  };
2985 
2986  //TODO: Unwrap at same DOM position
2987  if (this.elementIsWrapper) {
2988  _destroy(this.element);
2989  wrapper = this.element;
2990  this.originalElement.css({
2991  position: wrapper.css("position"),
2992  width: wrapper.outerWidth(),
2993  height: wrapper.outerHeight(),
2994  top: wrapper.css("top"),
2995  left: wrapper.css("left")
2996  }).insertAfter( wrapper );
2997  wrapper.remove();
2998  }
2999 
3000  this.originalElement.css("resize", this.originalResizeStyle);
3001  _destroy(this.originalElement);
3002 
3003  return this;
3004  },
3005 
3006  _mouseCapture: function(event) {
3007  var i, handle,
3008  capture = false;
3009 
3010  for (i in this.handles) {
3011  handle = $(this.handles[i])[0];
3012  if (handle === event.target || $.contains(handle, event.target)) {
3013  capture = true;
3014  }
3015  }
3016 
3017  return !this.options.disabled && capture;
3018  },
3019 
3020  _mouseStart: function(event) {
3021 
3022  var curleft, curtop, cursor,
3023  o = this.options,
3024  iniPos = this.element.position(),
3025  el = this.element;
3026 
3027  this.resizing = true;
3028 
3029  // bugfix for http://dev.jquery.com/ticket/1749
3030  if ( (/absolute/).test( el.css("position") ) ) {
3031  el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
3032  } else if (el.is(".ui-draggable")) {
3033  el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
3034  }
3035 
3036  this._renderProxy();
3037 
3038  curleft = num(this.helper.css("left"));
3039  curtop = num(this.helper.css("top"));
3040 
3041  if (o.containment) {
3042  curleft += $(o.containment).scrollLeft() || 0;
3043  curtop += $(o.containment).scrollTop() || 0;
3044  }
3045 
3046  //Store needed variables
3047  this.offset = this.helper.offset();
3048  this.position = { left: curleft, top: curtop };
3049  this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3050  this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
3051  this.originalPosition = { left: curleft, top: curtop };
3052  this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
3053  this.originalMousePosition = { left: event.pageX, top: event.pageY };
3054 
3055  //Aspect Ratio
3056  this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
3057 
3058  cursor = $(".ui-resizable-" + this.axis).css("cursor");
3059  $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
3060 
3061  el.addClass("ui-resizable-resizing");
3062  this._propagate("start", event);
3063  return true;
3064  },
3065 
3066  _mouseDrag: function(event) {
3067 
3068  //Increase performance, avoid regex
3069  var data,
3070  el = this.helper, props = {},
3071  smp = this.originalMousePosition,
3072  a = this.axis,
3073  prevTop = this.position.top,
3074  prevLeft = this.position.left,
3075  prevWidth = this.size.width,
3076  prevHeight = this.size.height,
3077  dx = (event.pageX-smp.left)||0,
3078  dy = (event.pageY-smp.top)||0,
3079  trigger = this._change[a];
3080 
3081  if (!trigger) {
3082  return false;
3083  }
3084 
3085  // Calculate the attrs that will be change
3086  data = trigger.apply(this, [event, dx, dy]);
3087 
3088  // Put this in the mouseDrag handler since the user can start pressing shift while resizing
3089  this._updateVirtualBoundaries(event.shiftKey);
3090  if (this._aspectRatio || event.shiftKey) {
3091  data = this._updateRatio(data, event);
3092  }
3093 
3094  data = this._respectSize(data, event);
3095 
3096  this._updateCache(data);
3097 
3098  // plugins callbacks need to be called first
3099  this._propagate("resize", event);
3100 
3101  if (this.position.top !== prevTop) {
3102  props.top = this.position.top + "px";
3103  }
3104  if (this.position.left !== prevLeft) {
3105  props.left = this.position.left + "px";
3106  }
3107  if (this.size.width !== prevWidth) {
3108  props.width = this.size.width + "px";
3109  }
3110  if (this.size.height !== prevHeight) {
3111  props.height = this.size.height + "px";
3112  }
3113  el.css(props);
3114 
3115  if (!this._helper && this._proportionallyResizeElements.length) {
3116  this._proportionallyResize();
3117  }
3118 
3119  // Call the user callback if the element was resized
3120  if ( ! $.isEmptyObject(props) ) {
3121  this._trigger("resize", event, this.ui());
3122  }
3123 
3124  return false;
3125  },
3126 
3127  _mouseStop: function(event) {
3128 
3129  this.resizing = false;
3130  var pr, ista, soffseth, soffsetw, s, left, top,
3131  o = this.options, that = this;
3132 
3133  if(this._helper) {
3134 
3135  pr = this._proportionallyResizeElements;
3136  ista = pr.length && (/textarea/i).test(pr[0].nodeName);
3137  soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
3138  soffsetw = ista ? 0 : that.sizeDiff.width;
3139 
3140  s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };
3141  left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
3142  top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3143 
3144  if (!o.animate) {
3145  this.element.css($.extend(s, { top: top, left: left }));
3146  }
3147 
3148  that.helper.height(that.size.height);
3149  that.helper.width(that.size.width);
3150 
3151  if (this._helper && !o.animate) {
3152  this._proportionallyResize();
3153  }
3154  }
3155 
3156  $("body").css("cursor", "auto");
3157 
3158  this.element.removeClass("ui-resizable-resizing");
3159 
3160  this._propagate("stop", event);
3161 
3162  if (this._helper) {
3163  this.helper.remove();
3164  }
3165 
3166  return false;
3167 
3168  },
3169 
3170  _updateVirtualBoundaries: function(forceAspectRatio) {
3171  var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3172  o = this.options;
3173 
3174  b = {
3175  minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
3176  maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
3177  minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
3178  maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
3179  };
3180 
3181  if(this._aspectRatio || forceAspectRatio) {
3182  // We want to create an enclosing box whose aspect ration is the requested one
3183  // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
3184  pMinWidth = b.minHeight * this.aspectRatio;
3185  pMinHeight = b.minWidth / this.aspectRatio;
3186  pMaxWidth = b.maxHeight * this.aspectRatio;
3187  pMaxHeight = b.maxWidth / this.aspectRatio;
3188 
3189  if(pMinWidth > b.minWidth) {
3190  b.minWidth = pMinWidth;
3191  }
3192  if(pMinHeight > b.minHeight) {
3193  b.minHeight = pMinHeight;
3194  }
3195  if(pMaxWidth < b.maxWidth) {
3196  b.maxWidth = pMaxWidth;
3197  }
3198  if(pMaxHeight < b.maxHeight) {
3199  b.maxHeight = pMaxHeight;
3200  }
3201  }
3202  this._vBoundaries = b;
3203  },
3204 
3205  _updateCache: function(data) {
3206  this.offset = this.helper.offset();
3207  if (isNumber(data.left)) {
3208  this.position.left = data.left;
3209  }
3210  if (isNumber(data.top)) {
3211  this.position.top = data.top;
3212  }
3213  if (isNumber(data.height)) {
3214  this.size.height = data.height;
3215  }
3216  if (isNumber(data.width)) {
3217  this.size.width = data.width;
3218  }
3219  },
3220 
3221  _updateRatio: function( data ) {
3222 
3223  var cpos = this.position,
3224  csize = this.size,
3225  a = this.axis;
3226 
3227  if (isNumber(data.height)) {
3228  data.width = (data.height * this.aspectRatio);
3229  } else if (isNumber(data.width)) {
3230  data.height = (data.width / this.aspectRatio);
3231  }
3232 
3233  if (a === "sw") {
3234  data.left = cpos.left + (csize.width - data.width);
3235  data.top = null;
3236  }
3237  if (a === "nw") {
3238  data.top = cpos.top + (csize.height - data.height);
3239  data.left = cpos.left + (csize.width - data.width);
3240  }
3241 
3242  return data;
3243  },
3244 
3245  _respectSize: function( data ) {
3246 
3247  var o = this._vBoundaries,
3248  a = this.axis,
3249  ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
3250  isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
3251  dw = this.originalPosition.left + this.originalSize.width,
3252  dh = this.position.top + this.size.height,
3253  cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
3254  if (isminw) {
3255  data.width = o.minWidth;
3256  }
3257  if (isminh) {
3258  data.height = o.minHeight;
3259  }
3260  if (ismaxw) {
3261  data.width = o.maxWidth;
3262  }
3263  if (ismaxh) {
3264  data.height = o.maxHeight;
3265  }
3266 
3267  if (isminw && cw) {
3268  data.left = dw - o.minWidth;
3269  }
3270  if (ismaxw && cw) {
3271  data.left = dw - o.maxWidth;
3272  }
3273  if (isminh && ch) {
3274  data.top = dh - o.minHeight;
3275  }
3276  if (ismaxh && ch) {
3277  data.top = dh - o.maxHeight;
3278  }
3279 
3280  // fixing jump error on top/left - bug #2330
3281  if (!data.width && !data.height && !data.left && data.top) {
3282  data.top = null;
3283  } else if (!data.width && !data.height && !data.top && data.left) {
3284  data.left = null;
3285  }
3286 
3287  return data;
3288  },
3289 
3290  _proportionallyResize: function() {
3291 
3292  if (!this._proportionallyResizeElements.length) {
3293  return;
3294  }
3295 
3296  var i, j, borders, paddings, prel,
3297  element = this.helper || this.element;
3298 
3299  for ( i=0; i < this._proportionallyResizeElements.length; i++) {
3300 
3301  prel = this._proportionallyResizeElements[i];
3302 
3303  if (!this.borderDif) {
3304  this.borderDif = [];
3305  borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
3306  paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
3307 
3308  for ( j = 0; j < borders.length; j++ ) {
3309  this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
3310  }
3311  }
3312 
3313  prel.css({
3314  height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
3315  width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
3316  });
3317 
3318  }
3319 
3320  },
3321 
3322  _renderProxy: function() {
3323 
3324  var el = this.element, o = this.options;
3325  this.elementOffset = el.offset();
3326 
3327  if(this._helper) {
3328 
3329  this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
3330 
3331  this.helper.addClass(this._helper).css({
3332  width: this.element.outerWidth() - 1,
3333  height: this.element.outerHeight() - 1,
3334  position: "absolute",
3335  left: this.elementOffset.left +"px",
3336  top: this.elementOffset.top +"px",
3337  zIndex: ++o.zIndex //TODO: Don't modify option
3338  });
3339 
3340  this.helper
3341  .appendTo("body")
3342  .disableSelection();
3343 
3344  } else {
3345  this.helper = this.element;
3346  }
3347 
3348  },
3349 
3350  _change: {
3351  e: function(event, dx) {
3352  return { width: this.originalSize.width + dx };
3353  },
3354  w: function(event, dx) {
3355  var cs = this.originalSize, sp = this.originalPosition;
3356  return { left: sp.left + dx, width: cs.width - dx };
3357  },
3358  n: function(event, dx, dy) {
3359  var cs = this.originalSize, sp = this.originalPosition;
3360  return { top: sp.top + dy, height: cs.height - dy };
3361  },
3362  s: function(event, dx, dy) {
3363  return { height: this.originalSize.height + dy };
3364  },
3365  se: function(event, dx, dy) {
3366  return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3367  },
3368  sw: function(event, dx, dy) {
3369  return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3370  },
3371  ne: function(event, dx, dy) {
3372  return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
3373  },
3374  nw: function(event, dx, dy) {
3375  return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
3376  }
3377  },
3378 
3379  _propagate: function(n, event) {
3380  $.ui.plugin.call(this, n, [event, this.ui()]);
3381  (n !== "resize" && this._trigger(n, event, this.ui()));
3382  },
3383 
3384  plugins: {},
3385 
3386  ui: function() {
3387  return {
3388  originalElement: this.originalElement,
3389  element: this.element,
3390  helper: this.helper,
3391  position: this.position,
3392  size: this.size,
3393  originalSize: this.originalSize,
3394  originalPosition: this.originalPosition
3395  };
3396  }
3397 
3398 });
3399 
3400 /*
3401  * Resizable Extensions
3402  */
3403 
3404 $.ui.plugin.add("resizable", "animate", {
3405 
3406  stop: function( event ) {
3407  var that = $(this).data("ui-resizable"),
3408  o = that.options,
3409  pr = that._proportionallyResizeElements,
3410  ista = pr.length && (/textarea/i).test(pr[0].nodeName),
3411  soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
3412  soffsetw = ista ? 0 : that.sizeDiff.width,
3413  style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
3414  left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
3415  top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
3416 
3417  that.element.animate(
3418  $.extend(style, top && left ? { top: top, left: left } : {}), {
3419  duration: o.animateDuration,
3420  easing: o.animateEasing,
3421  step: function() {
3422 
3423  var data = {
3424  width: parseInt(that.element.css("width"), 10),
3425  height: parseInt(that.element.css("height"), 10),
3426  top: parseInt(that.element.css("top"), 10),
3427  left: parseInt(that.element.css("left"), 10)
3428  };
3429 
3430  if (pr && pr.length) {
3431  $(pr[0]).css({ width: data.width, height: data.height });
3432  }
3433 
3434  // propagating resize, and updating values for each animation step
3435  that._updateCache(data);
3436  that._propagate("resize", event);
3437 
3438  }
3439  }
3440  );
3441  }
3442 
3443 });
3444 
3445 $.ui.plugin.add("resizable", "containment", {
3446 
3447  start: function() {
3448  var element, p, co, ch, cw, width, height,
3449  that = $(this).data("ui-resizable"),
3450  o = that.options,
3451  el = that.element,
3452  oc = o.containment,
3453  ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
3454 
3455  if (!ce) {
3456  return;
3457  }
3458 
3459  that.containerElement = $(ce);
3460 
3461  if (/document/.test(oc) || oc === document) {
3462  that.containerOffset = { left: 0, top: 0 };
3463  that.containerPosition = { left: 0, top: 0 };
3464 
3465  that.parentData = {
3466  element: $(document), left: 0, top: 0,
3467  width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3468  };
3469  }
3470 
3471  // i'm a node, so compute top, left, right, bottom
3472  else {
3473  element = $(ce);
3474  p = [];
3475  $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3476 
3477  that.containerOffset = element.offset();
3478  that.containerPosition = element.position();
3479  that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3480 
3481  co = that.containerOffset;
3482  ch = that.containerSize.height;
3483  cw = that.containerSize.width;
3484  width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3485  height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3486 
3487  that.parentData = {
3488  element: ce, left: co.left, top: co.top, width: width, height: height
3489  };
3490  }
3491  },
3492 
3493  resize: function( event ) {
3494  var woset, hoset, isParent, isOffsetRelative,
3495  that = $(this).data("ui-resizable"),
3496  o = that.options,
3497  co = that.containerOffset, cp = that.position,
3498  pRatio = that._aspectRatio || event.shiftKey,
3499  cop = { top:0, left:0 }, ce = that.containerElement;
3500 
3501  if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3502  cop = co;
3503  }
3504 
3505  if (cp.left < (that._helper ? co.left : 0)) {
3506  that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3507  if (pRatio) {
3508  that.size.height = that.size.width / that.aspectRatio;
3509  }
3510  that.position.left = o.helper ? co.left : 0;
3511  }
3512 
3513  if (cp.top < (that._helper ? co.top : 0)) {
3514  that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3515  if (pRatio) {
3516  that.size.width = that.size.height * that.aspectRatio;
3517  }
3518  that.position.top = that._helper ? co.top : 0;
3519  }
3520 
3521  that.offset.left = that.parentData.left+that.position.left;
3522  that.offset.top = that.parentData.top+that.position.top;
3523 
3524  woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3525  hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3526 
3527  isParent = that.containerElement.get(0) === that.element.parent().get(0);
3528  isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3529 
3530  if(isParent && isOffsetRelative) {
3531  woset -= that.parentData.left;
3532  }
3533 
3534  if (woset + that.size.width >= that.parentData.width) {
3535  that.size.width = that.parentData.width - woset;
3536  if (pRatio) {
3537  that.size.height = that.size.width / that.aspectRatio;
3538  }
3539  }
3540 
3541  if (hoset + that.size.height >= that.parentData.height) {
3542  that.size.height = that.parentData.height - hoset;
3543  if (pRatio) {
3544  that.size.width = that.size.height * that.aspectRatio;
3545  }
3546  }
3547  },
3548 
3549  stop: function(){
3550  var that = $(this).data("ui-resizable"),
3551  o = that.options,
3552  co = that.containerOffset,
3553  cop = that.containerPosition,
3554  ce = that.containerElement,
3555  helper = $(that.helper),
3556  ho = helper.offset(),
3557  w = helper.outerWidth() - that.sizeDiff.width,
3558  h = helper.outerHeight() - that.sizeDiff.height;
3559 
3560  if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3561  $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3562  }
3563 
3564  if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3565  $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3566  }
3567 
3568  }
3569 });
3570 
3571 $.ui.plugin.add("resizable", "alsoResize", {
3572 
3573  start: function () {
3574  var that = $(this).data("ui-resizable"),
3575  o = that.options,
3576  _store = function (exp) {
3577  $(exp).each(function() {
3578  var el = $(this);
3579  el.data("ui-resizable-alsoresize", {
3580  width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3581  left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3582  });
3583  });
3584  };
3585 
3586  if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3587  if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3588  else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3589  }else{
3590  _store(o.alsoResize);
3591  }
3592  },
3593 
3594  resize: function (event, ui) {
3595  var that = $(this).data("ui-resizable"),
3596  o = that.options,
3597  os = that.originalSize,
3598  op = that.originalPosition,
3599  delta = {
3600  height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3601  top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3602  },
3603 
3604  _alsoResize = function (exp, c) {
3605  $(exp).each(function() {
3606  var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3607  css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3608 
3609  $.each(css, function (i, prop) {
3610  var sum = (start[prop]||0) + (delta[prop]||0);
3611  if (sum && sum >= 0) {
3612  style[prop] = sum || null;
3613  }
3614  });
3615 
3616  el.css(style);
3617  });
3618  };
3619 
3620  if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3621  $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3622  }else{
3623  _alsoResize(o.alsoResize);
3624  }
3625  },
3626 
3627  stop: function () {
3628  $(this).removeData("resizable-alsoresize");
3629  }
3630 });
3631 
3632 $.ui.plugin.add("resizable", "ghost", {
3633 
3634  start: function() {
3635 
3636  var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3637 
3638  that.ghost = that.originalElement.clone();
3639  that.ghost
3640  .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3641  .addClass("ui-resizable-ghost")
3642  .addClass(typeof o.ghost === "string" ? o.ghost : "");
3643 
3644  that.ghost.appendTo(that.helper);
3645 
3646  },
3647 
3648  resize: function(){
3649  var that = $(this).data("ui-resizable");
3650  if (that.ghost) {
3651  that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3652  }
3653  },
3654 
3655  stop: function() {
3656  var that = $(this).data("ui-resizable");
3657  if (that.ghost && that.helper) {
3658  that.helper.get(0).removeChild(that.ghost.get(0));
3659  }
3660  }
3661 
3662 });
3663 
3664 $.ui.plugin.add("resizable", "grid", {
3665 
3666  resize: function() {
3667  var that = $(this).data("ui-resizable"),
3668  o = that.options,
3669  cs = that.size,
3670  os = that.originalSize,
3671  op = that.originalPosition,
3672  a = that.axis,
3673  grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3674  gridX = (grid[0]||1),
3675  gridY = (grid[1]||1),
3676  ox = Math.round((cs.width - os.width) / gridX) * gridX,
3677  oy = Math.round((cs.height - os.height) / gridY) * gridY,
3678  newWidth = os.width + ox,
3679  newHeight = os.height + oy,
3680  isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3681  isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3682  isMinWidth = o.minWidth && (o.minWidth > newWidth),
3683  isMinHeight = o.minHeight && (o.minHeight > newHeight);
3684 
3685  o.grid = grid;
3686 
3687  if (isMinWidth) {
3688  newWidth = newWidth + gridX;
3689  }
3690  if (isMinHeight) {
3691  newHeight = newHeight + gridY;
3692  }
3693  if (isMaxWidth) {
3694  newWidth = newWidth - gridX;
3695  }
3696  if (isMaxHeight) {
3697  newHeight = newHeight - gridY;
3698  }
3699 
3700  if (/^(se|s|e)$/.test(a)) {
3701  that.size.width = newWidth;
3702  that.size.height = newHeight;
3703  } else if (/^(ne)$/.test(a)) {
3704  that.size.width = newWidth;
3705  that.size.height = newHeight;
3706  that.position.top = op.top - oy;
3707  } else if (/^(sw)$/.test(a)) {
3708  that.size.width = newWidth;
3709  that.size.height = newHeight;
3710  that.position.left = op.left - ox;
3711  } else {
3712  that.size.width = newWidth;
3713  that.size.height = newHeight;
3714  that.position.top = op.top - oy;
3715  that.position.left = op.left - ox;
3716  }
3717  }
3718 
3719 });
3720 
3721 })(jQuery);
3722 (function( $, undefined ) {
3723 
3724 $.widget("ui.selectable", $.ui.mouse, {
3725  version: "1.10.3",
3726  options: {
3727  appendTo: "body",
3728  autoRefresh: true,
3729  distance: 0,
3730  filter: "*",
3731  tolerance: "touch",
3732 
3733  // callbacks
3734  selected: null,
3735  selecting: null,
3736  start: null,
3737  stop: null,
3738  unselected: null,
3739  unselecting: null
3740  },
3741  _create: function() {
3742  var selectees,
3743  that = this;
3744 
3745  this.element.addClass("ui-selectable");
3746 
3747  this.dragged = false;
3748 
3749  // cache selectee children based on filter
3750  this.refresh = function() {
3751  selectees = $(that.options.filter, that.element[0]);
3752  selectees.addClass("ui-selectee");
3753  selectees.each(function() {
3754  var $this = $(this),
3755  pos = $this.offset();
3756  $.data(this, "selectable-item", {
3757  element: this,
3758  $element: $this,
3759  left: pos.left,
3760  top: pos.top,
3761  right: pos.left + $this.outerWidth(),
3762  bottom: pos.top + $this.outerHeight(),
3763  startselected: false,
3764  selected: $this.hasClass("ui-selected"),
3765  selecting: $this.hasClass("ui-selecting"),
3766  unselecting: $this.hasClass("ui-unselecting")
3767  });
3768  });
3769  };
3770  this.refresh();
3771 
3772  this.selectees = selectees.addClass("ui-selectee");
3773 
3774  this._mouseInit();
3775 
3776  this.helper = $("<div class='ui-selectable-helper'></div>");
3777  },
3778 
3779  _destroy: function() {
3780  this.selectees
3781  .removeClass("ui-selectee")
3782  .removeData("selectable-item");
3783  this.element
3784  .removeClass("ui-selectable ui-selectable-disabled");
3785  this._mouseDestroy();
3786  },
3787 
3788  _mouseStart: function(event) {
3789  var that = this,
3790  options = this.options;
3791 
3792  this.opos = [event.pageX, event.pageY];
3793 
3794  if (this.options.disabled) {
3795  return;
3796  }
3797 
3798  this.selectees = $(options.filter, this.element[0]);
3799 
3800  this._trigger("start", event);
3801 
3802  $(options.appendTo).append(this.helper);
3803  // position helper (lasso)
3804  this.helper.css({
3805  "left": event.pageX,
3806  "top": event.pageY,
3807  "width": 0,
3808  "height": 0
3809  });
3810 
3811  if (options.autoRefresh) {
3812  this.refresh();
3813  }
3814 
3815  this.selectees.filter(".ui-selected").each(function() {
3816  var selectee = $.data(this, "selectable-item");
3817  selectee.startselected = true;
3818  if (!event.metaKey && !event.ctrlKey) {
3819  selectee.$element.removeClass("ui-selected");
3820  selectee.selected = false;
3821  selectee.$element.addClass("ui-unselecting");
3822  selectee.unselecting = true;
3823  // selectable UNSELECTING callback
3824  that._trigger("unselecting", event, {
3825  unselecting: selectee.element
3826  });
3827  }
3828  });
3829 
3830  $(event.target).parents().addBack().each(function() {
3831  var doSelect,
3832  selectee = $.data(this, "selectable-item");
3833  if (selectee) {
3834  doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3835  selectee.$element
3836  .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3837  .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3838  selectee.unselecting = !doSelect;
3839  selectee.selecting = doSelect;
3840  selectee.selected = doSelect;
3841  // selectable (UN)SELECTING callback
3842  if (doSelect) {
3843  that._trigger("selecting", event, {
3844  selecting: selectee.element
3845  });
3846  } else {
3847  that._trigger("unselecting", event, {
3848  unselecting: selectee.element
3849  });
3850  }
3851  return false;
3852  }
3853  });
3854 
3855  },
3856 
3857  _mouseDrag: function(event) {
3858 
3859  this.dragged = true;
3860 
3861  if (this.options.disabled) {
3862  return;
3863  }
3864 
3865  var tmp,
3866  that = this,
3867  options = this.options,
3868  x1 = this.opos[0],
3869  y1 = this.opos[1],
3870  x2 = event.pageX,
3871  y2 = event.pageY;
3872 
3873  if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3874  if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3875  this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3876 
3877  this.selectees.each(function() {
3878  var selectee = $.data(this, "selectable-item"),
3879  hit = false;
3880 
3881  //prevent helper from being selected if appendTo: selectable
3882  if (!selectee || selectee.element === that.element[0]) {
3883  return;
3884  }
3885 
3886  if (options.tolerance === "touch") {
3887  hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3888  } else if (options.tolerance === "fit") {
3889  hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3890  }
3891 
3892  if (hit) {
3893  // SELECT
3894  if (selectee.selected) {
3895  selectee.$element.removeClass("ui-selected");
3896  selectee.selected = false;
3897  }
3898  if (selectee.unselecting) {
3899  selectee.$element.removeClass("ui-unselecting");
3900  selectee.unselecting = false;
3901  }
3902  if (!selectee.selecting) {
3903  selectee.$element.addClass("ui-selecting");
3904  selectee.selecting = true;
3905  // selectable SELECTING callback
3906  that._trigger("selecting", event, {
3907  selecting: selectee.element
3908  });
3909  }
3910  } else {
3911  // UNSELECT
3912  if (selectee.selecting) {
3913  if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3914  selectee.$element.removeClass("ui-selecting");
3915  selectee.selecting = false;
3916  selectee.$element.addClass("ui-selected");
3917  selectee.selected = true;
3918  } else {
3919  selectee.$element.removeClass("ui-selecting");
3920  selectee.selecting = false;
3921  if (selectee.startselected) {
3922  selectee.$element.addClass("ui-unselecting");
3923  selectee.unselecting = true;
3924  }
3925  // selectable UNSELECTING callback
3926  that._trigger("unselecting", event, {
3927  unselecting: selectee.element
3928  });
3929  }
3930  }
3931  if (selectee.selected) {
3932  if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3933  selectee.$element.removeClass("ui-selected");
3934  selectee.selected = false;
3935 
3936  selectee.$element.addClass("ui-unselecting");
3937  selectee.unselecting = true;
3938  // selectable UNSELECTING callback
3939  that._trigger("unselecting", event, {
3940  unselecting: selectee.element
3941  });
3942  }
3943  }
3944  }
3945  });
3946 
3947  return false;
3948  },
3949 
3950  _mouseStop: function(event) {
3951  var that = this;
3952 
3953  this.dragged = false;
3954 
3955  $(".ui-unselecting", this.element[0]).each(function() {
3956  var selectee = $.data(this, "selectable-item");
3957  selectee.$element.removeClass("ui-unselecting");
3958  selectee.unselecting = false;
3959  selectee.startselected = false;
3960  that._trigger("unselected", event, {
3961  unselected: selectee.element
3962  });
3963  });
3964  $(".ui-selecting", this.element[0]).each(function() {
3965  var selectee = $.data(this, "selectable-item");
3966  selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3967  selectee.selecting = false;
3968  selectee.selected = true;
3969  selectee.startselected = true;
3970  that._trigger("selected", event, {
3971  selected: selectee.element
3972  });
3973  });
3974  this._trigger("stop", event);
3975 
3976  this.helper.remove();
3977 
3978  return false;
3979  }
3980 
3981 });
3982 
3983 })(jQuery);
3984 (function( $, undefined ) {
3985 
3986 /*jshint loopfunc: true */
3987 
3988 function isOverAxis( x, reference, size ) {
3989  return ( x > reference ) && ( x < ( reference + size ) );
3990 }
3991 
3992 function isFloating(item) {
3993  return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3994 }
3995 
3996 $.widget("ui.sortable", $.ui.mouse, {
3997  version: "1.10.3",
3998  widgetEventPrefix: "sort",
3999  ready: false,
4000  options: {
4001  appendTo: "parent",
4002  axis: false,
4003  connectWith: false,
4004  containment: false,
4005  cursor: "auto",
4006  cursorAt: false,
4007  dropOnEmpty: true,
4008  forcePlaceholderSize: false,
4009  forceHelperSize: false,
4010  grid: false,
4011  handle: false,
4012  helper: "original",
4013  items: "> *",
4014  opacity: false,
4015  placeholder: false,
4016  revert: false,
4017  scroll: true,
4018  scrollSensitivity: 20,
4019  scrollSpeed: 20,
4020  scope: "default",
4021  tolerance: "intersect",
4022  zIndex: 1000,
4023 
4024  // callbacks
4025  activate: null,
4026  beforeStop: null,
4027  change: null,
4028  deactivate: null,
4029  out: null,
4030  over: null,
4031  receive: null,
4032  remove: null,
4033  sort: null,
4034  start: null,
4035  stop: null,
4036  update: null
4037  },
4038  _create: function() {
4039 
4040  var o = this.options;
4041  this.containerCache = {};
4042  this.element.addClass("ui-sortable");
4043 
4044  //Get the items
4045  this.refresh();
4046 
4047  //Let's determine if the items are being displayed horizontally
4048  this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
4049 
4050  //Let's determine the parent's offset
4051  this.offset = this.element.offset();
4052 
4053  //Initialize mouse events for interaction
4054  this._mouseInit();
4055 
4056  //We're ready to go
4057  this.ready = true;
4058 
4059  },
4060 
4061  _destroy: function() {
4062  this.element
4063  .removeClass("ui-sortable ui-sortable-disabled");
4064  this._mouseDestroy();
4065 
4066  for ( var i = this.items.length - 1; i >= 0; i-- ) {
4067  this.items[i].item.removeData(this.widgetName + "-item");
4068  }
4069 
4070  return this;
4071  },
4072 
4073  _setOption: function(key, value){
4074  if ( key === "disabled" ) {
4075  this.options[ key ] = value;
4076 
4077  this.widget().toggleClass( "ui-sortable-disabled", !!value );
4078  } else {
4079  // Don't call widget base _setOption for disable as it adds ui-state-disabled class
4080  $.Widget.prototype._setOption.apply(this, arguments);
4081  }
4082  },
4083 
4084  _mouseCapture: function(event, overrideHandle) {
4085  var currentItem = null,
4086  validHandle = false,
4087  that = this;
4088 
4089  if (this.reverting) {
4090  return false;
4091  }
4092 
4093  if(this.options.disabled || this.options.type === "static") {
4094  return false;
4095  }
4096 
4097  //We have to refresh the items data once first
4098  this._refreshItems(event);
4099 
4100  //Find out if the clicked node (or one of its parents) is a actual item in this.items
4101  $(event.target).parents().each(function() {
4102  if($.data(this, that.widgetName + "-item") === that) {
4103  currentItem = $(this);
4104  return false;
4105  }
4106  });
4107  if($.data(event.target, that.widgetName + "-item") === that) {
4108  currentItem = $(event.target);
4109  }
4110 
4111  if(!currentItem) {
4112  return false;
4113  }
4114  if(this.options.handle && !overrideHandle) {
4115  $(this.options.handle, currentItem).find("*").addBack().each(function() {
4116  if(this === event.target) {
4117  validHandle = true;
4118  }
4119  });
4120  if(!validHandle) {
4121  return false;
4122  }
4123  }
4124 
4125  this.currentItem = currentItem;
4126  this._removeCurrentsFromItems();
4127  return true;
4128 
4129  },
4130 
4131  _mouseStart: function(event, overrideHandle, noActivation) {
4132 
4133  var i, body,
4134  o = this.options;
4135 
4136  this.currentContainer = this;
4137 
4138  //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
4139  this.refreshPositions();
4140 
4141  //Create and append the visible helper
4142  this.helper = this._createHelper(event);
4143 
4144  //Cache the helper size
4145  this._cacheHelperProportions();
4146 
4147  /*
4148  * - Position generation -
4149  * This block generates everything position related - it's the core of draggables.
4150  */
4151 
4152  //Cache the margins of the original element
4153  this._cacheMargins();
4154 
4155  //Get the next scrolling parent
4156  this.scrollParent = this.helper.scrollParent();
4157 
4158  //The element's absolute position on the page minus margins
4159  this.offset = this.currentItem.offset();
4160  this.offset = {
4161  top: this.offset.top - this.margins.top,
4162  left: this.offset.left - this.margins.left
4163  };
4164 
4165  $.extend(this.offset, {
4166  click: { //Where the click happened, relative to the element
4167  left: event.pageX - this.offset.left,
4168  top: event.pageY - this.offset.top
4169  },
4170  parent: this._getParentOffset(),
4171  relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
4172  });
4173 
4174  // Only after we got the offset, we can change the helper's position to absolute
4175  // TODO: Still need to figure out a way to make relative sorting possible
4176  this.helper.css("position", "absolute");
4177  this.cssPosition = this.helper.css("position");
4178 
4179  //Generate the original position
4180  this.originalPosition = this._generatePosition(event);
4181  this.originalPageX = event.pageX;
4182  this.originalPageY = event.pageY;
4183 
4184  //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4185  (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
4186 
4187  //Cache the former DOM position
4188  this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
4189 
4190  //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
4191  if(this.helper[0] !== this.currentItem[0]) {
4192  this.currentItem.hide();
4193  }
4194 
4195  //Create the placeholder
4196  this._createPlaceholder();
4197 
4198  //Set a containment if given in the options
4199  if(o.containment) {
4200  this._setContainment();
4201  }
4202 
4203  if( o.cursor && o.cursor !== "auto" ) { // cursor option
4204  body = this.document.find( "body" );
4205 
4206  // support: IE
4207  this.storedCursor = body.css( "cursor" );
4208  body.css( "cursor", o.cursor );
4209 
4210  this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
4211  }
4212 
4213  if(o.opacity) { // opacity option
4214  if (this.helper.css("opacity")) {
4215  this._storedOpacity = this.helper.css("opacity");
4216  }
4217  this.helper.css("opacity", o.opacity);
4218  }
4219 
4220  if(o.zIndex) { // zIndex option
4221  if (this.helper.css("zIndex")) {
4222  this._storedZIndex = this.helper.css("zIndex");
4223  }
4224  this.helper.css("zIndex", o.zIndex);
4225  }
4226 
4227  //Prepare scrolling
4228  if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4229  this.overflowOffset = this.scrollParent.offset();
4230  }
4231 
4232  //Call callbacks
4233  this._trigger("start", event, this._uiHash());
4234 
4235  //Recache the helper size
4236  if(!this._preserveHelperProportions) {
4237  this._cacheHelperProportions();
4238  }
4239 
4240 
4241  //Post "activate" events to possible containers
4242  if( !noActivation ) {
4243  for ( i = this.containers.length - 1; i >= 0; i-- ) {
4244  this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4245  }
4246  }
4247 
4248  //Prepare possible droppables
4249  if($.ui.ddmanager) {
4250  $.ui.ddmanager.current = this;
4251  }
4252 
4253  if ($.ui.ddmanager && !o.dropBehaviour) {
4254  $.ui.ddmanager.prepareOffsets(this, event);
4255  }
4256 
4257  this.dragging = true;
4258 
4259  this.helper.addClass("ui-sortable-helper");
4260  this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
4261  return true;
4262 
4263  },
4264 
4265  _mouseDrag: function(event) {
4266  var i, item, itemElement, intersection,
4267  o = this.options,
4268  scrolled = false;
4269 
4270  //Compute the helpers position
4271  this.position = this._generatePosition(event);
4272  this.positionAbs = this._convertPositionTo("absolute");
4273 
4274  if (!this.lastPositionAbs) {
4275  this.lastPositionAbs = this.positionAbs;
4276  }
4277 
4278  //Do scrolling
4279  if(this.options.scroll) {
4280  if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
4281 
4282  if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
4283  this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
4284  } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
4285  this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
4286  }
4287 
4288  if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
4289  this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
4290  } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
4291  this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
4292  }
4293 
4294  } else {
4295 
4296  if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
4297  scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
4298  } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
4299  scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
4300  }
4301 
4302  if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
4303  scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
4304  } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
4305  scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
4306  }
4307 
4308  }
4309 
4310  if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
4311  $.ui.ddmanager.prepareOffsets(this, event);
4312  }
4313  }
4314 
4315  //Regenerate the absolute position used for position checks
4316  this.positionAbs = this._convertPositionTo("absolute");
4317 
4318  //Set the helper position
4319  if(!this.options.axis || this.options.axis !== "y") {
4320  this.helper[0].style.left = this.position.left+"px";
4321  }
4322  if(!this.options.axis || this.options.axis !== "x") {
4323  this.helper[0].style.top = this.position.top+"px";
4324  }
4325 
4326  //Rearrange
4327  for (i = this.items.length - 1; i >= 0; i--) {
4328 
4329  //Cache variables and intersection, continue if no intersection
4330  item = this.items[i];
4331  itemElement = item.item[0];
4332  intersection = this._intersectsWithPointer(item);
4333  if (!intersection) {
4334  continue;
4335  }
4336 
4337  // Only put the placeholder inside the current Container, skip all
4338  // items form other containers. This works because when moving
4339  // an item from one container to another the
4340  // currentContainer is switched before the placeholder is moved.
4341  //
4342  // Without this moving items in "sub-sortables" can cause the placeholder to jitter
4343  // beetween the outer and inner container.
4344  if (item.instance !== this.currentContainer) {
4345  continue;
4346  }
4347 
4348  // cannot intersect with itself
4349  // no useless actions that have been done before
4350  // no action if the item moved is the parent of the item checked
4351  if (itemElement !== this.currentItem[0] &&
4352  this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
4353  !$.contains(this.placeholder[0], itemElement) &&
4354  (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
4355  ) {
4356 
4357  this.direction = intersection === 1 ? "down" : "up";
4358 
4359  if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
4360  this._rearrange(event, item);
4361  } else {
4362  break;
4363  }
4364 
4365  this._trigger("change", event, this._uiHash());
4366  break;
4367  }
4368  }
4369 
4370  //Post events to containers
4371  this._contactContainers(event);
4372 
4373  //Interconnect with droppables
4374  if($.ui.ddmanager) {
4375  $.ui.ddmanager.drag(this, event);
4376  }
4377 
4378  //Call callbacks
4379  this._trigger("sort", event, this._uiHash());
4380 
4381  this.lastPositionAbs = this.positionAbs;
4382  return false;
4383 
4384  },
4385 
4386  _mouseStop: function(event, noPropagation) {
4387 
4388  if(!event) {
4389  return;
4390  }
4391 
4392  //If we are using droppables, inform the manager about the drop
4393  if ($.ui.ddmanager && !this.options.dropBehaviour) {
4394  $.ui.ddmanager.drop(this, event);
4395  }
4396 
4397  if(this.options.revert) {
4398  var that = this,
4399  cur = this.placeholder.offset(),
4400  axis = this.options.axis,
4401  animation = {};
4402 
4403  if ( !axis || axis === "x" ) {
4404  animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
4405  }
4406  if ( !axis || axis === "y" ) {
4407  animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
4408  }
4409  this.reverting = true;
4410  $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
4411  that._clear(event);
4412  });
4413  } else {
4414  this._clear(event, noPropagation);
4415  }
4416 
4417  return false;
4418 
4419  },
4420 
4421  cancel: function() {
4422 
4423  if(this.dragging) {
4424 
4425  this._mouseUp({ target: null });
4426 
4427  if(this.options.helper === "original") {
4428  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4429  } else {
4430  this.currentItem.show();
4431  }
4432 
4433  //Post deactivating events to containers
4434  for (var i = this.containers.length - 1; i >= 0; i--){
4435  this.containers[i]._trigger("deactivate", null, this._uiHash(this));
4436  if(this.containers[i].containerCache.over) {
4437  this.containers[i]._trigger("out", null, this._uiHash(this));
4438  this.containers[i].containerCache.over = 0;
4439  }
4440  }
4441 
4442  }
4443 
4444  if (this.placeholder) {
4445  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4446  if(this.placeholder[0].parentNode) {
4447  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4448  }
4449  if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
4450  this.helper.remove();
4451  }
4452 
4453  $.extend(this, {
4454  helper: null,
4455  dragging: false,
4456  reverting: false,
4457  _noFinalSort: null
4458  });
4459 
4460  if(this.domPosition.prev) {
4461  $(this.domPosition.prev).after(this.currentItem);
4462  } else {
4463  $(this.domPosition.parent).prepend(this.currentItem);
4464  }
4465  }
4466 
4467  return this;
4468 
4469  },
4470 
4471  serialize: function(o) {
4472 
4473  var items = this._getItemsAsjQuery(o && o.connected),
4474  str = [];
4475  o = o || {};
4476 
4477  $(items).each(function() {
4478  var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4479  if (res) {
4480  str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4481  }
4482  });
4483 
4484  if(!str.length && o.key) {
4485  str.push(o.key + "=");
4486  }
4487 
4488  return str.join("&");
4489 
4490  },
4491 
4492  toArray: function(o) {
4493 
4494  var items = this._getItemsAsjQuery(o && o.connected),
4495  ret = [];
4496 
4497  o = o || {};
4498 
4499  items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4500  return ret;
4501 
4502  },
4503 
4504  /* Be careful with the following core functions */
4505  _intersectsWith: function(item) {
4506 
4507  var x1 = this.positionAbs.left,
4508  x2 = x1 + this.helperProportions.width,
4509  y1 = this.positionAbs.top,
4510  y2 = y1 + this.helperProportions.height,
4511  l = item.left,
4512  r = l + item.width,
4513  t = item.top,
4514  b = t + item.height,
4515  dyClick = this.offset.click.top,
4516  dxClick = this.offset.click.left,
4517  isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4518  isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4519  isOverElement = isOverElementHeight && isOverElementWidth;
4520 
4521  if ( this.options.tolerance === "pointer" ||
4522  this.options.forcePointerForContainers ||
4523  (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4524  ) {
4525  return isOverElement;
4526  } else {
4527 
4528  return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4529  x2 - (this.helperProportions.width / 2) < r && // Left Half
4530  t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4531  y2 - (this.helperProportions.height / 2) < b ); // Top Half
4532 
4533  }
4534  },
4535 
4536  _intersectsWithPointer: function(item) {
4537 
4538  var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4539  isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4540  isOverElement = isOverElementHeight && isOverElementWidth,
4541  verticalDirection = this._getDragVerticalDirection(),
4542  horizontalDirection = this._getDragHorizontalDirection();
4543 
4544  if (!isOverElement) {
4545  return false;
4546  }
4547 
4548  return this.floating ?
4549  ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4550  : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4551 
4552  },
4553 
4554  _intersectsWithSides: function(item) {
4555 
4556  var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4557  isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4558  verticalDirection = this._getDragVerticalDirection(),
4559  horizontalDirection = this._getDragHorizontalDirection();
4560 
4561  if (this.floating && horizontalDirection) {
4562  return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4563  } else {
4564  return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4565  }
4566 
4567  },
4568 
4569  _getDragVerticalDirection: function() {
4570  var delta = this.positionAbs.top - this.lastPositionAbs.top;
4571  return delta !== 0 && (delta > 0 ? "down" : "up");
4572  },
4573 
4574  _getDragHorizontalDirection: function() {
4575  var delta = this.positionAbs.left - this.lastPositionAbs.left;
4576  return delta !== 0 && (delta > 0 ? "right" : "left");
4577  },
4578 
4579  refresh: function(event) {
4580  this._refreshItems(event);
4581  this.refreshPositions();
4582  return this;
4583  },
4584 
4585  _connectWith: function() {
4586  var options = this.options;
4587  return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4588  },
4589 
4590  _getItemsAsjQuery: function(connected) {
4591 
4592  var i, j, cur, inst,
4593  items = [],
4594  queries = [],
4595  connectWith = this._connectWith();
4596 
4597  if(connectWith && connected) {
4598  for (i = connectWith.length - 1; i >= 0; i--){
4599  cur = $(connectWith[i]);
4600  for ( j = cur.length - 1; j >= 0; j--){
4601  inst = $.data(cur[j], this.widgetFullName);
4602  if(inst && inst !== this && !inst.options.disabled) {
4603  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]);
4604  }
4605  }
4606  }
4607  }
4608 
4609  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]);
4610 
4611  for (i = queries.length - 1; i >= 0; i--){
4612  queries[i][0].each(function() {
4613  items.push(this);
4614  });
4615  }
4616 
4617  return $(items);
4618 
4619  },
4620 
4621  _removeCurrentsFromItems: function() {
4622 
4623  var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4624 
4625  this.items = $.grep(this.items, function (item) {
4626  for (var j=0; j < list.length; j++) {
4627  if(list[j] === item.item[0]) {
4628  return false;
4629  }
4630  }
4631  return true;
4632  });
4633 
4634  },
4635 
4636  _refreshItems: function(event) {
4637 
4638  this.items = [];
4639  this.containers = [this];
4640 
4641  var i, j, cur, inst, targetData, _queries, item, queriesLength,
4642  items = this.items,
4643  queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4644  connectWith = this._connectWith();
4645 
4646  if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4647  for (i = connectWith.length - 1; i >= 0; i--){
4648  cur = $(connectWith[i]);
4649  for (j = cur.length - 1; j >= 0; j--){
4650  inst = $.data(cur[j], this.widgetFullName);
4651  if(inst && inst !== this && !inst.options.disabled) {
4652  queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4653  this.containers.push(inst);
4654  }
4655  }
4656  }
4657  }
4658 
4659  for (i = queries.length - 1; i >= 0; i--) {
4660  targetData = queries[i][1];
4661  _queries = queries[i][0];
4662 
4663  for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4664  item = $(_queries[j]);
4665 
4666  item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4667 
4668  items.push({
4669  item: item,
4670  instance: targetData,
4671  width: 0, height: 0,
4672  left: 0, top: 0
4673  });
4674  }
4675  }
4676 
4677  },
4678 
4679  refreshPositions: function(fast) {
4680 
4681  //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4682  if(this.offsetParent && this.helper) {
4683  this.offset.parent = this._getParentOffset();
4684  }
4685 
4686  var i, item, t, p;
4687 
4688  for (i = this.items.length - 1; i >= 0; i--){
4689  item = this.items[i];
4690 
4691  //We ignore calculating positions of all connected containers when we're not over them
4692  if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4693  continue;
4694  }
4695 
4696  t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4697 
4698  if (!fast) {
4699  item.width = t.outerWidth();
4700  item.height = t.outerHeight();
4701  }
4702 
4703  p = t.offset();
4704  item.left = p.left;
4705  item.top = p.top;
4706  }
4707 
4708  if(this.options.custom && this.options.custom.refreshContainers) {
4709  this.options.custom.refreshContainers.call(this);
4710  } else {
4711  for (i = this.containers.length - 1; i >= 0; i--){
4712  p = this.containers[i].element.offset();
4713  this.containers[i].containerCache.left = p.left;
4714  this.containers[i].containerCache.top = p.top;
4715  this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4716  this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4717  }
4718  }
4719 
4720  return this;
4721  },
4722 
4723  _createPlaceholder: function(that) {
4724  that = that || this;
4725  var className,
4726  o = that.options;
4727 
4728  if(!o.placeholder || o.placeholder.constructor === String) {
4729  className = o.placeholder;
4730  o.placeholder = {
4731  element: function() {
4732 
4733  var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4734  element = $( "<" + nodeName + ">", that.document[0] )
4735  .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4736  .removeClass("ui-sortable-helper");
4737 
4738  if ( nodeName === "tr" ) {
4739  that.currentItem.children().each(function() {
4740  $( "<td>&#160;</td>", that.document[0] )
4741  .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4742  .appendTo( element );
4743  });
4744  } else if ( nodeName === "img" ) {
4745  element.attr( "src", that.currentItem.attr( "src" ) );
4746  }
4747 
4748  if ( !className ) {
4749  element.css( "visibility", "hidden" );
4750  }
4751 
4752  return element;
4753  },
4754  update: function(container, p) {
4755 
4756  // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4757  // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4758  if(className && !o.forcePlaceholderSize) {
4759  return;
4760  }
4761 
4762  //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
4763  if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4764  if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4765  }
4766  };
4767  }
4768 
4769  //Create the placeholder
4770  that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4771 
4772  //Append it after the actual current item
4773  that.currentItem.after(that.placeholder);
4774 
4775  //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4776  o.placeholder.update(that, that.placeholder);
4777 
4778  },
4779 
4780  _contactContainers: function(event) {
4781  var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4782  innermostContainer = null,
4783  innermostIndex = null;
4784 
4785  // get innermost container that intersects with item
4786  for (i = this.containers.length - 1; i >= 0; i--) {
4787 
4788  // never consider a container that's located within the item itself
4789  if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4790  continue;
4791  }
4792 
4793  if(this._intersectsWith(this.containers[i].containerCache)) {
4794 
4795  // if we've already found a container and it's more "inner" than this, then continue
4796  if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4797  continue;
4798  }
4799 
4800  innermostContainer = this.containers[i];
4801  innermostIndex = i;
4802 
4803  } else {
4804  // container doesn't intersect. trigger "out" event if necessary
4805  if(this.containers[i].containerCache.over) {
4806  this.containers[i]._trigger("out", event, this._uiHash(this));
4807  this.containers[i].containerCache.over = 0;
4808  }
4809  }
4810 
4811  }
4812 
4813  // if no intersecting containers found, return
4814  if(!innermostContainer) {
4815  return;
4816  }
4817 
4818  // move the item into the container if it's not there already
4819  if(this.containers.length === 1) {
4820  if (!this.containers[innermostIndex].containerCache.over) {
4821  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4822  this.containers[innermostIndex].containerCache.over = 1;
4823  }
4824  } else {
4825 
4826  //When entering a new container, we will find the item with the least distance and append our item near it
4827  dist = 10000;
4828  itemWithLeastDistance = null;
4829  floating = innermostContainer.floating || isFloating(this.currentItem);
4830  posProperty = floating ? "left" : "top";
4831  sizeProperty = floating ? "width" : "height";
4832  base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4833  for (j = this.items.length - 1; j >= 0; j--) {
4834  if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4835  continue;
4836  }
4837  if(this.items[j].item[0] === this.currentItem[0]) {
4838  continue;
4839  }
4840  if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4841  continue;
4842  }
4843  cur = this.items[j].item.offset()[posProperty];
4844  nearBottom = false;
4845  if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4846  nearBottom = true;
4847  cur += this.items[j][sizeProperty];
4848  }
4849 
4850  if(Math.abs(cur - base) < dist) {
4851  dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4852  this.direction = nearBottom ? "up": "down";
4853  }
4854  }
4855 
4856  //Check if dropOnEmpty is enabled
4857  if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4858  return;
4859  }
4860 
4861  if(this.currentContainer === this.containers[innermostIndex]) {
4862  return;
4863  }
4864 
4865  itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4866  this._trigger("change", event, this._uiHash());
4867  this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4868  this.currentContainer = this.containers[innermostIndex];
4869 
4870  //Update the placeholder
4871  this.options.placeholder.update(this.currentContainer, this.placeholder);
4872 
4873  this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4874  this.containers[innermostIndex].containerCache.over = 1;
4875  }
4876 
4877 
4878  },
4879 
4880  _createHelper: function(event) {
4881 
4882  var o = this.options,
4883  helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4884 
4885  //Add the helper to the DOM if that didn't happen already
4886  if(!helper.parents("body").length) {
4887  $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4888  }
4889 
4890  if(helper[0] === this.currentItem[0]) {
4891  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") };
4892  }
4893 
4894  if(!helper[0].style.width || o.forceHelperSize) {
4895  helper.width(this.currentItem.width());
4896  }
4897  if(!helper[0].style.height || o.forceHelperSize) {
4898  helper.height(this.currentItem.height());
4899  }
4900 
4901  return helper;
4902 
4903  },
4904 
4905  _adjustOffsetFromHelper: function(obj) {
4906  if (typeof obj === "string") {
4907  obj = obj.split(" ");
4908  }
4909  if ($.isArray(obj)) {
4910  obj = {left: +obj[0], top: +obj[1] || 0};
4911  }
4912  if ("left" in obj) {
4913  this.offset.click.left = obj.left + this.margins.left;
4914  }
4915  if ("right" in obj) {
4916  this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4917  }
4918  if ("top" in obj) {
4919  this.offset.click.top = obj.top + this.margins.top;
4920  }
4921  if ("bottom" in obj) {
4922  this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4923  }
4924  },
4925 
4926  _getParentOffset: function() {
4927 
4928 
4929  //Get the offsetParent and cache its position
4930  this.offsetParent = this.helper.offsetParent();
4931  var po = this.offsetParent.offset();
4932 
4933  // This is a special case where we need to modify a offset calculated on start, since the following happened:
4934  // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4935  // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4936  // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4937  if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4938  po.left += this.scrollParent.scrollLeft();
4939  po.top += this.scrollParent.scrollTop();
4940  }
4941 
4942  // This needs to be actually done for all browsers, since pageX/pageY includes this information
4943  // with an ugly IE fix
4944  if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4945  po = { top: 0, left: 0 };
4946  }
4947 
4948  return {
4949  top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4950  left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4951  };
4952 
4953  },
4954 
4955  _getRelativeOffset: function() {
4956 
4957  if(this.cssPosition === "relative") {
4958  var p = this.currentItem.position();
4959  return {
4960  top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4961  left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4962  };
4963  } else {
4964  return { top: 0, left: 0 };
4965  }
4966 
4967  },
4968 
4969  _cacheMargins: function() {
4970  this.margins = {
4971  left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4972  top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4973  };
4974  },
4975 
4976  _cacheHelperProportions: function() {
4977  this.helperProportions = {
4978  width: this.helper.outerWidth(),
4979  height: this.helper.outerHeight()
4980  };
4981  },
4982 
4983  _setContainment: function() {
4984 
4985  var ce, co, over,
4986  o = this.options;
4987  if(o.containment === "parent") {
4988  o.containment = this.helper[0].parentNode;
4989  }
4990  if(o.containment === "document" || o.containment === "window") {
4991  this.containment = [
4992  0 - this.offset.relative.left - this.offset.parent.left,
4993  0 - this.offset.relative.top - this.offset.parent.top,
4994  $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4995  ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4996  ];
4997  }
4998 
4999  if(!(/^(document|window|parent)$/).test(o.containment)) {
5000  ce = $(o.containment)[0];
5001  co = $(o.containment).offset();
5002  over = ($(ce).css("overflow") !== "hidden");
5003 
5004  this.containment = [
5005  co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
5006  co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
5007  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,
5008  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
5009  ];
5010  }
5011 
5012  },
5013 
5014  _convertPositionTo: function(d, pos) {
5015 
5016  if(!pos) {
5017  pos = this.position;
5018  }
5019  var mod = d === "absolute" ? 1 : -1,
5020  scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
5021  scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
5022 
5023  return {
5024  top: (
5025  pos.top + // The absolute mouse position
5026  this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5027  this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
5028  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
5029  ),
5030  left: (
5031  pos.left + // The absolute mouse position
5032  this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
5033  this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
5034  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
5035  )
5036  };
5037 
5038  },
5039 
5040  _generatePosition: function(event) {
5041 
5042  var top, left,
5043  o = this.options,
5044  pageX = event.pageX,
5045  pageY = event.pageY,
5046  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);
5047 
5048  // This is another very weird special case that only happens for relative elements:
5049  // 1. If the css position is relative
5050  // 2. and the scroll parent is the document or similar to the offset parent
5051  // we have to refresh the relative offset during the scroll so there are no jumps
5052  if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
5053  this.offset.relative = this._getRelativeOffset();
5054  }
5055 
5056  /*
5057  * - Position constraining -
5058  * Constrain the position to a mix of grid, containment.
5059  */
5060 
5061  if(this.originalPosition) { //If we are not dragging yet, we won't check for options
5062 
5063  if(this.containment) {
5064  if(event.pageX - this.offset.click.left < this.containment[0]) {
5065  pageX = this.containment[0] + this.offset.click.left;
5066  }
5067  if(event.pageY - this.offset.click.top < this.containment[1]) {
5068  pageY = this.containment[1] + this.offset.click.top;
5069  }
5070  if(event.pageX - this.offset.click.left > this.containment[2]) {
5071  pageX = this.containment[2] + this.offset.click.left;
5072  }
5073  if(event.pageY - this.offset.click.top > this.containment[3]) {
5074  pageY = this.containment[3] + this.offset.click.top;
5075  }
5076  }
5077 
5078  if(o.grid) {
5079  top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
5080  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;
5081 
5082  left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
5083  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;
5084  }
5085 
5086  }
5087 
5088  return {
5089  top: (
5090  pageY - // The absolute mouse position
5091  this.offset.click.top - // Click offset (relative to the element)
5092  this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
5093  this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
5094  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
5095  ),
5096  left: (
5097  pageX - // The absolute mouse position
5098  this.offset.click.left - // Click offset (relative to the element)
5099  this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
5100  this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
5101  ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
5102  )
5103  };
5104 
5105  },
5106 
5107  _rearrange: function(event, i, a, hardRefresh) {
5108 
5109  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));
5110 
5111  //Various things done here to improve the performance:
5112  // 1. we create a setTimeout, that calls refreshPositions
5113  // 2. on the instance, we have a counter variable, that get's higher after every append
5114  // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
5115  // 4. this lets only the last addition to the timeout stack through
5116  this.counter = this.counter ? ++this.counter : 1;
5117  var counter = this.counter;
5118 
5119  this._delay(function() {
5120  if(counter === this.counter) {
5121  this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
5122  }
5123  });
5124 
5125  },
5126 
5127  _clear: function(event, noPropagation) {
5128 
5129  this.reverting = false;
5130  // We delay all events that have to be triggered to after the point where the placeholder has been removed and
5131  // everything else normalized again
5132  var i,
5133  delayedTriggers = [];
5134 
5135  // We first have to update the dom position of the actual currentItem
5136  // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
5137  if(!this._noFinalSort && this.currentItem.parent().length) {
5138  this.placeholder.before(this.currentItem);
5139  }
5140  this._noFinalSort = null;
5141 
5142  if(this.helper[0] === this.currentItem[0]) {
5143  for(i in this._storedCSS) {
5144  if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
5145  this._storedCSS[i] = "";
5146  }
5147  }
5148  this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
5149  } else {
5150  this.currentItem.show();
5151  }
5152 
5153  if(this.fromOutside && !noPropagation) {
5154  delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
5155  }
5156  if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
5157  delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
5158  }
5159 
5160  // Check if the items Container has Changed and trigger appropriate
5161  // events.
5162  if (this !== this.currentContainer) {
5163  if(!noPropagation) {
5164  delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
5165  delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5166  delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
5167  }
5168  }
5169 
5170 
5171  //Post events to containers
5172  for (i = this.containers.length - 1; i >= 0; i--){
5173  if(!noPropagation) {
5174  delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
5175  }
5176  if(this.containers[i].containerCache.over) {
5177  delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
5178  this.containers[i].containerCache.over = 0;
5179  }
5180  }
5181 
5182  //Do what was originally in plugins
5183  if ( this.storedCursor ) {
5184  this.document.find( "body" ).css( "cursor", this.storedCursor );
5185  this.storedStylesheet.remove();
5186  }
5187  if(this._storedOpacity) {
5188  this.helper.css("opacity", this._storedOpacity);
5189  }
5190  if(this._storedZIndex) {
5191  this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
5192  }
5193 
5194  this.dragging = false;
5195  if(this.cancelHelperRemoval) {
5196  if(!noPropagation) {
5197  this._trigger("beforeStop", event, this._uiHash());
5198  for (i=0; i < delayedTriggers.length; i++) {
5199  delayedTriggers[i].call(this, event);
5200  } //Trigger all delayed events
5201  this._trigger("stop", event, this._uiHash());
5202  }
5203 
5204  this.fromOutside = false;
5205  return false;
5206  }
5207 
5208  if(!noPropagation) {
5209  this._trigger("beforeStop", event, this._uiHash());
5210  }
5211 
5212  //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
5213  this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
5214 
5215  if(this.helper[0] !== this.currentItem[0]) {
5216  this.helper.remove();
5217  }
5218  this.helper = null;
5219 
5220  if(!noPropagation) {
5221  for (i=0; i < delayedTriggers.length; i++) {
5222  delayedTriggers[i].call(this, event);
5223  } //Trigger all delayed events
5224  this._trigger("stop", event, this._uiHash());
5225  }
5226 
5227  this.fromOutside = false;
5228  return true;
5229 
5230  },
5231 
5232  _trigger: function() {
5233  if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
5234  this.cancel();
5235  }
5236  },
5237 
5238  _uiHash: function(_inst) {
5239  var inst = _inst || this;
5240  return {
5241  helper: inst.helper,
5242  placeholder: inst.placeholder || $([]),
5243  position: inst.position,
5244  originalPosition: inst.originalPosition,
5245  offset: inst.positionAbs,
5246  item: inst.currentItem,
5247  sender: _inst ? _inst.element : null
5248  };
5249  }
5250 
5251 });
5252 
5253 })(jQuery);
5254 (function( $, undefined ) {
5255 
5256 var uid = 0,
5257  hideProps = {},
5258  showProps = {};
5259 
5260 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
5261  hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
5262 showProps.height = showProps.paddingTop = showProps.paddingBottom =
5263  showProps.borderTopWidth = showProps.borderBottomWidth = "show";
5264 
5265 $.widget( "ui.accordion", {
5266  version: "1.10.3",
5267  options: {
5268  active: 0,
5269  animate: {},
5270  collapsible: false,
5271  event: "click",
5272  header: "> li > :first-child,> :not(li):even",
5273  heightStyle: "auto",
5274  icons: {
5275  activeHeader: "ui-icon-triangle-1-s",
5276  header: "ui-icon-triangle-1-e"
5277  },
5278 
5279  // callbacks
5280  activate: null,
5281  beforeActivate: null
5282  },
5283 
5284  _create: function() {
5285  var options = this.options;
5286  this.prevShow = this.prevHide = $();
5287  this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
5288  // ARIA
5289  .attr( "role", "tablist" );
5290 
5291  // don't allow collapsible: false and active: false / null
5292  if ( !options.collapsible && (options.active === false || options.active == null) ) {
5293  options.active = 0;
5294  }
5295 
5296  this._processPanels();
5297  // handle negative values
5298  if ( options.active < 0 ) {
5299  options.active += this.headers.length;
5300  }
5301  this._refresh();
5302  },
5303 
5304  _getCreateEventData: function() {
5305  return {
5306  header: this.active,
5307  panel: !this.active.length ? $() : this.active.next(),
5308  content: !this.active.length ? $() : this.active.next()
5309  };
5310  },
5311 
5312  _createIcons: function() {
5313  var icons = this.options.icons;
5314  if ( icons ) {
5315  $( "<span>" )
5316  .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
5317  .prependTo( this.headers );
5318  this.active.children( ".ui-accordion-header-icon" )
5319  .removeClass( icons.header )
5320  .addClass( icons.activeHeader );
5321  this.headers.addClass( "ui-accordion-icons" );
5322  }
5323  },
5324 
5325  _destroyIcons: function() {
5326  this.headers
5327  .removeClass( "ui-accordion-icons" )
5328  .children( ".ui-accordion-header-icon" )
5329  .remove();
5330  },
5331 
5332  _destroy: function() {
5333  var contents;
5334 
5335  // clean up main element
5336  this.element
5337  .removeClass( "ui-accordion ui-widget ui-helper-reset" )
5338  .removeAttr( "role" );
5339 
5340  // clean up headers
5341  this.headers
5342  .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5343  .removeAttr( "role" )
5344  .removeAttr( "aria-selected" )
5345  .removeAttr( "aria-controls" )
5346  .removeAttr( "tabIndex" )
5347  .each(function() {
5348  if ( /^ui-accordion/.test( this.id ) ) {
5349  this.removeAttribute( "id" );
5350  }
5351  });
5352  this._destroyIcons();
5353 
5354  // clean up content panels
5355  contents = this.headers.next()
5356  .css( "display", "" )
5357  .removeAttr( "role" )
5358  .removeAttr( "aria-expanded" )
5359  .removeAttr( "aria-hidden" )
5360  .removeAttr( "aria-labelledby" )
5361  .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
5362  .each(function() {
5363  if ( /^ui-accordion/.test( this.id ) ) {
5364  this.removeAttribute( "id" );
5365  }
5366  });
5367  if ( this.options.heightStyle !== "content" ) {
5368  contents.css( "height", "" );
5369  }
5370  },
5371 
5372  _setOption: function( key, value ) {
5373  if ( key === "active" ) {
5374  // _activate() will handle invalid values and update this.options
5375  this._activate( value );
5376  return;
5377  }
5378 
5379  if ( key === "event" ) {
5380  if ( this.options.event ) {
5381  this._off( this.headers, this.options.event );
5382  }
5383  this._setupEvents( value );
5384  }
5385 
5386  this._super( key, value );
5387 
5388  // setting collapsible: false while collapsed; open first panel
5389  if ( key === "collapsible" && !value && this.options.active === false ) {
5390  this._activate( 0 );
5391  }
5392 
5393  if ( key === "icons" ) {
5394  this._destroyIcons();
5395  if ( value ) {
5396  this._createIcons();
5397  }
5398  }
5399 
5400  // #5332 - opacity doesn't cascade to positioned elements in IE
5401  // so we need to add the disabled class to the headers and panels
5402  if ( key === "disabled" ) {
5403  this.headers.add( this.headers.next() )
5404  .toggleClass( "ui-state-disabled", !!value );
5405  }
5406  },
5407 
5408  _keydown: function( event ) {
5409  /*jshint maxcomplexity:15*/
5410  if ( event.altKey || event.ctrlKey ) {
5411  return;
5412  }
5413 
5414  var keyCode = $.ui.keyCode,
5415  length = this.headers.length,
5416  currentIndex = this.headers.index( event.target ),
5417  toFocus = false;
5418 
5419  switch ( event.keyCode ) {
5420  case keyCode.RIGHT:
5421  case keyCode.DOWN:
5422  toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5423  break;
5424  case keyCode.LEFT:
5425  case keyCode.UP:
5426  toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5427  break;
5428  case keyCode.SPACE:
5429  case keyCode.ENTER:
5430  this._eventHandler( event );
5431  break;
5432  case keyCode.HOME:
5433  toFocus = this.headers[ 0 ];
5434  break;
5435  case keyCode.END:
5436  toFocus = this.headers[ length - 1 ];
5437  break;
5438  }
5439 
5440  if ( toFocus ) {
5441  $( event.target ).attr( "tabIndex", -1 );
5442  $( toFocus ).attr( "tabIndex", 0 );
5443  toFocus.focus();
5444  event.preventDefault();
5445  }
5446  },
5447 
5448  _panelKeyDown : function( event ) {
5449  if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
5450  $( event.currentTarget ).prev().focus();
5451  }
5452  },
5453 
5454  refresh: function() {
5455  var options = this.options;
5456  this._processPanels();
5457 
5458  // was collapsed or no panel
5459  if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
5460  options.active = false;
5461  this.active = $();
5462  // active false only when collapsible is true
5463  } else if ( options.active === false ) {
5464  this._activate( 0 );
5465  // was active, but active panel is gone
5466  } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5467  // all remaining panel are disabled
5468  if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
5469  options.active = false;
5470  this.active = $();
5471  // activate previous panel
5472  } else {
5473  this._activate( Math.max( 0, options.active - 1 ) );
5474  }
5475  // was active, active panel still exists
5476  } else {
5477  // make sure active index is correct
5478  options.active = this.headers.index( this.active );
5479  }
5480 
5481  this._destroyIcons();
5482 
5483  this._refresh();
5484  },
5485 
5486  _processPanels: function() {
5487  this.headers = this.element.find( this.options.header )
5488  .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
5489 
5490  this.headers.next()
5491  .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
5492  .filter(":not(.ui-accordion-content-active)")
5493  .hide();
5494  },
5495 
5496  _refresh: function() {
5497  var maxHeight,
5498  options = this.options,
5499  heightStyle = options.heightStyle,
5500  parent = this.element.parent(),
5501  accordionId = this.accordionId = "ui-accordion-" +
5502  (this.element.attr( "id" ) || ++uid);
5503 
5504  this.active = this._findActive( options.active )
5505  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
5506  .removeClass( "ui-corner-all" );
5507  this.active.next()
5508  .addClass( "ui-accordion-content-active" )
5509  .show();
5510 
5511  this.headers
5512  .attr( "role", "tab" )
5513  .each(function( i ) {
5514  var header = $( this ),
5515  headerId = header.attr( "id" ),
5516  panel = header.next(),
5517  panelId = panel.attr( "id" );
5518  if ( !headerId ) {
5519  headerId = accordionId + "-header-" + i;
5520  header.attr( "id", headerId );
5521  }
5522  if ( !panelId ) {
5523  panelId = accordionId + "-panel-" + i;
5524  panel.attr( "id", panelId );
5525  }
5526  header.attr( "aria-controls", panelId );
5527  panel.attr( "aria-labelledby", headerId );
5528  })
5529  .next()
5530  .attr( "role", "tabpanel" );
5531 
5532  this.headers
5533  .not( this.active )
5534  .attr({
5535  "aria-selected": "false",
5536  tabIndex: -1
5537  })
5538  .next()
5539  .attr({
5540  "aria-expanded": "false",
5541  "aria-hidden": "true"
5542  })
5543  .hide();
5544 
5545  // make sure at least one header is in the tab order
5546  if ( !this.active.length ) {
5547  this.headers.eq( 0 ).attr( "tabIndex", 0 );
5548  } else {
5549  this.active.attr({
5550  "aria-selected": "true",
5551  tabIndex: 0
5552  })
5553  .next()
5554  .attr({
5555  "aria-expanded": "true",
5556  "aria-hidden": "false"
5557  });
5558  }
5559 
5560  this._createIcons();
5561 
5562  this._setupEvents( options.event );
5563 
5564  if ( heightStyle === "fill" ) {
5565  maxHeight = parent.height();
5566  this.element.siblings( ":visible" ).each(function() {
5567  var elem = $( this ),
5568  position = elem.css( "position" );
5569 
5570  if ( position === "absolute" || position === "fixed" ) {
5571  return;
5572  }
5573  maxHeight -= elem.outerHeight( true );
5574  });
5575 
5576  this.headers.each(function() {
5577  maxHeight -= $( this ).outerHeight( true );
5578  });
5579 
5580  this.headers.next()
5581  .each(function() {
5582  $( this ).height( Math.max( 0, maxHeight -
5583  $( this ).innerHeight() + $( this ).height() ) );
5584  })
5585  .css( "overflow", "auto" );
5586  } else if ( heightStyle === "auto" ) {
5587  maxHeight = 0;
5588  this.headers.next()
5589  .each(function() {
5590  maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
5591  })
5592  .height( maxHeight );
5593  }
5594  },
5595 
5596  _activate: function( index ) {
5597  var active = this._findActive( index )[ 0 ];
5598 
5599  // trying to activate the already active panel
5600  if ( active === this.active[ 0 ] ) {
5601  return;
5602  }
5603 
5604  // trying to collapse, simulate a click on the currently active header
5605  active = active || this.active[ 0 ];
5606 
5607  this._eventHandler({
5608  target: active,
5609  currentTarget: active,
5610  preventDefault: $.noop
5611  });
5612  },
5613 
5614  _findActive: function( selector ) {
5615  return typeof selector === "number" ? this.headers.eq( selector ) : $();
5616  },
5617 
5618  _setupEvents: function( event ) {
5619  var events = {
5620  keydown: "_keydown"
5621  };
5622  if ( event ) {
5623  $.each( event.split(" "), function( index, eventName ) {
5624  events[ eventName ] = "_eventHandler";
5625  });
5626  }
5627 
5628  this._off( this.headers.add( this.headers.next() ) );
5629  this._on( this.headers, events );
5630  this._on( this.headers.next(), { keydown: "_panelKeyDown" });
5631  this._hoverable( this.headers );
5632  this._focusable( this.headers );
5633  },
5634 
5635  _eventHandler: function( event ) {
5636  var options = this.options,
5637  active = this.active,
5638  clicked = $( event.currentTarget ),
5639  clickedIsActive = clicked[ 0 ] === active[ 0 ],
5640  collapsing = clickedIsActive && options.collapsible,
5641  toShow = collapsing ? $() : clicked.next(),
5642  toHide = active.next(),
5643  eventData = {
5644  oldHeader: active,
5645  oldPanel: toHide,
5646  newHeader: collapsing ? $() : clicked,
5647  newPanel: toShow
5648  };
5649 
5650  event.preventDefault();
5651 
5652  if (
5653  // click on active header, but not collapsible
5654  ( clickedIsActive && !options.collapsible ) ||
5655  // allow canceling activation
5656  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
5657  return;
5658  }
5659 
5660  options.active = collapsing ? false : this.headers.index( clicked );
5661 
5662  // when the call to ._toggle() comes after the class changes
5663  // it causes a very odd bug in IE 8 (see #6720)
5664  this.active = clickedIsActive ? $() : clicked;
5665  this._toggle( eventData );
5666 
5667  // switch classes
5668  // corner classes on the previously active header stay after the animation
5669  active.removeClass( "ui-accordion-header-active ui-state-active" );
5670  if ( options.icons ) {
5671  active.children( ".ui-accordion-header-icon" )
5672  .removeClass( options.icons.activeHeader )
5673  .addClass( options.icons.header );
5674  }
5675 
5676  if ( !clickedIsActive ) {
5677  clicked
5678  .removeClass( "ui-corner-all" )
5679  .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
5680  if ( options.icons ) {
5681  clicked.children( ".ui-accordion-header-icon" )
5682  .removeClass( options.icons.header )
5683  .addClass( options.icons.activeHeader );
5684  }
5685 
5686  clicked
5687  .next()
5688  .addClass( "ui-accordion-content-active" );
5689  }
5690  },
5691 
5692  _toggle: function( data ) {
5693  var toShow = data.newPanel,
5694  toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
5695 
5696  // handle activating a panel during the animation for another activation
5697  this.prevShow.add( this.prevHide ).stop( true, true );
5698  this.prevShow = toShow;
5699  this.prevHide = toHide;
5700 
5701  if ( this.options.animate ) {
5702  this._animate( toShow, toHide, data );
5703  } else {
5704  toHide.hide();
5705  toShow.show();
5706  this._toggleComplete( data );
5707  }
5708 
5709  toHide.attr({
5710  "aria-expanded": "false",
5711  "aria-hidden": "true"
5712  });
5713  toHide.prev().attr( "aria-selected", "false" );
5714  // if we're switching panels, remove the old header from the tab order
5715  // if we're opening from collapsed state, remove the previous header from the tab order
5716  // if we're collapsing, then keep the collapsing header in the tab order
5717  if ( toShow.length && toHide.length ) {
5718  toHide.prev().attr( "tabIndex", -1 );
5719  } else if ( toShow.length ) {
5720  this.headers.filter(function() {
5721  return $( this ).attr( "tabIndex" ) === 0;
5722  })
5723  .attr( "tabIndex", -1 );
5724  }
5725 
5726  toShow
5727  .attr({
5728  "aria-expanded": "true",
5729  "aria-hidden": "false"
5730  })
5731  .prev()
5732  .attr({
5733  "aria-selected": "true",
5734  tabIndex: 0
5735  });
5736  },
5737 
5738  _animate: function( toShow, toHide, data ) {
5739  var total, easing, duration,
5740  that = this,
5741  adjust = 0,
5742  down = toShow.length &&
5743  ( !toHide.length || ( toShow.index() < toHide.index() ) ),
5744  animate = this.options.animate || {},
5745  options = down && animate.down || animate,
5746  complete = function() {
5747  that._toggleComplete( data );
5748  };
5749 
5750  if ( typeof options === "number" ) {
5751  duration = options;
5752  }
5753  if ( typeof options === "string" ) {
5754  easing = options;
5755  }
5756  // fall back from options to animation in case of partial down settings
5757  easing = easing || options.easing || animate.easing;
5758  duration = duration || options.duration || animate.duration;
5759 
5760  if ( !toHide.length ) {
5761  return toShow.animate( showProps, duration, easing, complete );
5762  }
5763  if ( !toShow.length ) {
5764  return toHide.animate( hideProps, duration, easing, complete );
5765  }
5766 
5767  total = toShow.show().outerHeight();
5768  toHide.animate( hideProps, {
5769  duration: duration,
5770  easing: easing,
5771  step: function( now, fx ) {
5772  fx.now = Math.round( now );
5773  }
5774  });
5775  toShow
5776  .hide()
5777  .animate( showProps, {
5778  duration: duration,
5779  easing: easing,
5780  complete: complete,
5781  step: function( now, fx ) {
5782  fx.now = Math.round( now );
5783  if ( fx.prop !== "height" ) {
5784  adjust += fx.now;
5785  } else if ( that.options.heightStyle !== "content" ) {
5786  fx.now = Math.round( total - toHide.outerHeight() - adjust );
5787  adjust = 0;
5788  }
5789  }
5790  });
5791  },
5792 
5793  _toggleComplete: function( data ) {
5794  var toHide = data.oldPanel;
5795 
5796  toHide
5797  .removeClass( "ui-accordion-content-active" )
5798  .prev()
5799  .removeClass( "ui-corner-top" )
5800  .addClass( "ui-corner-all" );
5801 
5802  // Work around for rendering bug in IE (#5421)
5803  if ( toHide.length ) {
5804  toHide.parent()[0].className = toHide.parent()[0].className;
5805  }
5806 
5807  this._trigger( "activate", null, data );
5808  }
5809 });
5810 
5811 })( jQuery );
5812 (function( $, undefined ) {
5813 
5814 // used to prevent race conditions with remote data sources
5815 var requestIndex = 0;
5816 
5817 $.widget( "ui.autocomplete", {
5818  version: "1.10.3",
5819  defaultElement: "<input>",
5820  options: {
5821  appendTo: null,
5822  autoFocus: false,
5823  delay: 300,
5824  minLength: 1,
5825  position: {
5826  my: "left top",
5827  at: "left bottom",
5828  collision: "none"
5829  },
5830  source: null,
5831 
5832  // callbacks
5833  change: null,
5834  close: null,
5835  focus: null,
5836  open: null,
5837  response: null,
5838  search: null,
5839  select: null
5840  },
5841 
5842  pending: 0,
5843 
5844  _create: function() {
5845  // Some browsers only repeat keydown events, not keypress events,
5846  // so we use the suppressKeyPress flag to determine if we've already
5847  // handled the keydown event. #7269
5848  // Unfortunately the code for & in keypress is the same as the up arrow,
5849  // so we use the suppressKeyPressRepeat flag to avoid handling keypress
5850  // events when we know the keydown event was used to modify the
5851  // search term. #7799
5852  var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5853  nodeName = this.element[0].nodeName.toLowerCase(),
5854  isTextarea = nodeName === "textarea",
5855  isInput = nodeName === "input";
5856 
5857  this.isMultiLine =
5858  // Textareas are always multi-line
5859  isTextarea ? true :
5860  // Inputs are always single-line, even if inside a contentEditable element
5861  // IE also treats inputs as contentEditable
5862  isInput ? false :
5863  // All other element types are determined by whether or not they're contentEditable
5864  this.element.prop( "isContentEditable" );
5865 
5866  this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5867  this.isNewMenu = true;
5868 
5869  this.element
5870  .addClass( "ui-autocomplete-input" )
5871  .attr( "autocomplete", "off" );
5872 
5873  this._on( this.element, {
5874  keydown: function( event ) {
5875  /*jshint maxcomplexity:15*/
5876  if ( this.element.prop( "readOnly" ) ) {
5877  suppressKeyPress = true;
5878  suppressInput = true;
5879  suppressKeyPressRepeat = true;
5880  return;
5881  }
5882 
5883  suppressKeyPress = false;
5884  suppressInput = false;
5885  suppressKeyPressRepeat = false;
5886  var keyCode = $.ui.keyCode;
5887  switch( event.keyCode ) {
5888  case keyCode.PAGE_UP:
5889  suppressKeyPress = true;
5890  this._move( "previousPage", event );
5891  break;
5892  case keyCode.PAGE_DOWN:
5893  suppressKeyPress = true;
5894  this._move( "nextPage", event );
5895  break;
5896  case keyCode.UP:
5897  suppressKeyPress = true;
5898  this._keyEvent( "previous", event );
5899  break;
5900  case keyCode.DOWN:
5901  suppressKeyPress = true;
5902  this._keyEvent( "next", event );
5903  break;
5904  case keyCode.ENTER:
5905  case keyCode.NUMPAD_ENTER:
5906  // when menu is open and has focus
5907  if ( this.menu.active ) {
5908  // #6055 - Opera still allows the keypress to occur
5909  // which causes forms to submit
5910  suppressKeyPress = true;
5911  event.preventDefault();
5912  this.menu.select( event );
5913  }
5914  break;
5915  case keyCode.TAB:
5916  if ( this.menu.active ) {
5917  this.menu.select( event );
5918  }
5919  break;
5920  case keyCode.ESCAPE:
5921  if ( this.menu.element.is( ":visible" ) ) {
5922  this._value( this.term );
5923  this.close( event );
5924  // Different browsers have different default behavior for escape
5925  // Single press can mean undo or clear
5926  // Double press in IE means clear the whole form
5927  event.preventDefault();
5928  }
5929  break;
5930  default:
5931  suppressKeyPressRepeat = true;
5932  // search timeout should be triggered before the input value is changed
5933  this._searchTimeout( event );
5934  break;
5935  }
5936  },
5937  keypress: function( event ) {
5938  if ( suppressKeyPress ) {
5939  suppressKeyPress = false;
5940  if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5941  event.preventDefault();
5942  }
5943  return;
5944  }
5945  if ( suppressKeyPressRepeat ) {
5946  return;
5947  }
5948 
5949  // replicate some key handlers to allow them to repeat in Firefox and Opera
5950  var keyCode = $.ui.keyCode;
5951  switch( event.keyCode ) {
5952  case keyCode.PAGE_UP:
5953  this._move( "previousPage", event );
5954  break;
5955  case keyCode.PAGE_DOWN:
5956  this._move( "nextPage", event );
5957  break;
5958  case keyCode.UP:
5959  this._keyEvent( "previous", event );
5960  break;
5961  case keyCode.DOWN:
5962  this._keyEvent( "next", event );
5963  break;
5964  }
5965  },
5966  input: function( event ) {
5967  if ( suppressInput ) {
5968  suppressInput = false;
5969  event.preventDefault();
5970  return;
5971  }
5972  this._searchTimeout( event );
5973  },
5974  focus: function() {
5975  this.selectedItem = null;
5976  this.previous = this._value();
5977  },
5978  blur: function( event ) {
5979  if ( this.cancelBlur ) {
5980  delete this.cancelBlur;
5981  return;
5982  }
5983 
5984  clearTimeout( this.searching );
5985  this.close( event );
5986  this._change( event );
5987  }
5988  });
5989 
5990  this._initSource();
5991  this.menu = $( "<ul>" )
5992  .addClass( "ui-autocomplete ui-front" )
5993  .appendTo( this._appendTo() )
5994  .menu({
5995  // disable ARIA support, the live region takes care of that
5996  role: null
5997  })
5998  .hide()
5999  .data( "ui-menu" );
6000 
6001  this._on( this.menu.element, {
6002  mousedown: function( event ) {
6003  // prevent moving focus out of the text field
6004  event.preventDefault();
6005 
6006  // IE doesn't prevent moving focus even with event.preventDefault()
6007  // so we set a flag to know when we should ignore the blur event
6008  this.cancelBlur = true;
6009  this._delay(function() {
6010  delete this.cancelBlur;
6011  });
6012 
6013  // clicking on the scrollbar causes focus to shift to the body
6014  // but we can't detect a mouseup or a click immediately afterward
6015  // so we have to track the next mousedown and close the menu if
6016  // the user clicks somewhere outside of the autocomplete
6017  var menuElement = this.menu.element[ 0 ];
6018  if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6019  this._delay(function() {
6020  var that = this;
6021  this.document.one( "mousedown", function( event ) {
6022  if ( event.target !== that.element[ 0 ] &&
6023  event.target !== menuElement &&
6024  !$.contains( menuElement, event.target ) ) {
6025  that.close();
6026  }
6027  });
6028  });
6029  }
6030  },
6031  menufocus: function( event, ui ) {
6032  // support: Firefox
6033  // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6034  if ( this.isNewMenu ) {
6035  this.isNewMenu = false;
6036  if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6037  this.menu.blur();
6038 
6039  this.document.one( "mousemove", function() {
6040  $( event.target ).trigger( event.originalEvent );
6041  });
6042 
6043  return;
6044  }
6045  }
6046 
6047  var item = ui.item.data( "ui-autocomplete-item" );
6048  if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6049  // use value to match what will end up in the input, if it was a key event
6050  if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6051  this._value( item.value );
6052  }
6053  } else {
6054  // Normally the input is populated with the item's value as the
6055  // menu is navigated, causing screen readers to notice a change and
6056  // announce the item. Since the focus event was canceled, this doesn't
6057  // happen, so we update the live region so that screen readers can
6058  // still notice the change and announce it.
6059  this.liveRegion.text( item.value );
6060  }
6061  },
6062  menuselect: function( event, ui ) {
6063  var item = ui.item.data( "ui-autocomplete-item" ),
6064  previous = this.previous;
6065 
6066  // only trigger when focus was lost (click on menu)
6067  if ( this.element[0] !== this.document[0].activeElement ) {
6068  this.element.focus();
6069  this.previous = previous;
6070  // #6109 - IE triggers two focus events and the second
6071  // is asynchronous, so we need to reset the previous
6072  // term synchronously and asynchronously :-(
6073  this._delay(function() {
6074  this.previous = previous;
6075  this.selectedItem = item;
6076  });
6077  }
6078 
6079  if ( false !== this._trigger( "select", event, { item: item } ) ) {
6080  this._value( item.value );
6081  }
6082  // reset the term after the select event
6083  // this allows custom select handling to work properly
6084  this.term = this._value();
6085 
6086  this.close( event );
6087  this.selectedItem = item;
6088  }
6089  });
6090 
6091  this.liveRegion = $( "<span>", {
6092  role: "status",
6093  "aria-live": "polite"
6094  })
6095  .addClass( "ui-helper-hidden-accessible" )
6096  .insertBefore( this.element );
6097 
6098  // turning off autocomplete prevents the browser from remembering the
6099  // value when navigating through history, so we re-enable autocomplete
6100  // if the page is unloaded before the widget is destroyed. #7790
6101  this._on( this.window, {
6102  beforeunload: function() {
6103  this.element.removeAttr( "autocomplete" );
6104  }
6105  });
6106  },
6107 
6108  _destroy: function() {
6109  clearTimeout( this.searching );
6110  this.element
6111  .removeClass( "ui-autocomplete-input" )
6112  .removeAttr( "autocomplete" );
6113  this.menu.element.remove();
6114  this.liveRegion.remove();
6115  },
6116 
6117  _setOption: function( key, value ) {
6118  this._super( key, value );
6119  if ( key === "source" ) {
6120  this._initSource();
6121  }
6122  if ( key === "appendTo" ) {
6123  this.menu.element.appendTo( this._appendTo() );
6124  }
6125  if ( key === "disabled" && value && this.xhr ) {
6126  this.xhr.abort();
6127  }
6128  },
6129 
6130  _appendTo: function() {
6131  var element = this.options.appendTo;
6132 
6133  if ( element ) {
6134  element = element.jquery || element.nodeType ?
6135  $( element ) :
6136  this.document.find( element ).eq( 0 );
6137  }
6138 
6139  if ( !element ) {
6140  element = this.element.closest( ".ui-front" );
6141  }
6142 
6143  if ( !element.length ) {
6144  element = this.document[0].body;
6145  }
6146 
6147  return element;
6148  },
6149 
6150  _initSource: function() {
6151  var array, url,
6152  that = this;
6153  if ( $.isArray(this.options.source) ) {
6154  array = this.options.source;
6155  this.source = function( request, response ) {
6156  response( $.ui.autocomplete.filter( array, request.term ) );
6157  };
6158  } else if ( typeof this.options.source === "string" ) {
6159  url = this.options.source;
6160  this.source = function( request, response ) {
6161  if ( that.xhr ) {
6162  that.xhr.abort();
6163  }
6164  that.xhr = $.ajax({
6165  url: url,
6166  data: request,
6167  dataType: "json",
6168  success: function( data ) {
6169  response( data );
6170  },
6171  error: function() {
6172  response( [] );
6173  }
6174  });
6175  };
6176  } else {
6177  this.source = this.options.source;
6178  }
6179  },
6180 
6181  _searchTimeout: function( event ) {
6182  clearTimeout( this.searching );
6183  this.searching = this._delay(function() {
6184  // only search if the value has changed
6185  if ( this.term !== this._value() ) {
6186  this.selectedItem = null;
6187  this.search( null, event );
6188  }
6189  }, this.options.delay );
6190  },
6191 
6192  search: function( value, event ) {
6193  value = value != null ? value : this._value();
6194 
6195  // always save the actual value, not the one passed as an argument
6196  this.term = this._value();
6197 
6198  if ( value.length < this.options.minLength ) {
6199  return this.close( event );
6200  }
6201 
6202  if ( this._trigger( "search", event ) === false ) {
6203  return;
6204  }
6205 
6206  return this._search( value );
6207  },
6208 
6209  _search: function( value ) {
6210  this.pending++;
6211  this.element.addClass( "ui-autocomplete-loading" );
6212  this.cancelSearch = false;
6213 
6214  this.source( { term: value }, this._response() );
6215  },
6216 
6217  _response: function() {
6218  var that = this,
6219  index = ++requestIndex;
6220 
6221  return function( content ) {
6222  if ( index === requestIndex ) {
6223  that.__response( content );
6224  }
6225 
6226  that.pending--;
6227  if ( !that.pending ) {
6228  that.element.removeClass( "ui-autocomplete-loading" );
6229  }
6230  };
6231  },
6232 
6233  __response: function( content ) {
6234  if ( content ) {
6235  content = this._normalize( content );
6236  }
6237  this._trigger( "response", null, { content: content } );
6238  if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6239  this._suggest( content );
6240  this._trigger( "open" );
6241  } else {
6242  // use ._close() instead of .close() so we don't cancel future searches
6243  this._close();
6244  }
6245  },
6246 
6247  close: function( event ) {
6248  this.cancelSearch = true;
6249  this._close( event );
6250  },
6251 
6252  _close: function( event ) {
6253  if ( this.menu.element.is( ":visible" ) ) {
6254  this.menu.element.hide();
6255  this.menu.blur();
6256  this.isNewMenu = true;
6257  this._trigger( "close", event );
6258  }
6259  },
6260 
6261  _change: function( event ) {
6262  if ( this.previous !== this._value() ) {
6263  this._trigger( "change", event, { item: this.selectedItem } );
6264  }
6265  },
6266 
6267  _normalize: function( items ) {
6268  // assume all items have the right format when the first item is complete
6269  if ( items.length && items[0].label && items[0].value ) {
6270  return items;
6271  }
6272  return $.map( items, function( item ) {
6273  if ( typeof item === "string" ) {
6274  return {
6275  label: item,
6276  value: item
6277  };
6278  }
6279  return $.extend({
6280  label: item.label || item.value,
6281  value: item.value || item.label
6282  }, item );
6283  });
6284  },
6285 
6286  _suggest: function( items ) {
6287  var ul = this.menu.element.empty();
6288  this._renderMenu( ul, items );
6289  this.isNewMenu = true;
6290  this.menu.refresh();
6291 
6292  // size and position menu
6293  ul.show();
6294  this._resizeMenu();
6295  ul.position( $.extend({
6296  of: this.element
6297  }, this.options.position ));
6298 
6299  if ( this.options.autoFocus ) {
6300  this.menu.next();
6301  }
6302  },
6303 
6304  _resizeMenu: function() {
6305  var ul = this.menu.element;
6306  ul.outerWidth( Math.max(
6307  // Firefox wraps long text (possibly a rounding bug)
6308  // so we add 1px to avoid the wrapping (#7513)
6309  ul.width( "" ).outerWidth() + 1,
6310  this.element.outerWidth()
6311  ) );
6312  },
6313 
6314  _renderMenu: function( ul, items ) {
6315  var that = this;
6316  $.each( items, function( index, item ) {
6317  that._renderItemData( ul, item );
6318  });
6319  },
6320 
6321  _renderItemData: function( ul, item ) {
6322  return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6323  },
6324 
6325  _renderItem: function( ul, item ) {
6326  return $( "<li>" )
6327  .append( $( "<a>" ).text( item.label ) )
6328  .appendTo( ul );
6329  },
6330 
6331  _move: function( direction, event ) {
6332  if ( !this.menu.element.is( ":visible" ) ) {
6333  this.search( null, event );
6334  return;
6335  }
6336  if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6337  this.menu.isLastItem() && /^next/.test( direction ) ) {
6338  this._value( this.term );
6339  this.menu.blur();
6340  return;
6341  }
6342  this.menu[ direction ]( event );
6343  },
6344 
6345  widget: function() {
6346  return this.menu.element;
6347  },
6348 
6349  _value: function() {
6350  return this.valueMethod.apply( this.element, arguments );
6351  },
6352 
6353  _keyEvent: function( keyEvent, event ) {
6354  if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6355  this._move( keyEvent, event );
6356 
6357  // prevents moving cursor to beginning/end of the text field in some browsers
6358  event.preventDefault();
6359  }
6360  }
6361 });
6362 
6363 $.extend( $.ui.autocomplete, {
6364  escapeRegex: function( value ) {
6365  return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
6366  },
6367  filter: function(array, term) {
6368  var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6369  return $.grep( array, function(value) {
6370  return matcher.test( value.label || value.value || value );
6371  });
6372  }
6373 });
6374 
6375 
6376 // live region extension, adding a `messages` option
6377 // NOTE: This is an experimental API. We are still investigating
6378 // a full solution for string manipulation and internationalization.
6379 $.widget( "ui.autocomplete", $.ui.autocomplete, {
6380  options: {
6381  messages: {
6382  noResults: "No search results.",
6383  results: function( amount ) {
6384  return amount + ( amount > 1 ? " results are" : " result is" ) +
6385  " available, use up and down arrow keys to navigate.";
6386  }
6387  }
6388  },
6389 
6390  __response: function( content ) {
6391  var message;
6392  this._superApply( arguments );
6393  if ( this.options.disabled || this.cancelSearch ) {
6394  return;
6395  }
6396  if ( content && content.length ) {
6397  message = this.options.messages.results( content.length );
6398  } else {
6399  message = this.options.messages.noResults;
6400  }
6401  this.liveRegion.text( message );
6402  }
6403 });
6404 
6405 }( jQuery ));
6406 (function( $, undefined ) {
6407 
6408 var lastActive, startXPos, startYPos, clickDragged,
6409  baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6410  stateClasses = "ui-state-hover ui-state-active ",
6411  typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
6412  formResetHandler = function() {
6413  var form = $( this );
6414  setTimeout(function() {
6415  form.find( ":ui-button" ).button( "refresh" );
6416  }, 1 );
6417  },
6418  radioGroup = function( radio ) {
6419  var name = radio.name,
6420  form = radio.form,
6421  radios = $( [] );
6422  if ( name ) {
6423  name = name.replace( /'/g, "\\'" );
6424  if ( form ) {
6425  radios = $( form ).find( "[name='" + name + "']" );
6426  } else {
6427  radios = $( "[name='" + name + "']", radio.ownerDocument )
6428  .filter(function() {
6429  return !this.form;
6430  });
6431  }
6432  }
6433  return radios;
6434  };
6435 
6436 $.widget( "ui.button", {
6437  version: "1.10.3",
6438  defaultElement: "<button>",
6439  options: {
6440  disabled: null,
6441  text: true,
6442  label: null,
6443  icons: {
6444  primary: null,
6445  secondary: null
6446  }
6447  },
6448  _create: function() {
6449  this.element.closest( "form" )
6450  .unbind( "reset" + this.eventNamespace )
6451  .bind( "reset" + this.eventNamespace, formResetHandler );
6452 
6453  if ( typeof this.options.disabled !== "boolean" ) {
6454  this.options.disabled = !!this.element.prop( "disabled" );
6455  } else {
6456  this.element.prop( "disabled", this.options.disabled );
6457  }
6458 
6459  this._determineButtonType();
6460  this.hasTitle = !!this.buttonElement.attr( "title" );
6461 
6462  var that = this,
6463  options = this.options,
6464  toggleButton = this.type === "checkbox" || this.type === "radio",
6465  activeClass = !toggleButton ? "ui-state-active" : "",
6466  focusClass = "ui-state-focus";
6467 
6468  if ( options.label === null ) {
6469  options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
6470  }
6471 
6472  this._hoverable( this.buttonElement );
6473 
6474  this.buttonElement
6475  .addClass( baseClasses )
6476  .attr( "role", "button" )
6477  .bind( "mouseenter" + this.eventNamespace, function() {
6478  if ( options.disabled ) {
6479  return;
6480  }
6481  if ( this === lastActive ) {
6482  $( this ).addClass( "ui-state-active" );
6483  }
6484  })
6485  .bind( "mouseleave" + this.eventNamespace, function() {
6486  if ( options.disabled ) {
6487  return;
6488  }
6489  $( this ).removeClass( activeClass );
6490  })
6491  .bind( "click" + this.eventNamespace, function( event ) {
6492  if ( options.disabled ) {
6493  event.preventDefault();
6494  event.stopImmediatePropagation();
6495  }
6496  });
6497 
6498  this.element
6499  .bind( "focus" + this.eventNamespace, function() {
6500  // no need to check disabled, focus won't be triggered anyway
6501  that.buttonElement.addClass( focusClass );
6502  })
6503  .bind( "blur" + this.eventNamespace, function() {
6504  that.buttonElement.removeClass( focusClass );
6505  });
6506 
6507  if ( toggleButton ) {
6508  this.element.bind( "change" + this.eventNamespace, function() {
6509  if ( clickDragged ) {
6510  return;
6511  }
6512  that.refresh();
6513  });
6514  // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6515  // prevents issue where button state changes but checkbox/radio checked state
6516  // does not in Firefox (see ticket #6970)
6517  this.buttonElement
6518  .bind( "mousedown" + this.eventNamespace, function( event ) {
6519  if ( options.disabled ) {
6520  return;
6521  }
6522  clickDragged = false;
6523  startXPos = event.pageX;
6524  startYPos = event.pageY;
6525  })
6526  .bind( "mouseup" + this.eventNamespace, function( event ) {
6527  if ( options.disabled ) {
6528  return;
6529  }
6530  if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6531  clickDragged = true;
6532  }
6533  });
6534  }
6535 
6536  if ( this.type === "checkbox" ) {
6537  this.buttonElement.bind( "click" + this.eventNamespace, function() {
6538  if ( options.disabled || clickDragged ) {
6539  return false;
6540  }
6541  });
6542  } else if ( this.type === "radio" ) {
6543  this.buttonElement.bind( "click" + this.eventNamespace, function() {
6544  if ( options.disabled || clickDragged ) {
6545  return false;
6546  }
6547  $( this ).addClass( "ui-state-active" );
6548  that.buttonElement.attr( "aria-pressed", "true" );
6549 
6550  var radio = that.element[ 0 ];
6551  radioGroup( radio )
6552  .not( radio )
6553  .map(function() {
6554  return $( this ).button( "widget" )[ 0 ];
6555  })
6556  .removeClass( "ui-state-active" )
6557  .attr( "aria-pressed", "false" );
6558  });
6559  } else {
6560  this.buttonElement
6561  .bind( "mousedown" + this.eventNamespace, function() {
6562  if ( options.disabled ) {
6563  return false;
6564  }
6565  $( this ).addClass( "ui-state-active" );
6566  lastActive = this;
6567  that.document.one( "mouseup", function() {
6568  lastActive = null;
6569  });
6570  })
6571  .bind( "mouseup" + this.eventNamespace, function() {
6572  if ( options.disabled ) {
6573  return false;
6574  }
6575  $( this ).removeClass( "ui-state-active" );
6576  })
6577  .bind( "keydown" + this.eventNamespace, function(event) {
6578  if ( options.disabled ) {
6579  return false;
6580  }
6581  if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
6582  $( this ).addClass( "ui-state-active" );
6583  }
6584  })
6585  // see #8559, we bind to blur here in case the button element loses
6586  // focus between keydown and keyup, it would be left in an "active" state
6587  .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
6588  $( this ).removeClass( "ui-state-active" );
6589  });
6590 
6591  if ( this.buttonElement.is("a") ) {
6592  this.buttonElement.keyup(function(event) {
6593  if ( event.keyCode === $.ui.keyCode.SPACE ) {
6594  // TODO pass through original event correctly (just as 2nd argument doesn't work)
6595  $( this ).click();
6596  }
6597  });
6598  }
6599  }
6600 
6601  // TODO: pull out $.Widget's handling for the disabled option into
6602  // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
6603  // be overridden by individual plugins
6604  this._setOption( "disabled", options.disabled );
6605  this._resetButton();
6606  },
6607 
6608  _determineButtonType: function() {
6609  var ancestor, labelSelector, checked;
6610 
6611  if ( this.element.is("[type=checkbox]") ) {
6612  this.type = "checkbox";
6613  } else if ( this.element.is("[type=radio]") ) {
6614  this.type = "radio";
6615  } else if ( this.element.is("input") ) {
6616  this.type = "input";
6617  } else {
6618  this.type = "button";
6619  }
6620 
6621  if ( this.type === "checkbox" || this.type === "radio" ) {
6622  // we don't search against the document in case the element
6623  // is disconnected from the DOM
6624  ancestor = this.element.parents().last();
6625  labelSelector = "label[for='" + this.element.attr("id") + "']";
6626  this.buttonElement = ancestor.find( labelSelector );
6627  if ( !this.buttonElement.length ) {
6628  ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
6629  this.buttonElement = ancestor.filter( labelSelector );
6630  if ( !this.buttonElement.length ) {
6631  this.buttonElement = ancestor.find( labelSelector );
6632  }
6633  }
6634  this.element.addClass( "ui-helper-hidden-accessible" );
6635 
6636  checked = this.element.is( ":checked" );
6637  if ( checked ) {
6638  this.buttonElement.addClass( "ui-state-active" );
6639  }
6640  this.buttonElement.prop( "aria-pressed", checked );
6641  } else {
6642  this.buttonElement = this.element;
6643  }
6644  },
6645 
6646  widget: function() {
6647  return this.buttonElement;
6648  },
6649 
6650  _destroy: function() {
6651  this.element
6652  .removeClass( "ui-helper-hidden-accessible" );
6653  this.buttonElement
6654  .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
6655  .removeAttr( "role" )
6656  .removeAttr( "aria-pressed" )
6657  .html( this.buttonElement.find(".ui-button-text").html() );
6658 
6659  if ( !this.hasTitle ) {
6660  this.buttonElement.removeAttr( "title" );
6661  }
6662  },
6663 
6664  _setOption: function( key, value ) {
6665  this._super( key, value );
6666  if ( key === "disabled" ) {
6667  if ( value ) {
6668  this.element.prop( "disabled", true );
6669  } else {
6670  this.element.prop( "disabled", false );
6671  }
6672  return;
6673  }
6674  this._resetButton();
6675  },
6676 
6677  refresh: function() {
6678  //See #8237 & #8828
6679  var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
6680 
6681  if ( isDisabled !== this.options.disabled ) {
6682  this._setOption( "disabled", isDisabled );
6683  }
6684  if ( this.type === "radio" ) {
6685  radioGroup( this.element[0] ).each(function() {
6686  if ( $( this ).is( ":checked" ) ) {
6687  $( this ).button( "widget" )
6688  .addClass( "ui-state-active" )
6689  .attr( "aria-pressed", "true" );
6690  } else {
6691  $( this ).button( "widget" )
6692  .removeClass( "ui-state-active" )
6693  .attr( "aria-pressed", "false" );
6694  }
6695  });
6696  } else if ( this.type === "checkbox" ) {
6697  if ( this.element.is( ":checked" ) ) {
6698  this.buttonElement
6699  .addClass( "ui-state-active" )
6700  .attr( "aria-pressed", "true" );
6701  } else {
6702  this.buttonElement
6703  .removeClass( "ui-state-active" )
6704  .attr( "aria-pressed", "false" );
6705  }
6706  }
6707  },
6708 
6709  _resetButton: function() {
6710  if ( this.type === "input" ) {
6711  if ( this.options.label ) {
6712  this.element.val( this.options.label );
6713  }
6714  return;
6715  }
6716  var buttonElement = this.buttonElement.removeClass( typeClasses ),
6717  buttonText = $( "<span></span>", this.document[0] )
6718  .addClass( "ui-button-text" )
6719  .html( this.options.label )
6720  .appendTo( buttonElement.empty() )
6721  .text(),
6722  icons = this.options.icons,
6723  multipleIcons = icons.primary && icons.secondary,
6724  buttonClasses = [];
6725 
6726  if ( icons.primary || icons.secondary ) {
6727  if ( this.options.text ) {
6728  buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
6729  }
6730 
6731  if ( icons.primary ) {
6732  buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
6733  }
6734 
6735  if ( icons.secondary ) {
6736  buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
6737  }
6738 
6739  if ( !this.options.text ) {
6740  buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
6741 
6742  if ( !this.hasTitle ) {
6743  buttonElement.attr( "title", $.trim( buttonText ) );
6744  }
6745  }
6746  } else {
6747  buttonClasses.push( "ui-button-text-only" );
6748  }
6749  buttonElement.addClass( buttonClasses.join( " " ) );
6750  }
6751 });
6752 
6753 $.widget( "ui.buttonset", {
6754  version: "1.10.3",
6755  options: {
6756  items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
6757  },
6758 
6759  _create: function() {
6760  this.element.addClass( "ui-buttonset" );
6761  },
6762 
6763  _init: function() {
6764  this.refresh();
6765  },
6766 
6767  _setOption: function( key, value ) {
6768  if ( key === "disabled" ) {
6769  this.buttons.button( "option", key, value );
6770  }
6771 
6772  this._super( key, value );
6773  },
6774 
6775  refresh: function() {
6776  var rtl = this.element.css( "direction" ) === "rtl";
6777 
6778  this.buttons = this.element.find( this.options.items )
6779  .filter( ":ui-button" )
6780  .button( "refresh" )
6781  .end()
6782  .not( ":ui-button" )
6783  .button()
6784  .end()
6785  .map(function() {
6786  return $( this ).button( "widget" )[ 0 ];
6787  })
6788  .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
6789  .filter( ":first" )
6790  .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
6791  .end()
6792  .filter( ":last" )
6793  .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
6794  .end()
6795  .end();
6796  },
6797 
6798  _destroy: function() {
6799  this.element.removeClass( "ui-buttonset" );
6800  this.buttons
6801  .map(function() {
6802  return $( this ).button( "widget" )[ 0 ];
6803  })
6804  .removeClass( "ui-corner-left ui-corner-right" )
6805  .end()
6806  .button( "destroy" );
6807  }
6808 });
6809 
6810 }( jQuery ) );
6811 (function( $, undefined ) {
6812 
6813 $.extend($.ui, { datepicker: { version: "1.10.3" } });
6814 
6815 var PROP_NAME = "datepicker",
6816  instActive;
6817 
6818 /* Date picker manager.
6819  Use the singleton instance of this class, $.datepicker, to interact with the date picker.
6820  Settings for (groups of) date pickers are maintained in an instance object,
6821  allowing multiple different settings on the same page. */
6822 
6823 function Datepicker() {
6824  this._curInst = null; // The current instance in use
6825  this._keyEvent = false; // If the last event was a key event
6826  this._disabledInputs = []; // List of date picker inputs that have been disabled
6827  this._datepickerShowing = false; // True if the popup picker is showing , false if not
6828  this._inDialog = false; // True if showing within a "dialog", false if not
6829  this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
6830  this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
6831  this._appendClass = "ui-datepicker-append"; // The name of the append marker class
6832  this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
6833  this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
6834  this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
6835  this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
6836  this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
6837  this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
6838  this.regional = []; // Available regional settings, indexed by language code
6839  this.regional[""] = { // Default regional settings
6840  closeText: "Done", // Display text for close link
6841  prevText: "Prev", // Display text for previous month link
6842  nextText: "Next", // Display text for next month link
6843  currentText: "Today", // Display text for current month link
6844  monthNames: ["January","February","March","April","May","June",
6845  "July","August","September","October","November","December"], // Names of months for drop-down and formatting
6846  monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
6847  dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
6848  dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
6849  dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
6850  weekHeader: "Wk", // Column header for week of the year
6851  dateFormat: "mm/dd/yy", // See format options on parseDate
6852  firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
6853  isRTL: false, // True if right-to-left language, false if left-to-right
6854  showMonthAfterYear: false, // True if the year select precedes month, false for month then year
6855  yearSuffix: "" // Additional text to append to the year in the month headers
6856  };
6857  this._defaults = { // Global defaults for all the date picker instances
6858  showOn: "focus", // "focus" for popup on focus,
6859  // "button" for trigger button, or "both" for either
6860  showAnim: "fadeIn", // Name of jQuery animation for popup
6861  showOptions: {}, // Options for enhanced animations
6862  defaultDate: null, // Used when field is blank: actual date,
6863  // +/-number for offset from today, null for today
6864  appendText: "", // Display text following the input box, e.g. showing the format
6865  buttonText: "...", // Text for trigger button
6866  buttonImage: "", // URL for trigger button image
6867  buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
6868  hideIfNoPrevNext: false, // True to hide next/previous month links
6869  // if not applicable, false to just disable them
6870  navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
6871  gotoCurrent: false, // True if today link goes back to current selection instead
6872  changeMonth: false, // True if month can be selected directly, false if only prev/next
6873  changeYear: false, // True if year can be selected directly, false if only prev/next
6874  yearRange: "c-10:c+10", // Range of years to display in drop-down,
6875  // either relative to today's year (-nn:+nn), relative to currently displayed year
6876  // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
6877  showOtherMonths: false, // True to show dates in other months, false to leave blank
6878  selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
6879  showWeek: false, // True to show week of the year, false to not show it
6880  calculateWeek: this.iso8601Week, // How to calculate the week of the year,
6881  // takes a Date and returns the number of the week for it
6882  shortYearCutoff: "+10", // Short year values < this are in the current century,
6883  // > this are in the previous century,
6884  // string value starting with "+" for current year + value
6885  minDate: null, // The earliest selectable date, or null for no limit
6886  maxDate: null, // The latest selectable date, or null for no limit
6887  duration: "fast", // Duration of display/closure
6888  beforeShowDay: null, // Function that takes a date and returns an array with
6889  // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
6890  // [2] = cell title (optional), e.g. $.datepicker.noWeekends
6891  beforeShow: null, // Function that takes an input field and
6892  // returns a set of custom settings for the date picker
6893  onSelect: null, // Define a callback function when a date is selected
6894  onChangeMonthYear: null, // Define a callback function when the month or year is changed
6895  onClose: null, // Define a callback function when the datepicker is closed
6896  numberOfMonths: 1, // Number of months to show at a time
6897  showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
6898  stepMonths: 1, // Number of months to step back/forward
6899  stepBigMonths: 12, // Number of months to step back/forward for the big links
6900  altField: "", // Selector for an alternate field to store selected dates into
6901  altFormat: "", // The date format to use for the alternate field
6902  constrainInput: true, // The input is constrained by the current date format
6903  showButtonPanel: false, // True to show button panel, false to not show it
6904  autoSize: false, // True to size the input for the date format, false to leave as is
6905  disabled: false // The initial disabled state
6906  };
6907  $.extend(this._defaults, this.regional[""]);
6908  this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
6909 }
6910 
6911 $.extend(Datepicker.prototype, {
6912  /* Class name added to elements to indicate already configured with a date picker. */
6913  markerClassName: "hasDatepicker",
6914 
6915  //Keep track of the maximum number of rows displayed (see #7043)
6916  maxRows: 4,
6917 
6918  // TODO rename to "widget" when switching to widget factory
6919  _widgetDatepicker: function() {
6920  return this.dpDiv;
6921  },
6922 
6923  /* Override the default settings for all instances of the date picker.
6924  * @param settings object - the new settings to use as defaults (anonymous object)
6925  * @return the manager object
6926  */
6927  setDefaults: function(settings) {
6928  extendRemove(this._defaults, settings || {});
6929  return this;
6930  },
6931 
6932  /* Attach the date picker to a jQuery selection.
6933  * @param target element - the target input field or division or span
6934  * @param settings object - the new settings to use for this date picker instance (anonymous)
6935  */
6936  _attachDatepicker: function(target, settings) {
6937  var nodeName, inline, inst;
6938  nodeName = target.nodeName.toLowerCase();
6939  inline = (nodeName === "div" || nodeName === "span");
6940  if (!target.id) {
6941  this.uuid += 1;
6942  target.id = "dp" + this.uuid;
6943  }
6944  inst = this._newInst($(target), inline);
6945  inst.settings = $.extend({}, settings || {});
6946  if (nodeName === "input") {
6947  this._connectDatepicker(target, inst);
6948  } else if (inline) {
6949  this._inlineDatepicker(target, inst);
6950  }
6951  },
6952 
6953  /* Create a new instance object. */
6954  _newInst: function(target, inline) {
6955  var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
6956  return {id: id, input: target, // associated target
6957  selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
6958  drawMonth: 0, drawYear: 0, // month being drawn
6959  inline: inline, // is datepicker inline or not
6960  dpDiv: (!inline ? this.dpDiv : // presentation div
6961  bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
6962  },
6963 
6964  /* Attach the date picker to an input field. */
6965  _connectDatepicker: function(target, inst) {
6966  var input = $(target);
6967  inst.append = $([]);
6968  inst.trigger = $([]);
6969  if (input.hasClass(this.markerClassName)) {
6970  return;
6971  }
6972  this._attachments(input, inst);
6973  input.addClass(this.markerClassName).keydown(this._doKeyDown).
6974  keypress(this._doKeyPress).keyup(this._doKeyUp);
6975  this._autoSize(inst);
6976  $.data(target, PROP_NAME, inst);
6977  //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
6978  if( inst.settings.disabled ) {
6979  this._disableDatepicker( target );
6980  }
6981  },
6982 
6983  /* Make attachments based on settings. */
6984  _attachments: function(input, inst) {
6985  var showOn, buttonText, buttonImage,
6986  appendText = this._get(inst, "appendText"),
6987  isRTL = this._get(inst, "isRTL");
6988 
6989  if (inst.append) {
6990  inst.append.remove();
6991  }
6992  if (appendText) {
6993  inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
6994  input[isRTL ? "before" : "after"](inst.append);
6995  }
6996 
6997  input.unbind("focus", this._showDatepicker);
6998 
6999  if (inst.trigger) {
7000  inst.trigger.remove();
7001  }
7002 
7003  showOn = this._get(inst, "showOn");
7004  if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7005  input.focus(this._showDatepicker);
7006  }
7007  if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7008  buttonText = this._get(inst, "buttonText");
7009  buttonImage = this._get(inst, "buttonImage");
7010  inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7011  $("<img/>").addClass(this._triggerClass).
7012  attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7013  $("<button type='button'></button>").addClass(this._triggerClass).
7014  html(!buttonImage ? buttonText : $("<img/>").attr(
7015  { src:buttonImage, alt:buttonText, title:buttonText })));
7016  input[isRTL ? "before" : "after"](inst.trigger);
7017  inst.trigger.click(function() {
7018  if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7019  $.datepicker._hideDatepicker();
7020  } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7021  $.datepicker._hideDatepicker();
7022  $.datepicker._showDatepicker(input[0]);
7023  } else {
7024  $.datepicker._showDatepicker(input[0]);
7025  }
7026  return false;
7027  });
7028  }
7029  },
7030 
7031  /* Apply the maximum length for the date format. */
7032  _autoSize: function(inst) {
7033  if (this._get(inst, "autoSize") && !inst.inline) {
7034  var findMax, max, maxI, i,
7035  date = new Date(2009, 12 - 1, 20), // Ensure double digits
7036  dateFormat = this._get(inst, "dateFormat");
7037 
7038  if (dateFormat.match(/[DM]/)) {
7039  findMax = function(names) {
7040  max = 0;
7041  maxI = 0;
7042  for (i = 0; i < names.length; i++) {
7043  if (names[i].length > max) {
7044  max = names[i].length;
7045  maxI = i;
7046  }
7047  }
7048  return maxI;
7049  };
7050  date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7051  "monthNames" : "monthNamesShort"))));
7052  date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7053  "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7054  }
7055  inst.input.attr("size", this._formatDate(inst, date).length);
7056  }
7057  },
7058 
7059  /* Attach an inline date picker to a div. */
7060  _inlineDatepicker: function(target, inst) {
7061  var divSpan = $(target);
7062  if (divSpan.hasClass(this.markerClassName)) {
7063  return;
7064  }
7065  divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7066  $.data(target, PROP_NAME, inst);
7067  this._setDate(inst, this._getDefaultDate(inst), true);
7068  this._updateDatepicker(inst);
7069  this._updateAlternate(inst);
7070  //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7071  if( inst.settings.disabled ) {
7072  this._disableDatepicker( target );
7073  }
7074  // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7075  // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7076  inst.dpDiv.css( "display", "block" );
7077  },
7078 
7079  /* Pop-up the date picker in a "dialog" box.
7080  * @param input element - ignored
7081  * @param date string or Date - the initial date to display
7082  * @param onSelect function - the function to call when a date is selected
7083  * @param settings object - update the dialog date picker instance's settings (anonymous object)
7084  * @param pos int[2] - coordinates for the dialog's position within the screen or
7085  * event - with x/y coordinates or
7086  * leave empty for default (screen centre)
7087  * @return the manager object
7088  */
7089  _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7090  var id, browserWidth, browserHeight, scrollX, scrollY,
7091  inst = this._dialogInst; // internal instance
7092 
7093  if (!inst) {
7094  this.uuid += 1;
7095  id = "dp" + this.uuid;
7096  this._dialogInput = $("<input type='text' id='" + id +
7097  "' style='position: absolute; top: -100px; width: 0px;'/>");
7098  this._dialogInput.keydown(this._doKeyDown);
7099  $("body").append(this._dialogInput);
7100  inst = this._dialogInst = this._newInst(this._dialogInput, false);
7101  inst.settings = {};
7102  $.data(this._dialogInput[0], PROP_NAME, inst);
7103  }
7104  extendRemove(inst.settings, settings || {});
7105  date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7106  this._dialogInput.val(date);
7107 
7108  this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7109  if (!this._pos) {
7110  browserWidth = document.documentElement.clientWidth;
7111  browserHeight = document.documentElement.clientHeight;
7112  scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7113  scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7114  this._pos = // should use actual width/height below
7115  [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7116  }
7117 
7118  // move input on screen for focus, but hidden behind dialog
7119  this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7120  inst.settings.onSelect = onSelect;
7121  this._inDialog = true;
7122  this.dpDiv.addClass(this._dialogClass);
7123  this._showDatepicker(this._dialogInput[0]);
7124  if ($.blockUI) {
7125  $.blockUI(this.dpDiv);
7126  }
7127  $.data(this._dialogInput[0], PROP_NAME, inst);
7128  return this;
7129  },
7130 
7131  /* Detach a datepicker from its control.
7132  * @param target element - the target input field or division or span
7133  */
7134  _destroyDatepicker: function(target) {
7135  var nodeName,
7136  $target = $(target),
7137  inst = $.data(target, PROP_NAME);
7138 
7139  if (!$target.hasClass(this.markerClassName)) {
7140  return;
7141  }
7142 
7143  nodeName = target.nodeName.toLowerCase();
7144  $.removeData(target, PROP_NAME);
7145  if (nodeName === "input") {
7146  inst.append.remove();
7147  inst.trigger.remove();
7148  $target.removeClass(this.markerClassName).
7149  unbind("focus", this._showDatepicker).
7150  unbind("keydown", this._doKeyDown).
7151  unbind("keypress", this._doKeyPress).
7152  unbind("keyup", this._doKeyUp);
7153  } else if (nodeName === "div" || nodeName === "span") {
7154  $target.removeClass(this.markerClassName).empty();
7155  }
7156  },
7157 
7158  /* Enable the date picker to a jQuery selection.
7159  * @param target element - the target input field or division or span
7160  */
7161  _enableDatepicker: function(target) {
7162  var nodeName, inline,
7163  $target = $(target),
7164  inst = $.data(target, PROP_NAME);
7165 
7166  if (!$target.hasClass(this.markerClassName)) {
7167  return;
7168  }
7169 
7170  nodeName = target.nodeName.toLowerCase();
7171  if (nodeName === "input") {
7172  target.disabled = false;
7173  inst.trigger.filter("button").
7174  each(function() { this.disabled = false; }).end().
7175  filter("img").css({opacity: "1.0", cursor: ""});
7176  } else if (nodeName === "div" || nodeName === "span") {
7177  inline = $target.children("." + this._inlineClass);
7178  inline.children().removeClass("ui-state-disabled");
7179  inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7180  prop("disabled", false);
7181  }
7182  this._disabledInputs = $.map(this._disabledInputs,
7183  function(value) { return (value === target ? null : value); }); // delete entry
7184  },
7185 
7186  /* Disable the date picker to a jQuery selection.
7187  * @param target element - the target input field or division or span
7188  */
7189  _disableDatepicker: function(target) {
7190  var nodeName, inline,
7191  $target = $(target),
7192  inst = $.data(target, PROP_NAME);
7193 
7194  if (!$target.hasClass(this.markerClassName)) {
7195  return;
7196  }
7197 
7198  nodeName = target.nodeName.toLowerCase();
7199  if (nodeName === "input") {
7200  target.disabled = true;
7201  inst.trigger.filter("button").
7202  each(function() { this.disabled = true; }).end().
7203  filter("img").css({opacity: "0.5", cursor: "default"});
7204  } else if (nodeName === "div" || nodeName === "span") {
7205  inline = $target.children("." + this._inlineClass);
7206  inline.children().addClass("ui-state-disabled");
7207  inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7208  prop("disabled", true);
7209  }
7210  this._disabledInputs = $.map(this._disabledInputs,
7211  function(value) { return (value === target ? null : value); }); // delete entry
7212  this._disabledInputs[this._disabledInputs.length] = target;
7213  },
7214 
7215  /* Is the first field in a jQuery collection disabled as a datepicker?
7216  * @param target element - the target input field or division or span
7217  * @return boolean - true if disabled, false if enabled
7218  */
7219  _isDisabledDatepicker: function(target) {
7220  if (!target) {
7221  return false;
7222  }
7223  for (var i = 0; i < this._disabledInputs.length; i++) {
7224  if (this._disabledInputs[i] === target) {
7225  return true;
7226  }
7227  }
7228  return false;
7229  },
7230 
7231  /* Retrieve the instance data for the target control.
7232  * @param target element - the target input field or division or span
7233  * @return object - the associated instance data
7234  * @throws error if a jQuery problem getting data
7235  */
7236  _getInst: function(target) {
7237  try {
7238  return $.data(target, PROP_NAME);
7239  }
7240  catch (err) {
7241  throw "Missing instance data for this datepicker";
7242  }
7243  },
7244 
7245  /* Update or retrieve the settings for a date picker attached to an input field or division.
7246  * @param target element - the target input field or division or span
7247  * @param name object - the new settings to update or
7248  * string - the name of the setting to change or retrieve,
7249  * when retrieving also "all" for all instance settings or
7250  * "defaults" for all global defaults
7251  * @param value any - the new value for the setting
7252  * (omit if above is an object or to retrieve a value)
7253  */
7254  _optionDatepicker: function(target, name, value) {
7255  var settings, date, minDate, maxDate,
7256  inst = this._getInst(target);
7257 
7258  if (arguments.length === 2 && typeof name === "string") {
7259  return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7260  (inst ? (name === "all" ? $.extend({}, inst.settings) :
7261  this._get(inst, name)) : null));
7262  }
7263 
7264  settings = name || {};
7265  if (typeof name === "string") {
7266  settings = {};
7267  settings[name] = value;
7268  }
7269 
7270  if (inst) {
7271  if (this._curInst === inst) {
7272  this._hideDatepicker();
7273  }
7274 
7275  date = this._getDateDatepicker(target, true);
7276  minDate = this._getMinMaxDate(inst, "min");
7277  maxDate = this._getMinMaxDate(inst, "max");
7278  extendRemove(inst.settings, settings);
7279  // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7280  if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
7281  inst.settings.minDate = this._formatDate(inst, minDate);
7282  }
7283  if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
7284  inst.settings.maxDate = this._formatDate(inst, maxDate);
7285  }
7286  if ( "disabled" in settings ) {
7287  if ( settings.disabled ) {
7288  this._disableDatepicker(target);
7289  } else {
7290  this._enableDatepicker(target);
7291  }
7292  }
7293  this._attachments($(target), inst);
7294  this._autoSize(inst);
7295  this._setDate(inst, date);
7296  this._updateAlternate(inst);
7297  this._updateDatepicker(inst);
7298  }
7299  },
7300 
7301  // change method deprecated
7302  _changeDatepicker: function(target, name, value) {
7303  this._optionDatepicker(target, name, value);
7304  },
7305 
7306  /* Redraw the date picker attached to an input field or division.
7307  * @param target element - the target input field or division or span
7308  */
7309  _refreshDatepicker: function(target) {
7310  var inst = this._getInst(target);
7311  if (inst) {
7312  this._updateDatepicker(inst);
7313  }
7314  },
7315 
7316  /* Set the dates for a jQuery selection.
7317  * @param target element - the target input field or division or span
7318  * @param date Date - the new date
7319  */
7320  _setDateDatepicker: function(target, date) {
7321  var inst = this._getInst(target);
7322  if (inst) {
7323  this._setDate(inst, date);
7324  this._updateDatepicker(inst);
7325  this._updateAlternate(inst);
7326  }
7327  },
7328 
7329  /* Get the date(s) for the first entry in a jQuery selection.
7330  * @param target element - the target input field or division or span
7331  * @param noDefault boolean - true if no default date is to be used
7332  * @return Date - the current date
7333  */
7334  _getDateDatepicker: function(target, noDefault) {
7335  var inst = this._getInst(target);
7336  if (inst && !inst.inline) {
7337  this._setDateFromField(inst, noDefault);
7338  }
7339  return (inst ? this._getDate(inst) : null);
7340  },
7341 
7342  /* Handle keystrokes. */
7343  _doKeyDown: function(event) {
7344  var onSelect, dateStr, sel,
7345  inst = $.datepicker._getInst(event.target),
7346  handled = true,
7347  isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
7348 
7349  inst._keyEvent = true;
7350  if ($.datepicker._datepickerShowing) {
7351  switch (event.keyCode) {
7352  case 9: $.datepicker._hideDatepicker();
7353  handled = false;
7354  break; // hide on tab out
7355  case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
7356  $.datepicker._currentClass + ")", inst.dpDiv);
7357  if (sel[0]) {
7358  $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7359  }
7360 
7361  onSelect = $.datepicker._get(inst, "onSelect");
7362  if (onSelect) {
7363  dateStr = $.datepicker._formatDate(inst);
7364 
7365  // trigger custom callback
7366  onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7367  } else {
7368  $.datepicker._hideDatepicker();
7369  }
7370 
7371  return false; // don't submit the form
7372  case 27: $.datepicker._hideDatepicker();
7373  break; // hide on escape
7374  case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7375  -$.datepicker._get(inst, "stepBigMonths") :
7376  -$.datepicker._get(inst, "stepMonths")), "M");
7377  break; // previous month/year on page up/+ ctrl
7378  case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7379  +$.datepicker._get(inst, "stepBigMonths") :
7380  +$.datepicker._get(inst, "stepMonths")), "M");
7381  break; // next month/year on page down/+ ctrl
7382  case 35: if (event.ctrlKey || event.metaKey) {
7383  $.datepicker._clearDate(event.target);
7384  }
7385  handled = event.ctrlKey || event.metaKey;
7386  break; // clear on ctrl or command +end
7387  case 36: if (event.ctrlKey || event.metaKey) {
7388  $.datepicker._gotoToday(event.target);
7389  }
7390  handled = event.ctrlKey || event.metaKey;
7391  break; // current on ctrl or command +home
7392  case 37: if (event.ctrlKey || event.metaKey) {
7393  $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
7394  }
7395  handled = event.ctrlKey || event.metaKey;
7396  // -1 day on ctrl or command +left
7397  if (event.originalEvent.altKey) {
7398  $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7399  -$.datepicker._get(inst, "stepBigMonths") :
7400  -$.datepicker._get(inst, "stepMonths")), "M");
7401  }
7402  // next month/year on alt +left on Mac
7403  break;
7404  case 38: if (event.ctrlKey || event.metaKey) {
7405  $.datepicker._adjustDate(event.target, -7, "D");
7406  }
7407  handled = event.ctrlKey || event.metaKey;
7408  break; // -1 week on ctrl or command +up
7409  case 39: if (event.ctrlKey || event.metaKey) {
7410  $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
7411  }
7412  handled = event.ctrlKey || event.metaKey;
7413  // +1 day on ctrl or command +right
7414  if (event.originalEvent.altKey) {
7415  $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7416  +$.datepicker._get(inst, "stepBigMonths") :
7417  +$.datepicker._get(inst, "stepMonths")), "M");
7418  }
7419  // next month/year on alt +right
7420  break;
7421  case 40: if (event.ctrlKey || event.metaKey) {
7422  $.datepicker._adjustDate(event.target, +7, "D");
7423  }
7424  handled = event.ctrlKey || event.metaKey;
7425  break; // +1 week on ctrl or command +down
7426  default: handled = false;
7427  }
7428  } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
7429  $.datepicker._showDatepicker(this);
7430  } else {
7431  handled = false;
7432  }
7433 
7434  if (handled) {
7435  event.preventDefault();
7436  event.stopPropagation();
7437  }
7438  },
7439 
7440  /* Filter entered characters - based on date format. */
7441  _doKeyPress: function(event) {
7442  var chars, chr,
7443  inst = $.datepicker._getInst(event.target);
7444 
7445  if ($.datepicker._get(inst, "constrainInput")) {
7446  chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
7447  chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
7448  return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
7449  }
7450  },
7451 
7452  /* Synchronise manual entry and field/alternate field. */
7453  _doKeyUp: function(event) {
7454  var date,
7455  inst = $.datepicker._getInst(event.target);
7456 
7457  if (inst.input.val() !== inst.lastVal) {
7458  try {
7459  date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7460  (inst.input ? inst.input.val() : null),
7461  $.datepicker._getFormatConfig(inst));
7462 
7463  if (date) { // only if valid
7464  $.datepicker._setDateFromField(inst);
7465  $.datepicker._updateAlternate(inst);
7466  $.datepicker._updateDatepicker(inst);
7467  }
7468  }
7469  catch (err) {
7470  }
7471  }
7472  return true;
7473  },
7474 
7475  /* Pop-up the date picker for a given input field.
7476  * If false returned from beforeShow event handler do not show.
7477  * @param input element - the input field attached to the date picker or
7478  * event - if triggered by focus
7479  */
7480  _showDatepicker: function(input) {
7481  input = input.target || input;
7482  if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
7483  input = $("input", input.parentNode)[0];
7484  }
7485 
7486  if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
7487  return;
7488  }
7489 
7490  var inst, beforeShow, beforeShowSettings, isFixed,
7491  offset, showAnim, duration;
7492 
7493  inst = $.datepicker._getInst(input);
7494  if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
7495  $.datepicker._curInst.dpDiv.stop(true, true);
7496  if ( inst && $.datepicker._datepickerShowing ) {
7497  $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7498  }
7499  }
7500 
7501  beforeShow = $.datepicker._get(inst, "beforeShow");
7502  beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7503  if(beforeShowSettings === false){
7504  return;
7505  }
7506  extendRemove(inst.settings, beforeShowSettings);
7507 
7508  inst.lastVal = null;
7509  $.datepicker._lastInput = input;
7510  $.datepicker._setDateFromField(inst);
7511 
7512  if ($.datepicker._inDialog) { // hide cursor
7513  input.value = "";
7514  }
7515  if (!$.datepicker._pos) { // position below input
7516  $.datepicker._pos = $.datepicker._findPos(input);
7517  $.datepicker._pos[1] += input.offsetHeight; // add the height
7518  }
7519 
7520  isFixed = false;
7521  $(input).parents().each(function() {
7522  isFixed |= $(this).css("position") === "fixed";
7523  return !isFixed;
7524  });
7525 
7526  offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7527  $.datepicker._pos = null;
7528  //to avoid flashes on Firefox
7529  inst.dpDiv.empty();
7530  // determine sizing offscreen
7531  inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
7532  $.datepicker._updateDatepicker(inst);
7533  // fix width for dynamic number of date pickers
7534  // and adjust position before showing
7535  offset = $.datepicker._checkOffset(inst, offset, isFixed);
7536  inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7537  "static" : (isFixed ? "fixed" : "absolute")), display: "none",
7538  left: offset.left + "px", top: offset.top + "px"});
7539 
7540  if (!inst.inline) {
7541  showAnim = $.datepicker._get(inst, "showAnim");
7542  duration = $.datepicker._get(inst, "duration");
7543  inst.dpDiv.zIndex($(input).zIndex()+1);
7544  $.datepicker._datepickerShowing = true;
7545 
7546  if ( $.effects && $.effects.effect[ showAnim ] ) {
7547  inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
7548  } else {
7549  inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
7550  }
7551 
7552  if ( $.datepicker._shouldFocusInput( inst ) ) {
7553  inst.input.focus();
7554  }
7555 
7556  $.datepicker._curInst = inst;
7557  }
7558  },
7559 
7560  /* Generate the date picker content. */
7561  _updateDatepicker: function(inst) {
7562  this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7563  instActive = inst; // for delegate hover events
7564  inst.dpDiv.empty().append(this._generateHTML(inst));
7565  this._attachHandlers(inst);
7566  inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
7567 
7568  var origyearshtml,
7569  numMonths = this._getNumberOfMonths(inst),
7570  cols = numMonths[1],
7571  width = 17;
7572 
7573  inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
7574  if (cols > 1) {
7575  inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
7576  }
7577  inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
7578  "Class"]("ui-datepicker-multi");
7579  inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
7580  "Class"]("ui-datepicker-rtl");
7581 
7582  if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7583  inst.input.focus();
7584  }
7585 
7586  // deffered render of the years select (to avoid flashes on Firefox)
7587  if( inst.yearshtml ){
7588  origyearshtml = inst.yearshtml;
7589  setTimeout(function(){
7590  //assure that inst.yearshtml didn't change.
7591  if( origyearshtml === inst.yearshtml && inst.yearshtml ){
7592  inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
7593  }
7594  origyearshtml = inst.yearshtml = null;
7595  }, 0);
7596  }
7597  },
7598 
7599  // #6694 - don't focus the input if it's already focused
7600  // this breaks the change event in IE
7601  // Support: IE and jQuery <1.9
7602  _shouldFocusInput: function( inst ) {
7603  return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
7604  },
7605 
7606  /* Check positioning to remain on screen. */
7607  _checkOffset: function(inst, offset, isFixed) {
7608  var dpWidth = inst.dpDiv.outerWidth(),
7609  dpHeight = inst.dpDiv.outerHeight(),
7610  inputWidth = inst.input ? inst.input.outerWidth() : 0,
7611  inputHeight = inst.input ? inst.input.outerHeight() : 0,
7612  viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
7613  viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
7614 
7615  offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
7616  offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
7617  offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
7618 
7619  // now check if datepicker is showing outside window viewport - move to a better place if so.
7620  offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
7621  Math.abs(offset.left + dpWidth - viewWidth) : 0);
7622  offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
7623  Math.abs(dpHeight + inputHeight) : 0);
7624 
7625  return offset;
7626  },
7627 
7628  /* Find an object's position on the screen. */
7629  _findPos: function(obj) {
7630  var position,
7631  inst = this._getInst(obj),
7632  isRTL = this._get(inst, "isRTL");
7633 
7634  while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
7635  obj = obj[isRTL ? "previousSibling" : "nextSibling"];
7636  }
7637 
7638  position = $(obj).offset();
7639  return [position.left, position.top];
7640  },
7641 
7642  /* Hide the date picker from view.
7643  * @param input element - the input field attached to the date picker
7644  */
7645  _hideDatepicker: function(input) {
7646  var showAnim, duration, postProcess, onClose,
7647  inst = this._curInst;
7648 
7649  if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
7650  return;
7651  }
7652 
7653  if (this._datepickerShowing) {
7654  showAnim = this._get(inst, "showAnim");
7655  duration = this._get(inst, "duration");
7656  postProcess = function() {
7657  $.datepicker._tidyDialog(inst);
7658  };
7659 
7660  // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
7661  if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
7662  inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
7663  } else {
7664  inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
7665  (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
7666  }
7667 
7668  if (!showAnim) {
7669  postProcess();
7670  }
7671  this._datepickerShowing = false;
7672 
7673  onClose = this._get(inst, "onClose");
7674  if (onClose) {
7675  onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
7676  }
7677 
7678  this._lastInput = null;
7679  if (this._inDialog) {
7680  this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
7681  if ($.blockUI) {
7682  $.unblockUI();
7683  $("body").append(this.dpDiv);
7684  }
7685  }
7686  this._inDialog = false;
7687  }
7688  },
7689 
7690  /* Tidy up after a dialog display. */
7691  _tidyDialog: function(inst) {
7692  inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
7693  },
7694 
7695  /* Close date picker if clicked elsewhere. */
7696  _checkExternalClick: function(event) {
7697  if (!$.datepicker._curInst) {
7698  return;
7699  }
7700 
7701  var $target = $(event.target),
7702  inst = $.datepicker._getInst($target[0]);
7703 
7704  if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
7705  $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
7706  !$target.hasClass($.datepicker.markerClassName) &&
7707  !$target.closest("." + $.datepicker._triggerClass).length &&
7708  $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
7709  ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
7710  $.datepicker._hideDatepicker();
7711  }
7712  },
7713 
7714  /* Adjust one of the date sub-fields. */
7715  _adjustDate: function(id, offset, period) {
7716  var target = $(id),
7717  inst = this._getInst(target[0]);
7718 
7719  if (this._isDisabledDatepicker(target[0])) {
7720  return;
7721  }
7722  this._adjustInstDate(inst, offset +
7723  (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
7724  period);
7725  this._updateDatepicker(inst);
7726  },
7727 
7728  /* Action for current link. */
7729  _gotoToday: function(id) {
7730  var date,
7731  target = $(id),
7732  inst = this._getInst(target[0]);
7733 
7734  if (this._get(inst, "gotoCurrent") && inst.currentDay) {
7735  inst.selectedDay = inst.currentDay;
7736  inst.drawMonth = inst.selectedMonth = inst.currentMonth;
7737  inst.drawYear = inst.selectedYear = inst.currentYear;
7738  } else {
7739  date = new Date();
7740  inst.selectedDay = date.getDate();
7741  inst.drawMonth = inst.selectedMonth = date.getMonth();
7742  inst.drawYear = inst.selectedYear = date.getFullYear();
7743  }
7744  this._notifyChange(inst);
7745  this._adjustDate(target);
7746  },
7747 
7748  /* Action for selecting a new month/year. */
7749  _selectMonthYear: function(id, select, period) {
7750  var target = $(id),
7751  inst = this._getInst(target[0]);
7752 
7753  inst["selected" + (period === "M" ? "Month" : "Year")] =
7754  inst["draw" + (period === "M" ? "Month" : "Year")] =
7755  parseInt(select.options[select.selectedIndex].value,10);
7756 
7757  this._notifyChange(inst);
7758  this._adjustDate(target);
7759  },
7760 
7761  /* Action for selecting a day. */
7762  _selectDay: function(id, month, year, td) {
7763  var inst,
7764  target = $(id);
7765 
7766  if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
7767  return;
7768  }
7769 
7770  inst = this._getInst(target[0]);
7771  inst.selectedDay = inst.currentDay = $("a", td).html();
7772  inst.selectedMonth = inst.currentMonth = month;
7773  inst.selectedYear = inst.currentYear = year;
7774  this._selectDate(id, this._formatDate(inst,
7775  inst.currentDay, inst.currentMonth, inst.currentYear));
7776  },
7777 
7778  /* Erase the input field and hide the date picker. */
7779  _clearDate: function(id) {
7780  var target = $(id);
7781  this._selectDate(target, "");
7782  },
7783 
7784  /* Update the input field with the selected date. */
7785  _selectDate: function(id, dateStr) {
7786  var onSelect,
7787  target = $(id),
7788  inst = this._getInst(target[0]);
7789 
7790  dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
7791  if (inst.input) {
7792  inst.input.val(dateStr);
7793  }
7794  this._updateAlternate(inst);
7795 
7796  onSelect = this._get(inst, "onSelect");
7797  if (onSelect) {
7798  onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
7799  } else if (inst.input) {
7800  inst.input.trigger("change"); // fire the change event
7801  }
7802 
7803  if (inst.inline){
7804  this._updateDatepicker(inst);
7805  } else {
7806  this._hideDatepicker();
7807  this._lastInput = inst.input[0];
7808  if (typeof(inst.input[0]) !== "object") {
7809  inst.input.focus(); // restore focus
7810  }
7811  this._lastInput = null;
7812  }
7813  },
7814 
7815  /* Update any alternate field to synchronise with the main field. */
7816  _updateAlternate: function(inst) {
7817  var altFormat, date, dateStr,
7818  altField = this._get(inst, "altField");
7819 
7820  if (altField) { // update alternate field too
7821  altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
7822  date = this._getDate(inst);
7823  dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
7824  $(altField).each(function() { $(this).val(dateStr); });
7825  }
7826  },
7827 
7828  /* Set as beforeShowDay function to prevent selection of weekends.
7829  * @param date Date - the date to customise
7830  * @return [boolean, string] - is this date selectable?, what is its CSS class?
7831  */
7832  noWeekends: function(date) {
7833  var day = date.getDay();
7834  return [(day > 0 && day < 6), ""];
7835  },
7836 
7837  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
7838  * @param date Date - the date to get the week for
7839  * @return number - the number of the week within the year that contains this date
7840  */
7841  iso8601Week: function(date) {
7842  var time,
7843  checkDate = new Date(date.getTime());
7844 
7845  // Find Thursday of this week starting on Monday
7846  checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
7847 
7848  time = checkDate.getTime();
7849  checkDate.setMonth(0); // Compare with Jan 1
7850  checkDate.setDate(1);
7851  return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
7852  },
7853 
7854  /* Parse a string value into a date object.
7855  * See formatDate below for the possible formats.
7856  *
7857  * @param format string - the expected format of the date
7858  * @param value string - the date in the above format
7859  * @param settings Object - attributes include:
7860  * shortYearCutoff number - the cutoff year for determining the century (optional)
7861  * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
7862  * dayNames string[7] - names of the days from Sunday (optional)
7863  * monthNamesShort string[12] - abbreviated names of the months (optional)
7864  * monthNames string[12] - names of the months (optional)
7865  * @return Date - the extracted date value or null if value is blank
7866  */
7867  parseDate: function (format, value, settings) {
7868  if (format == null || value == null) {
7869  throw "Invalid arguments";
7870  }
7871 
7872  value = (typeof value === "object" ? value.toString() : value + "");
7873  if (value === "") {
7874  return null;
7875  }
7876 
7877  var iFormat, dim, extra,
7878  iValue = 0,
7879  shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
7880  shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
7881  new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
7882  dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
7883  dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
7884  monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
7885  monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
7886  year = -1,
7887  month = -1,
7888  day = -1,
7889  doy = -1,
7890  literal = false,
7891  date,
7892  // Check whether a format character is doubled
7893  lookAhead = function(match) {
7894  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
7895  if (matches) {
7896  iFormat++;
7897  }
7898  return matches;
7899  },
7900  // Extract a number from the string value
7901  getNumber = function(match) {
7902  var isDoubled = lookAhead(match),
7903  size = (match === "@" ? 14 : (match === "!" ? 20 :
7904  (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
7905  digits = new RegExp("^\\d{1," + size + "}"),
7906  num = value.substring(iValue).match(digits);
7907  if (!num) {
7908  throw "Missing number at position " + iValue;
7909  }
7910  iValue += num[0].length;
7911  return parseInt(num[0], 10);
7912  },
7913  // Extract a name from the string value and convert to an index
7914  getName = function(match, shortNames, longNames) {
7915  var index = -1,
7916  names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
7917  return [ [k, v] ];
7918  }).sort(function (a, b) {
7919  return -(a[1].length - b[1].length);
7920  });
7921 
7922  $.each(names, function (i, pair) {
7923  var name = pair[1];
7924  if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
7925  index = pair[0];
7926  iValue += name.length;
7927  return false;
7928  }
7929  });
7930  if (index !== -1) {
7931  return index + 1;
7932  } else {
7933  throw "Unknown name at position " + iValue;
7934  }
7935  },
7936  // Confirm that a literal character matches the string value
7937  checkLiteral = function() {
7938  if (value.charAt(iValue) !== format.charAt(iFormat)) {
7939  throw "Unexpected literal at position " + iValue;
7940  }
7941  iValue++;
7942  };
7943 
7944  for (iFormat = 0; iFormat < format.length; iFormat++) {
7945  if (literal) {
7946  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
7947  literal = false;
7948  } else {
7949  checkLiteral();
7950  }
7951  } else {
7952  switch (format.charAt(iFormat)) {
7953  case "d":
7954  day = getNumber("d");
7955  break;
7956  case "D":
7957  getName("D", dayNamesShort, dayNames);
7958  break;
7959  case "o":
7960  doy = getNumber("o");
7961  break;
7962  case "m":
7963  month = getNumber("m");
7964  break;
7965  case "M":
7966  month = getName("M", monthNamesShort, monthNames);
7967  break;
7968  case "y":
7969  year = getNumber("y");
7970  break;
7971  case "@":
7972  date = new Date(getNumber("@"));
7973  year = date.getFullYear();
7974  month = date.getMonth() + 1;
7975  day = date.getDate();
7976  break;
7977  case "!":
7978  date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
7979  year = date.getFullYear();
7980  month = date.getMonth() + 1;
7981  day = date.getDate();
7982  break;
7983  case "'":
7984  if (lookAhead("'")){
7985  checkLiteral();
7986  } else {
7987  literal = true;
7988  }
7989  break;
7990  default:
7991  checkLiteral();
7992  }
7993  }
7994  }
7995 
7996  if (iValue < value.length){
7997  extra = value.substr(iValue);
7998  if (!/^\s+/.test(extra)) {
7999  throw "Extra/unparsed characters found in date: " + extra;
8000  }
8001  }
8002 
8003  if (year === -1) {
8004  year = new Date().getFullYear();
8005  } else if (year < 100) {
8006  year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8007  (year <= shortYearCutoff ? 0 : -100);
8008  }
8009 
8010  if (doy > -1) {
8011  month = 1;
8012  day = doy;
8013  do {
8014  dim = this._getDaysInMonth(year, month - 1);
8015  if (day <= dim) {
8016  break;
8017  }
8018  month++;
8019  day -= dim;
8020  } while (true);
8021  }
8022 
8023  date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8024  if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8025  throw "Invalid date"; // E.g. 31/02/00
8026  }
8027  return date;
8028  },
8029 
8030  /* Standard date formats. */
8031  ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8032  COOKIE: "D, dd M yy",
8033  ISO_8601: "yy-mm-dd",
8034  RFC_822: "D, d M y",
8035  RFC_850: "DD, dd-M-y",
8036  RFC_1036: "D, d M y",
8037  RFC_1123: "D, d M yy",
8038  RFC_2822: "D, d M yy",
8039  RSS: "D, d M y", // RFC 822
8040  TICKS: "!",
8041  TIMESTAMP: "@",
8042  W3C: "yy-mm-dd", // ISO 8601
8043 
8044  _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8045  Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8046 
8047  /* Format a date object into a string value.
8048  * The format can be combinations of the following:
8049  * d - day of month (no leading zero)
8050  * dd - day of month (two digit)
8051  * o - day of year (no leading zeros)
8052  * oo - day of year (three digit)
8053  * D - day name short
8054  * DD - day name long
8055  * m - month of year (no leading zero)
8056  * mm - month of year (two digit)
8057  * M - month name short
8058  * MM - month name long
8059  * y - year (two digit)
8060  * yy - year (four digit)
8061  * @ - Unix timestamp (ms since 01/01/1970)
8062  * ! - Windows ticks (100ns since 01/01/0001)
8063  * "..." - literal text
8064  * '' - single quote
8065  *
8066  * @param format string - the desired format of the date
8067  * @param date Date - the date value to format
8068  * @param settings Object - attributes include:
8069  * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8070  * dayNames string[7] - names of the days from Sunday (optional)
8071  * monthNamesShort string[12] - abbreviated names of the months (optional)
8072  * monthNames string[12] - names of the months (optional)
8073  * @return string - the date in the above format
8074  */
8075  formatDate: function (format, date, settings) {
8076  if (!date) {
8077  return "";
8078  }
8079 
8080  var iFormat,
8081  dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8082  dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8083  monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8084  monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8085  // Check whether a format character is doubled
8086  lookAhead = function(match) {
8087  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8088  if (matches) {
8089  iFormat++;
8090  }
8091  return matches;
8092  },
8093  // Format a number, with leading zero if necessary
8094  formatNumber = function(match, value, len) {
8095  var num = "" + value;
8096  if (lookAhead(match)) {
8097  while (num.length < len) {
8098  num = "0" + num;
8099  }
8100  }
8101  return num;
8102  },
8103  // Format a name, short or long as requested
8104  formatName = function(match, value, shortNames, longNames) {
8105  return (lookAhead(match) ? longNames[value] : shortNames[value]);
8106  },
8107  output = "",
8108  literal = false;
8109 
8110  if (date) {
8111  for (iFormat = 0; iFormat < format.length; iFormat++) {
8112  if (literal) {
8113  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8114  literal = false;
8115  } else {
8116  output += format.charAt(iFormat);
8117  }
8118  } else {
8119  switch (format.charAt(iFormat)) {
8120  case "d":
8121  output += formatNumber("d", date.getDate(), 2);
8122  break;
8123  case "D":
8124  output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8125  break;
8126  case "o":
8127  output += formatNumber("o",
8128  Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8129  break;
8130  case "m":
8131  output += formatNumber("m", date.getMonth() + 1, 2);
8132  break;
8133  case "M":
8134  output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8135  break;
8136  case "y":
8137  output += (lookAhead("y") ? date.getFullYear() :
8138  (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8139  break;
8140  case "@":
8141  output += date.getTime();
8142  break;
8143  case "!":
8144  output += date.getTime() * 10000 + this._ticksTo1970;
8145  break;
8146  case "'":
8147  if (lookAhead("'")) {
8148  output += "'";
8149  } else {
8150  literal = true;
8151  }
8152  break;
8153  default:
8154  output += format.charAt(iFormat);
8155  }
8156  }
8157  }
8158  }
8159  return output;
8160  },
8161 
8162  /* Extract all possible characters from the date format. */
8163  _possibleChars: function (format) {
8164  var iFormat,
8165  chars = "",
8166  literal = false,
8167  // Check whether a format character is doubled
8168  lookAhead = function(match) {
8169  var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8170  if (matches) {
8171  iFormat++;
8172  }
8173  return matches;
8174  };
8175 
8176  for (iFormat = 0; iFormat < format.length; iFormat++) {
8177  if (literal) {
8178  if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8179  literal = false;
8180  } else {
8181  chars += format.charAt(iFormat);
8182  }
8183  } else {
8184  switch (format.charAt(iFormat)) {
8185  case "d": case "m": case "y": case "@":
8186  chars += "0123456789";
8187  break;
8188  case "D": case "M":
8189  return null; // Accept anything
8190  case "'":
8191  if (lookAhead("'")) {
8192  chars += "'";
8193  } else {
8194  literal = true;
8195  }
8196  break;
8197  default:
8198  chars += format.charAt(iFormat);
8199  }
8200  }
8201  }
8202  return chars;
8203  },
8204 
8205  /* Get a setting value, defaulting if necessary. */
8206  _get: function(inst, name) {
8207  return inst.settings[name] !== undefined ?
8208  inst.settings[name] : this._defaults[name];
8209  },
8210 
8211  /* Parse existing date and initialise date picker. */
8212  _setDateFromField: function(inst, noDefault) {
8213  if (inst.input.val() === inst.lastVal) {
8214  return;
8215  }
8216 
8217  var dateFormat = this._get(inst, "dateFormat"),
8218  dates = inst.lastVal = inst.input ? inst.input.val() : null,
8219  defaultDate = this._getDefaultDate(inst),
8220  date = defaultDate,
8221  settings = this._getFormatConfig(inst);
8222 
8223  try {
8224  date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8225  } catch (event) {
8226  dates = (noDefault ? "" : dates);
8227  }
8228  inst.selectedDay = date.getDate();
8229  inst.drawMonth = inst.selectedMonth = date.getMonth();
8230  inst.drawYear = inst.selectedYear = date.getFullYear();
8231  inst.currentDay = (dates ? date.getDate() : 0);
8232  inst.currentMonth = (dates ? date.getMonth() : 0);
8233  inst.currentYear = (dates ? date.getFullYear() : 0);
8234  this._adjustInstDate(inst);
8235  },
8236 
8237  /* Retrieve the default date shown on opening. */
8238  _getDefaultDate: function(inst) {
8239  return this._restrictMinMax(inst,
8240  this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8241  },
8242 
8243  /* A date may be specified as an exact value or a relative one. */
8244  _determineDate: function(inst, date, defaultDate) {
8245  var offsetNumeric = function(offset) {
8246  var date = new Date();
8247  date.setDate(date.getDate() + offset);
8248  return date;
8249  },
8250  offsetString = function(offset) {
8251  try {
8252  return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8253  offset, $.datepicker._getFormatConfig(inst));
8254  }
8255  catch (e) {
8256  // Ignore
8257  }
8258 
8259  var date = (offset.toLowerCase().match(/^c/) ?
8260  $.datepicker._getDate(inst) : null) || new Date(),
8261  year = date.getFullYear(),
8262  month = date.getMonth(),
8263  day = date.getDate(),
8264  pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8265  matches = pattern.exec(offset);
8266 
8267  while (matches) {
8268  switch (matches[2] || "d") {
8269  case "d" : case "D" :
8270  day += parseInt(matches[1],10); break;
8271  case "w" : case "W" :
8272  day += parseInt(matches[1],10) * 7; break;
8273  case "m" : case "M" :
8274  month += parseInt(matches[1],10);
8275  day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8276  break;
8277  case "y": case "Y" :
8278  year += parseInt(matches[1],10);
8279  day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8280  break;
8281  }
8282  matches = pattern.exec(offset);
8283  }
8284  return new Date(year, month, day);
8285  },
8286  newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
8287  (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8288 
8289  newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
8290  if (newDate) {
8291  newDate.setHours(0);
8292  newDate.setMinutes(0);
8293  newDate.setSeconds(0);
8294  newDate.setMilliseconds(0);
8295  }
8296  return this._daylightSavingAdjust(newDate);
8297  },
8298 
8299  /* Handle switch to/from daylight saving.
8300  * Hours may be non-zero on daylight saving cut-over:
8301  * > 12 when midnight changeover, but then cannot generate
8302  * midnight datetime, so jump to 1AM, otherwise reset.
8303  * @param date (Date) the date to check
8304  * @return (Date) the corrected date
8305  */
8306  _daylightSavingAdjust: function(date) {
8307  if (!date) {
8308  return null;
8309  }
8310  date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8311  return date;
8312  },
8313 
8314  /* Set the date(s) directly. */
8315  _setDate: function(inst, date, noChange) {
8316  var clear = !date,
8317  origMonth = inst.selectedMonth,
8318  origYear = inst.selectedYear,
8319  newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8320 
8321  inst.selectedDay = inst.currentDay = newDate.getDate();
8322  inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8323  inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8324  if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
8325  this._notifyChange(inst);
8326  }
8327  this._adjustInstDate(inst);
8328  if (inst.input) {
8329  inst.input.val(clear ? "" : this._formatDate(inst));
8330  }
8331  },
8332 
8333  /* Retrieve the date(s) directly. */
8334  _getDate: function(inst) {
8335  var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
8336  this._daylightSavingAdjust(new Date(
8337  inst.currentYear, inst.currentMonth, inst.currentDay)));
8338  return startDate;
8339  },
8340 
8341  /* Attach the onxxx handlers. These are declared statically so
8342  * they work with static code transformers like Caja.
8343  */
8344  _attachHandlers: function(inst) {
8345  var stepMonths = this._get(inst, "stepMonths"),
8346  id = "#" + inst.id.replace( /\\\\/g, "\\" );
8347  inst.dpDiv.find("[data-handler]").map(function () {
8348  var handler = {
8349  prev: function () {
8350  $.datepicker._adjustDate(id, -stepMonths, "M");
8351  },
8352  next: function () {
8353  $.datepicker._adjustDate(id, +stepMonths, "M");
8354  },
8355  hide: function () {
8356  $.datepicker._hideDatepicker();
8357  },
8358  today: function () {
8359  $.datepicker._gotoToday(id);
8360  },
8361  selectDay: function () {
8362  $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
8363  return false;
8364  },
8365  selectMonth: function () {
8366  $.datepicker._selectMonthYear(id, this, "M");
8367  return false;
8368  },
8369  selectYear: function () {
8370  $.datepicker._selectMonthYear(id, this, "Y");
8371  return false;
8372  }
8373  };
8374  $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
8375  });
8376  },
8377 
8378  /* Generate the HTML for the current state of the date picker. */
8379  _generateHTML: function(inst) {
8380  var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8381  controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8382  monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8383  selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8384  cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8385  printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8386  tempDate = new Date(),
8387  today = this._daylightSavingAdjust(
8388  new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
8389  isRTL = this._get(inst, "isRTL"),
8390  showButtonPanel = this._get(inst, "showButtonPanel"),
8391  hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
8392  navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
8393  numMonths = this._getNumberOfMonths(inst),
8394  showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
8395  stepMonths = this._get(inst, "stepMonths"),
8396  isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
8397  currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8398  new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
8399  minDate = this._getMinMaxDate(inst, "min"),
8400  maxDate = this._getMinMaxDate(inst, "max"),
8401  drawMonth = inst.drawMonth - showCurrentAtPos,
8402  drawYear = inst.drawYear;
8403 
8404  if (drawMonth < 0) {
8405  drawMonth += 12;
8406  drawYear--;
8407  }
8408  if (maxDate) {
8409  maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8410  maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8411  maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8412  while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8413  drawMonth--;
8414  if (drawMonth < 0) {
8415  drawMonth = 11;
8416  drawYear--;
8417  }
8418  }
8419  }
8420  inst.drawMonth = drawMonth;
8421  inst.drawYear = drawYear;
8422 
8423  prevText = this._get(inst, "prevText");
8424  prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8425  this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8426  this._getFormatConfig(inst)));
8427 
8428  prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8429  "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8430  " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
8431  (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
8432 
8433  nextText = this._get(inst, "nextText");
8434  nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8435  this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8436  this._getFormatConfig(inst)));
8437 
8438  next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8439  "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8440  " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
8441  (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
8442 
8443  currentText = this._get(inst, "currentText");
8444  gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
8445  currentText = (!navigationAsDateFormat ? currentText :
8446  this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8447 
8448  controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
8449  this._get(inst, "closeText") + "</button>" : "");
8450 
8451  buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
8452  (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
8453  ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
8454 
8455  firstDay = parseInt(this._get(inst, "firstDay"),10);
8456  firstDay = (isNaN(firstDay) ? 0 : firstDay);
8457 
8458  showWeek = this._get(inst, "showWeek");
8459  dayNames = this._get(inst, "dayNames");
8460  dayNamesMin = this._get(inst, "dayNamesMin");
8461  monthNames = this._get(inst, "monthNames");
8462  monthNamesShort = this._get(inst, "monthNamesShort");
8463  beforeShowDay = this._get(inst, "beforeShowDay");
8464  showOtherMonths = this._get(inst, "showOtherMonths");
8465  selectOtherMonths = this._get(inst, "selectOtherMonths");
8466  defaultDate = this._getDefaultDate(inst);
8467  html = "";
8468  dow;
8469  for (row = 0; row < numMonths[0]; row++) {
8470  group = "";
8471  this.maxRows = 4;
8472  for (col = 0; col < numMonths[1]; col++) {
8473  selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8474  cornerClass = " ui-corner-all";
8475  calender = "";
8476  if (isMultiMonth) {
8477  calender += "<div class='ui-datepicker-group";
8478  if (numMonths[1] > 1) {
8479  switch (col) {
8480  case 0: calender += " ui-datepicker-group-first";
8481  cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
8482  case numMonths[1]-1: calender += " ui-datepicker-group-last";
8483  cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
8484  default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8485  }
8486  }
8487  calender += "'>";
8488  }
8489  calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8490  (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
8491  (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
8492  this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8493  row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8494  "</div><table class='ui-datepicker-calendar'><thead>" +
8495  "<tr>";
8496  thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
8497  for (dow = 0; dow < 7; dow++) { // days of the week
8498  day = (dow + firstDay) % 7;
8499  thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
8500  "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
8501  }
8502  calender += thead + "</tr></thead><tbody>";
8503  daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8504  if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
8505  inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8506  }
8507  leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8508  curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8509  numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8510  this.maxRows = numRows;
8511  printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8512  for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8513  calender += "<tr>";
8514  tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8515  this._get(inst, "calculateWeek")(printDate) + "</td>");
8516  for (dow = 0; dow < 7; dow++) { // create date picker days
8517  daySettings = (beforeShowDay ?
8518  beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
8519  otherMonth = (printDate.getMonth() !== drawMonth);
8520  unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8521  (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8522  tbody += "<td class='" +
8523  ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
8524  (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
8525  ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
8526  (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
8527  // or defaultDate is current printedDate and defaultDate is selectedDate
8528  " " + this._dayOverClass : "") + // highlight selected day
8529  (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
8530  (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
8531  (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
8532  (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
8533  ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
8534  (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
8535  (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8536  (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8537  (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
8538  (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
8539  (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
8540  "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
8541  printDate.setDate(printDate.getDate() + 1);
8542  printDate = this._daylightSavingAdjust(printDate);
8543  }
8544  calender += tbody + "</tr>";
8545  }
8546  drawMonth++;
8547  if (drawMonth > 11) {
8548  drawMonth = 0;
8549  drawYear++;
8550  }
8551  calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
8552  ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
8553  group += calender;
8554  }
8555  html += group;
8556  }
8557  html += buttonPanel;
8558  inst._keyEvent = false;
8559  return html;
8560  },
8561 
8562  /* Generate the month and year header. */
8563  _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8564  secondary, monthNames, monthNamesShort) {
8565 
8566  var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8567  changeMonth = this._get(inst, "changeMonth"),
8568  changeYear = this._get(inst, "changeYear"),
8569  showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
8570  html = "<div class='ui-datepicker-title'>",
8571  monthHtml = "";
8572 
8573  // month selection
8574  if (secondary || !changeMonth) {
8575  monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
8576  } else {
8577  inMinYear = (minDate && minDate.getFullYear() === drawYear);
8578  inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
8579  monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
8580  for ( month = 0; month < 12; month++) {
8581  if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
8582  monthHtml += "<option value='" + month + "'" +
8583  (month === drawMonth ? " selected='selected'" : "") +
8584  ">" + monthNamesShort[month] + "</option>";
8585  }
8586  }
8587  monthHtml += "</select>";
8588  }
8589 
8590  if (!showMonthAfterYear) {
8591  html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
8592  }
8593 
8594  // year selection
8595  if ( !inst.yearshtml ) {
8596  inst.yearshtml = "";
8597  if (secondary || !changeYear) {
8598  html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
8599  } else {
8600  // determine range of years to display
8601  years = this._get(inst, "yearRange").split(":");
8602  thisYear = new Date().getFullYear();
8603  determineYear = function(value) {
8604  var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8605  (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
8606  parseInt(value, 10)));
8607  return (isNaN(year) ? thisYear : year);
8608  };
8609  year = determineYear(years[0]);
8610  endYear = Math.max(year, determineYear(years[1] || ""));
8611  year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8612  endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8613  inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
8614  for (; year <= endYear; year++) {
8615  inst.yearshtml += "<option value='" + year + "'" +
8616  (year === drawYear ? " selected='selected'" : "") +
8617  ">" + year + "</option>";
8618  }
8619  inst.yearshtml += "</select>";
8620 
8621  html += inst.yearshtml;
8622  inst.yearshtml = null;
8623  }
8624  }
8625 
8626  html += this._get(inst, "yearSuffix");
8627  if (showMonthAfterYear) {
8628  html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
8629  }
8630  html += "</div>"; // Close datepicker_header
8631  return html;
8632  },
8633 
8634  /* Adjust one of the date sub-fields. */
8635  _adjustInstDate: function(inst, offset, period) {
8636  var year = inst.drawYear + (period === "Y" ? offset : 0),
8637  month = inst.drawMonth + (period === "M" ? offset : 0),
8638  day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
8639  date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
8640 
8641  inst.selectedDay = date.getDate();
8642  inst.drawMonth = inst.selectedMonth = date.getMonth();
8643  inst.drawYear = inst.selectedYear = date.getFullYear();
8644  if (period === "M" || period === "Y") {
8645  this._notifyChange(inst);
8646  }
8647  },
8648 
8649  /* Ensure a date is within any min/max bounds. */
8650  _restrictMinMax: function(inst, date) {
8651  var minDate = this._getMinMaxDate(inst, "min"),
8652  maxDate = this._getMinMaxDate(inst, "max"),
8653  newDate = (minDate && date < minDate ? minDate : date);
8654  return (maxDate && newDate > maxDate ? maxDate : newDate);
8655  },
8656 
8657  /* Notify change of month/year. */
8658  _notifyChange: function(inst) {
8659  var onChange = this._get(inst, "onChangeMonthYear");
8660  if (onChange) {
8661  onChange.apply((inst.input ? inst.input[0] : null),
8662  [inst.selectedYear, inst.selectedMonth + 1, inst]);
8663  }
8664  },
8665 
8666  /* Determine the number of months to show. */
8667  _getNumberOfMonths: function(inst) {
8668  var numMonths = this._get(inst, "numberOfMonths");
8669  return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
8670  },
8671 
8672  /* Determine the current maximum date - ensure no time components are set. */
8673  _getMinMaxDate: function(inst, minMax) {
8674  return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
8675  },
8676 
8677  /* Find the number of days in a given month. */
8678  _getDaysInMonth: function(year, month) {
8679  return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8680  },
8681 
8682  /* Find the day of the week of the first of a month. */
8683  _getFirstDayOfMonth: function(year, month) {
8684  return new Date(year, month, 1).getDay();
8685  },
8686 
8687  /* Determines if we should allow a "next/prev" month display change. */
8688  _canAdjustMonth: function(inst, offset, curYear, curMonth) {
8689  var numMonths = this._getNumberOfMonths(inst),
8690  date = this._daylightSavingAdjust(new Date(curYear,
8691  curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8692 
8693  if (offset < 0) {
8694  date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8695  }
8696  return this._isInRange(inst, date);
8697  },
8698 
8699  /* Is the given date in the accepted range? */
8700  _isInRange: function(inst, date) {
8701  var yearSplit, currentYear,
8702  minDate = this._getMinMaxDate(inst, "min"),
8703  maxDate = this._getMinMaxDate(inst, "max"),
8704  minYear = null,
8705  maxYear = null,
8706  years = this._get(inst, "yearRange");
8707  if (years){
8708  yearSplit = years.split(":");
8709  currentYear = new Date().getFullYear();
8710  minYear = parseInt(yearSplit[0], 10);
8711  maxYear = parseInt(yearSplit[1], 10);
8712  if ( yearSplit[0].match(/[+\-].*/) ) {
8713  minYear += currentYear;
8714  }
8715  if ( yearSplit[1].match(/[+\-].*/) ) {
8716  maxYear += currentYear;
8717  }
8718  }
8719 
8720  return ((!minDate || date.getTime() >= minDate.getTime()) &&
8721  (!maxDate || date.getTime() <= maxDate.getTime()) &&
8722  (!minYear || date.getFullYear() >= minYear) &&
8723  (!maxYear || date.getFullYear() <= maxYear));
8724  },
8725 
8726  /* Provide the configuration settings for formatting/parsing. */
8727  _getFormatConfig: function(inst) {
8728  var shortYearCutoff = this._get(inst, "shortYearCutoff");
8729  shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
8730  new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8731  return {shortYearCutoff: shortYearCutoff,
8732  dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
8733  monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
8734  },
8735 
8736  /* Format the given date for display. */
8737  _formatDate: function(inst, day, month, year) {
8738  if (!day) {
8739  inst.currentDay = inst.selectedDay;
8740  inst.currentMonth = inst.selectedMonth;
8741  inst.currentYear = inst.selectedYear;
8742  }
8743  var date = (day ? (typeof day === "object" ? day :
8744  this._daylightSavingAdjust(new Date(year, month, day))) :
8745  this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8746  return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
8747  }
8748 });
8749 
8750 /*
8751  * Bind hover events for datepicker elements.
8752  * Done via delegate so the binding only occurs once in the lifetime of the parent div.
8753  * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
8754  */
8755 function bindHover(dpDiv) {
8756  var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
8757  return dpDiv.delegate(selector, "mouseout", function() {
8758  $(this).removeClass("ui-state-hover");
8759  if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8760  $(this).removeClass("ui-datepicker-prev-hover");
8761  }
8762  if (this.className.indexOf("ui-datepicker-next") !== -1) {
8763  $(this).removeClass("ui-datepicker-next-hover");
8764  }
8765  })
8766  .delegate(selector, "mouseover", function(){
8767  if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
8768  $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
8769  $(this).addClass("ui-state-hover");
8770  if (this.className.indexOf("ui-datepicker-prev") !== -1) {
8771  $(this).addClass("ui-datepicker-prev-hover");
8772  }
8773  if (this.className.indexOf("ui-datepicker-next") !== -1) {
8774  $(this).addClass("ui-datepicker-next-hover");
8775  }
8776  }
8777  });
8778 }
8779 
8780 /* jQuery extend now ignores nulls! */
8781 function extendRemove(target, props) {
8782  $.extend(target, props);
8783  for (var name in props) {
8784  if (props[name] == null) {
8785  target[name] = props[name];
8786  }
8787  }
8788  return target;
8789 }
8790 
8791 /* Invoke the datepicker functionality.
8792  @param options string - a command, optionally followed by additional parameters or
8793  Object - settings for attaching new datepicker functionality
8794  @return jQuery object */
8795 $.fn.datepicker = function(options){
8796 
8797  /* Verify an empty collection wasn't passed - Fixes #6976 */
8798  if ( !this.length ) {
8799  return this;
8800  }
8801 
8802  /* Initialise the date picker. */
8803  if (!$.datepicker.initialized) {
8804  $(document).mousedown($.datepicker._checkExternalClick);
8805  $.datepicker.initialized = true;
8806  }
8807 
8808  /* Append datepicker main container to body if not exist. */
8809  if ($("#"+$.datepicker._mainDivId).length === 0) {
8810  $("body").append($.datepicker.dpDiv);
8811  }
8812 
8813  var otherArgs = Array.prototype.slice.call(arguments, 1);
8814  if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
8815  return $.datepicker["_" + options + "Datepicker"].
8816  apply($.datepicker, [this[0]].concat(otherArgs));
8817  }
8818  if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
8819  return $.datepicker["_" + options + "Datepicker"].
8820  apply($.datepicker, [this[0]].concat(otherArgs));
8821  }
8822  return this.each(function() {
8823  typeof options === "string" ?
8824  $.datepicker["_" + options + "Datepicker"].
8825  apply($.datepicker, [this].concat(otherArgs)) :
8826  $.datepicker._attachDatepicker(this, options);
8827  });
8828 };
8829 
8830 $.datepicker = new Datepicker(); // singleton instance
8831 $.datepicker.initialized = false;
8832 $.datepicker.uuid = new Date().getTime();
8833 $.datepicker.version = "1.10.3";
8834 
8835 })(jQuery);
8836 (function( $, undefined ) {
8837 
8838 var sizeRelatedOptions = {
8839  buttons: true,
8840  height: true,
8841  maxHeight: true,
8842  maxWidth: true,
8843  minHeight: true,
8844  minWidth: true,
8845  width: true
8846  },
8847  resizableRelatedOptions = {
8848  maxHeight: true,
8849  maxWidth: true,
8850  minHeight: true,
8851  minWidth: true
8852  };
8853 
8854 $.widget( "ui.dialog", {
8855  version: "1.10.3",
8856  options: {
8857  appendTo: "body",
8858  autoOpen: true,
8859  buttons: [],
8860  closeOnEscape: true,
8861  closeText: "close",
8862  dialogClass: "",
8863  draggable: true,
8864  hide: null,
8865  height: "auto",
8866  maxHeight: null,
8867  maxWidth: null,
8868  minHeight: 150,
8869  minWidth: 150,
8870  modal: false,
8871  position: {
8872  my: "center",
8873  at: "center",
8874  of: window,
8875  collision: "fit",
8876  // Ensure the titlebar is always visible
8877  using: function( pos ) {
8878  var topOffset = $( this ).css( pos ).offset().top;
8879  if ( topOffset < 0 ) {
8880  $( this ).css( "top", pos.top - topOffset );
8881  }
8882  }
8883  },
8884  resizable: true,
8885  show: null,
8886  title: null,
8887  width: 300,
8888 
8889  // callbacks
8890  beforeClose: null,
8891  close: null,
8892  drag: null,
8893  dragStart: null,
8894  dragStop: null,
8895  focus: null,
8896  open: null,
8897  resize: null,
8898  resizeStart: null,
8899  resizeStop: null
8900  },
8901 
8902  _create: function() {
8903  this.originalCss = {
8904  display: this.element[0].style.display,
8905  width: this.element[0].style.width,
8906  minHeight: this.element[0].style.minHeight,
8907  maxHeight: this.element[0].style.maxHeight,
8908  height: this.element[0].style.height
8909  };
8910  this.originalPosition = {
8911  parent: this.element.parent(),
8912  index: this.element.parent().children().index( this.element )
8913  };
8914  this.originalTitle = this.element.attr("title");
8915  this.options.title = this.options.title || this.originalTitle;
8916 
8917  this._createWrapper();
8918 
8919  this.element
8920  .show()
8921  .removeAttr("title")
8922  .addClass("ui-dialog-content ui-widget-content")
8923  .appendTo( this.uiDialog );
8924 
8925  this._createTitlebar();
8926  this._createButtonPane();
8927 
8928  if ( this.options.draggable && $.fn.draggable ) {
8929  this._makeDraggable();
8930  }
8931  if ( this.options.resizable && $.fn.resizable ) {
8932  this._makeResizable();
8933  }
8934 
8935  this._isOpen = false;
8936  },
8937 
8938  _init: function() {
8939  if ( this.options.autoOpen ) {
8940  this.open();
8941  }
8942  },
8943 
8944  _appendTo: function() {
8945  var element = this.options.appendTo;
8946  if ( element && (element.jquery || element.nodeType) ) {
8947  return $( element );
8948  }
8949  return this.document.find( element || "body" ).eq( 0 );
8950  },
8951 
8952  _destroy: function() {
8953  var next,
8954  originalPosition = this.originalPosition;
8955 
8956  this._destroyOverlay();
8957 
8958  this.element
8959  .removeUniqueId()
8960  .removeClass("ui-dialog-content ui-widget-content")
8961  .css( this.originalCss )
8962  // Without detaching first, the following becomes really slow
8963  .detach();
8964 
8965  this.uiDialog.stop( true, true ).remove();
8966 
8967  if ( this.originalTitle ) {
8968  this.element.attr( "title", this.originalTitle );
8969  }
8970 
8971  next = originalPosition.parent.children().eq( originalPosition.index );
8972  // Don't try to place the dialog next to itself (#8613)
8973  if ( next.length && next[0] !== this.element[0] ) {
8974  next.before( this.element );
8975  } else {
8976  originalPosition.parent.append( this.element );
8977  }
8978  },
8979 
8980  widget: function() {
8981  return this.uiDialog;
8982  },
8983 
8984  disable: $.noop,
8985  enable: $.noop,
8986 
8987  close: function( event ) {
8988  var that = this;
8989 
8990  if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
8991  return;
8992  }
8993 
8994  this._isOpen = false;
8995  this._destroyOverlay();
8996 
8997  if ( !this.opener.filter(":focusable").focus().length ) {
8998  // Hiding a focused element doesn't trigger blur in WebKit
8999  // so in case we have nothing to focus on, explicitly blur the active element
9000  // https://bugs.webkit.org/show_bug.cgi?id=47182
9001  $( this.document[0].activeElement ).blur();
9002  }
9003 
9004  this._hide( this.uiDialog, this.options.hide, function() {
9005  that._trigger( "close", event );
9006  });
9007  },
9008 
9009  isOpen: function() {
9010  return this._isOpen;
9011  },
9012 
9013  moveToTop: function() {
9014  this._moveToTop();
9015  },
9016 
9017  _moveToTop: function( event, silent ) {
9018  var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9019  if ( moved && !silent ) {
9020  this._trigger( "focus", event );
9021  }
9022  return moved;
9023  },
9024 
9025  open: function() {
9026  var that = this;
9027  if ( this._isOpen ) {
9028  if ( this._moveToTop() ) {
9029  this._focusTabbable();
9030  }
9031  return;
9032  }
9033 
9034  this._isOpen = true;
9035  this.opener = $( this.document[0].activeElement );
9036 
9037  this._size();
9038  this._position();
9039  this._createOverlay();
9040  this._moveToTop( null, true );
9041  this._show( this.uiDialog, this.options.show, function() {
9042  that._focusTabbable();
9043  that._trigger("focus");
9044  });
9045 
9046  this._trigger("open");
9047  },
9048 
9049  _focusTabbable: function() {
9050  // Set focus to the first match:
9051  // 1. First element inside the dialog matching [autofocus]
9052  // 2. Tabbable element inside the content element
9053  // 3. Tabbable element inside the buttonpane
9054  // 4. The close button
9055  // 5. The dialog itself
9056  var hasFocus = this.element.find("[autofocus]");
9057  if ( !hasFocus.length ) {
9058  hasFocus = this.element.find(":tabbable");
9059  }
9060  if ( !hasFocus.length ) {
9061  hasFocus = this.uiDialogButtonPane.find(":tabbable");
9062  }
9063  if ( !hasFocus.length ) {
9064  hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9065  }
9066  if ( !hasFocus.length ) {
9067  hasFocus = this.uiDialog;
9068  }
9069  hasFocus.eq( 0 ).focus();
9070  },
9071 
9072  _keepFocus: function( event ) {
9073  function checkFocus() {
9074  var activeElement = this.document[0].activeElement,
9075  isActive = this.uiDialog[0] === activeElement ||
9076  $.contains( this.uiDialog[0], activeElement );
9077  if ( !isActive ) {
9078  this._focusTabbable();
9079  }
9080  }
9081  event.preventDefault();
9082  checkFocus.call( this );
9083  // support: IE
9084  // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9085  // so we check again later
9086  this._delay( checkFocus );
9087  },
9088 
9089  _createWrapper: function() {
9090  this.uiDialog = $("<div>")
9091  .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9092  this.options.dialogClass )
9093  .hide()
9094  .attr({
9095  // Setting tabIndex makes the div focusable
9096  tabIndex: -1,
9097  role: "dialog"
9098  })
9099  .appendTo( this._appendTo() );
9100 
9101  this._on( this.uiDialog, {
9102  keydown: function( event ) {
9103  if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9104  event.keyCode === $.ui.keyCode.ESCAPE ) {
9105  event.preventDefault();
9106  this.close( event );
9107  return;
9108  }
9109 
9110  // prevent tabbing out of dialogs
9111  if ( event.keyCode !== $.ui.keyCode.TAB ) {
9112  return;
9113  }
9114  var tabbables = this.uiDialog.find(":tabbable"),
9115  first = tabbables.filter(":first"),
9116  last = tabbables.filter(":last");
9117 
9118  if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9119  first.focus( 1 );
9120  event.preventDefault();
9121  } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9122  last.focus( 1 );
9123  event.preventDefault();
9124  }
9125  },
9126  mousedown: function( event ) {
9127  if ( this._moveToTop( event ) ) {
9128  this._focusTabbable();
9129  }
9130  }
9131  });
9132 
9133  // We assume that any existing aria-describedby attribute means
9134  // that the dialog content is marked up properly
9135  // otherwise we brute force the content as the description
9136  if ( !this.element.find("[aria-describedby]").length ) {
9137  this.uiDialog.attr({
9138  "aria-describedby": this.element.uniqueId().attr("id")
9139  });
9140  }
9141  },
9142 
9143  _createTitlebar: function() {
9144  var uiDialogTitle;
9145 
9146  this.uiDialogTitlebar = $("<div>")
9147  .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9148  .prependTo( this.uiDialog );
9149  this._on( this.uiDialogTitlebar, {
9150  mousedown: function( event ) {
9151  // Don't prevent click on close button (#8838)
9152  // Focusing a dialog that is partially scrolled out of view
9153  // causes the browser to scroll it into view, preventing the click event
9154  if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9155  // Dialog isn't getting focus when dragging (#8063)
9156  this.uiDialog.focus();
9157  }
9158  }
9159  });
9160 
9161  this.uiDialogTitlebarClose = $("<button></button>")
9162  .button({
9163  label: this.options.closeText,
9164  icons: {
9165  primary: "ui-icon-closethick"
9166  },
9167  text: false
9168  })
9169  .addClass("ui-dialog-titlebar-close")
9170  .appendTo( this.uiDialogTitlebar );
9171  this._on( this.uiDialogTitlebarClose, {
9172  click: function( event ) {
9173  event.preventDefault();
9174  this.close( event );
9175  }
9176  });
9177 
9178  uiDialogTitle = $("<span>")
9179  .uniqueId()
9180  .addClass("ui-dialog-title")
9181  .prependTo( this.uiDialogTitlebar );
9182  this._title( uiDialogTitle );
9183 
9184  this.uiDialog.attr({
9185  "aria-labelledby": uiDialogTitle.attr("id")
9186  });
9187  },
9188 
9189  _title: function( title ) {
9190  if ( !this.options.title ) {
9191  title.html("&#160;");
9192  }
9193  title.text( this.options.title );
9194  },
9195 
9196  _createButtonPane: function() {
9197  this.uiDialogButtonPane = $("<div>")
9198  .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
9199 
9200  this.uiButtonSet = $("<div>")
9201  .addClass("ui-dialog-buttonset")
9202  .appendTo( this.uiDialogButtonPane );
9203 
9204  this._createButtons();
9205  },
9206 
9207  _createButtons: function() {
9208  var that = this,
9209  buttons = this.options.buttons;
9210 
9211  // if we already have a button pane, remove it
9212  this.uiDialogButtonPane.remove();
9213  this.uiButtonSet.empty();
9214 
9215  if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
9216  this.uiDialog.removeClass("ui-dialog-buttons");
9217  return;
9218  }
9219 
9220  $.each( buttons, function( name, props ) {
9221  var click, buttonOptions;
9222  props = $.isFunction( props ) ?
9223  { click: props, text: name } :
9224  props;
9225  // Default to a non-submitting button
9226  props = $.extend( { type: "button" }, props );
9227  // Change the context for the click callback to be the main element
9228  click = props.click;
9229  props.click = function() {
9230  click.apply( that.element[0], arguments );
9231  };
9232  buttonOptions = {
9233  icons: props.icons,
9234  text: props.showText
9235  };
9236  delete props.icons;
9237  delete props.showText;
9238  $( "<button></button>", props )
9239  .button( buttonOptions )
9240  .appendTo( that.uiButtonSet );
9241  });
9242  this.uiDialog.addClass("ui-dialog-buttons");
9243  this.uiDialogButtonPane.appendTo( this.uiDialog );
9244  },
9245 
9246  _makeDraggable: function() {
9247  var that = this,
9248  options = this.options;
9249 
9250  function filteredUi( ui ) {
9251  return {
9252  position: ui.position,
9253  offset: ui.offset
9254  };
9255  }
9256 
9257  this.uiDialog.draggable({
9258  cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
9259  handle: ".ui-dialog-titlebar",
9260  containment: "document",
9261  start: function( event, ui ) {
9262  $( this ).addClass("ui-dialog-dragging");
9263  that._blockFrames();
9264  that._trigger( "dragStart", event, filteredUi( ui ) );
9265  },
9266  drag: function( event, ui ) {
9267  that._trigger( "drag", event, filteredUi( ui ) );
9268  },
9269  stop: function( event, ui ) {
9270  options.position = [
9271  ui.position.left - that.document.scrollLeft(),
9272  ui.position.top - that.document.scrollTop()
9273  ];
9274  $( this ).removeClass("ui-dialog-dragging");
9275  that._unblockFrames();
9276  that._trigger( "dragStop", event, filteredUi( ui ) );
9277  }
9278  });
9279  },
9280 
9281  _makeResizable: function() {
9282  var that = this,
9283  options = this.options,
9284  handles = options.resizable,
9285  // .ui-resizable has position: relative defined in the stylesheet
9286  // but dialogs have to use absolute or fixed positioning
9287  position = this.uiDialog.css("position"),
9288  resizeHandles = typeof handles === "string" ?
9289  handles :
9290  "n,e,s,w,se,sw,ne,nw";
9291 
9292  function filteredUi( ui ) {
9293  return {
9294  originalPosition: ui.originalPosition,
9295  originalSize: ui.originalSize,
9296  position: ui.position,
9297  size: ui.size
9298  };
9299  }
9300 
9301  this.uiDialog.resizable({
9302  cancel: ".ui-dialog-content",
9303  containment: "document",
9304  alsoResize: this.element,
9305  maxWidth: options.maxWidth,
9306  maxHeight: options.maxHeight,
9307  minWidth: options.minWidth,
9308  minHeight: this._minHeight(),
9309  handles: resizeHandles,
9310  start: function( event, ui ) {
9311  $( this ).addClass("ui-dialog-resizing");
9312  that._blockFrames();
9313  that._trigger( "resizeStart", event, filteredUi( ui ) );
9314  },
9315  resize: function( event, ui ) {
9316  that._trigger( "resize", event, filteredUi( ui ) );
9317  },
9318  stop: function( event, ui ) {
9319  options.height = $( this ).height();
9320  options.width = $( this ).width();
9321  $( this ).removeClass("ui-dialog-resizing");
9322  that._unblockFrames();
9323  that._trigger( "resizeStop", event, filteredUi( ui ) );
9324  }
9325  })
9326  .css( "position", position );
9327  },
9328 
9329  _minHeight: function() {
9330  var options = this.options;
9331 
9332  return options.height === "auto" ?
9333  options.minHeight :
9334  Math.min( options.minHeight, options.height );
9335  },
9336 
9337  _position: function() {
9338  // Need to show the dialog to get the actual offset in the position plugin
9339  var isVisible = this.uiDialog.is(":visible");
9340  if ( !isVisible ) {
9341  this.uiDialog.show();
9342  }
9343  this.uiDialog.position( this.options.position );
9344  if ( !isVisible ) {
9345  this.uiDialog.hide();
9346  }
9347  },
9348 
9349  _setOptions: function( options ) {
9350  var that = this,
9351  resize = false,
9352  resizableOptions = {};
9353 
9354  $.each( options, function( key, value ) {
9355  that._setOption( key, value );
9356 
9357  if ( key in sizeRelatedOptions ) {
9358  resize = true;
9359  }
9360  if ( key in resizableRelatedOptions ) {
9361  resizableOptions[ key ] = value;
9362  }
9363  });
9364 
9365  if ( resize ) {
9366  this._size();
9367  this._position();
9368  }
9369  if ( this.uiDialog.is(":data(ui-resizable)") ) {
9370  this.uiDialog.resizable( "option", resizableOptions );
9371  }
9372  },
9373 
9374  _setOption: function( key, value ) {
9375  /*jshint maxcomplexity:15*/
9376  var isDraggable, isResizable,
9377  uiDialog = this.uiDialog;
9378 
9379  if ( key === "dialogClass" ) {
9380  uiDialog
9381  .removeClass( this.options.dialogClass )
9382  .addClass( value );
9383  }
9384 
9385  if ( key === "disabled" ) {
9386  return;
9387  }
9388 
9389  this._super( key, value );
9390 
9391  if ( key === "appendTo" ) {
9392  this.uiDialog.appendTo( this._appendTo() );
9393  }
9394 
9395  if ( key === "buttons" ) {
9396  this._createButtons();
9397  }
9398 
9399  if ( key === "closeText" ) {
9400  this.uiDialogTitlebarClose.button({
9401  // Ensure that we always pass a string
9402  label: "" + value
9403  });
9404  }
9405 
9406  if ( key === "draggable" ) {
9407  isDraggable = uiDialog.is(":data(ui-draggable)");
9408  if ( isDraggable && !value ) {
9409  uiDialog.draggable("destroy");
9410  }
9411 
9412  if ( !isDraggable && value ) {
9413  this._makeDraggable();
9414  }
9415  }
9416 
9417  if ( key === "position" ) {
9418  this._position();
9419  }
9420 
9421  if ( key === "resizable" ) {
9422  // currently resizable, becoming non-resizable
9423  isResizable = uiDialog.is(":data(ui-resizable)");
9424  if ( isResizable && !value ) {
9425  uiDialog.resizable("destroy");
9426  }
9427 
9428  // currently resizable, changing handles
9429  if ( isResizable && typeof value === "string" ) {
9430  uiDialog.resizable( "option", "handles", value );
9431  }
9432 
9433  // currently non-resizable, becoming resizable
9434  if ( !isResizable && value !== false ) {
9435  this._makeResizable();
9436  }
9437  }
9438 
9439  if ( key === "title" ) {
9440  this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
9441  }
9442  },
9443 
9444  _size: function() {
9445  // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9446  // divs will both have width and height set, so we need to reset them
9447  var nonContentHeight, minContentHeight, maxContentHeight,
9448  options = this.options;
9449 
9450  // Reset content sizing
9451  this.element.show().css({
9452  width: "auto",
9453  minHeight: 0,
9454  maxHeight: "none",
9455  height: 0
9456  });
9457 
9458  if ( options.minWidth > options.width ) {
9459  options.width = options.minWidth;
9460  }
9461 
9462  // reset wrapper sizing
9463  // determine the height of all the non-content elements
9464  nonContentHeight = this.uiDialog.css({
9465  height: "auto",
9466  width: options.width
9467  })
9468  .outerHeight();
9469  minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9470  maxContentHeight = typeof options.maxHeight === "number" ?
9471  Math.max( 0, options.maxHeight - nonContentHeight ) :
9472  "none";
9473 
9474  if ( options.height === "auto" ) {
9475  this.element.css({
9476  minHeight: minContentHeight,
9477  maxHeight: maxContentHeight,
9478  height: "auto"
9479  });
9480  } else {
9481  this.element.height( Math.max( 0, options.height - nonContentHeight ) );
9482  }
9483 
9484  if (this.uiDialog.is(":data(ui-resizable)") ) {
9485  this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
9486  }
9487  },
9488 
9489  _blockFrames: function() {
9490  this.iframeBlocks = this.document.find( "iframe" ).map(function() {
9491  var iframe = $( this );
9492 
9493  return $( "<div>" )
9494  .css({
9495  position: "absolute",
9496  width: iframe.outerWidth(),
9497  height: iframe.outerHeight()
9498  })
9499  .appendTo( iframe.parent() )
9500  .offset( iframe.offset() )[0];
9501  });
9502  },
9503 
9504  _unblockFrames: function() {
9505  if ( this.iframeBlocks ) {
9506  this.iframeBlocks.remove();
9507  delete this.iframeBlocks;
9508  }
9509  },
9510 
9511  _allowInteraction: function( event ) {
9512  if ( $( event.target ).closest(".ui-dialog").length ) {
9513  return true;
9514  }
9515 
9516  // TODO: Remove hack when datepicker implements
9517  // the .ui-front logic (#8989)
9518  return !!$( event.target ).closest(".ui-datepicker").length;
9519  },
9520 
9521  _createOverlay: function() {
9522  if ( !this.options.modal ) {
9523  return;
9524  }
9525 
9526  var that = this,
9527  widgetFullName = this.widgetFullName;
9528  if ( !$.ui.dialog.overlayInstances ) {
9529  // Prevent use of anchors and inputs.
9530  // We use a delay in case the overlay is created from an
9531  // event that we're going to be cancelling. (#2804)
9532  this._delay(function() {
9533  // Handle .dialog().dialog("close") (#4065)
9534  if ( $.ui.dialog.overlayInstances ) {
9535  this.document.bind( "focusin.dialog", function( event ) {
9536  if ( !that._allowInteraction( event ) ) {
9537  event.preventDefault();
9538  $(".ui-dialog:visible:last .ui-dialog-content")
9539  .data( widgetFullName )._focusTabbable();
9540  }
9541  });
9542  }
9543  });
9544  }
9545 
9546  this.overlay = $("<div>")
9547  .addClass("ui-widget-overlay ui-front")
9548  .appendTo( this._appendTo() );
9549  this._on( this.overlay, {
9550  mousedown: "_keepFocus"
9551  });
9552  $.ui.dialog.overlayInstances++;
9553  },
9554 
9555  _destroyOverlay: function() {
9556  if ( !this.options.modal ) {
9557  return;
9558  }
9559 
9560  if ( this.overlay ) {
9561  $.ui.dialog.overlayInstances--;
9562 
9563  if ( !$.ui.dialog.overlayInstances ) {
9564  this.document.unbind( "focusin.dialog" );
9565  }
9566  this.overlay.remove();
9567  this.overlay = null;
9568  }
9569  }
9570 });
9571 
9572 $.ui.dialog.overlayInstances = 0;
9573 
9574 // DEPRECATED
9575 if ( $.uiBackCompat !== false ) {
9576  // position option with array notation
9577  // just override with old implementation
9578  $.widget( "ui.dialog", $.ui.dialog, {
9579  _position: function() {
9580  var position = this.options.position,
9581  myAt = [],
9582  offset = [ 0, 0 ],
9583  isVisible;
9584 
9585  if ( position ) {
9586  if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
9587  myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
9588  if ( myAt.length === 1 ) {
9589  myAt[1] = myAt[0];
9590  }
9591 
9592  $.each( [ "left", "top" ], function( i, offsetPosition ) {
9593  if ( +myAt[ i ] === myAt[ i ] ) {
9594  offset[ i ] = myAt[ i ];
9595  myAt[ i ] = offsetPosition;
9596  }
9597  });
9598 
9599  position = {
9600  my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
9601  myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
9602  at: myAt.join(" ")
9603  };
9604  }
9605 
9606  position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
9607  } else {
9608  position = $.ui.dialog.prototype.options.position;
9609  }
9610 
9611  // need to show the dialog to get the actual offset in the position plugin
9612  isVisible = this.uiDialog.is(":visible");
9613  if ( !isVisible ) {
9614  this.uiDialog.show();
9615  }
9616  this.uiDialog.position( position );
9617  if ( !isVisible ) {
9618  this.uiDialog.hide();
9619  }
9620  }
9621  });
9622 }
9623 
9624 }( jQuery ) );
9625 (function( $, undefined ) {
9626 
9627 $.widget( "ui.menu", {
9628  version: "1.10.3",
9629  defaultElement: "<ul>",
9630  delay: 300,
9631  options: {
9632  icons: {
9633  submenu: "ui-icon-carat-1-e"
9634  },
9635  menus: "ul",
9636  position: {
9637  my: "left top",
9638  at: "right top"
9639  },
9640  role: "menu",
9641 
9642  // callbacks
9643  blur: null,
9644  focus: null,
9645  select: null
9646  },
9647 
9648  _create: function() {
9649  this.activeMenu = this.element;
9650  // flag used to prevent firing of the click handler
9651  // as the event bubbles up through nested menus
9652  this.mouseHandled = false;
9653  this.element
9654  .uniqueId()
9655  .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9656  .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
9657  .attr({
9658  role: this.options.role,
9659  tabIndex: 0
9660  })
9661  // need to catch all clicks on disabled menu
9662  // not possible through _on
9663  .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
9664  if ( this.options.disabled ) {
9665  event.preventDefault();
9666  }
9667  }, this ));
9668 
9669  if ( this.options.disabled ) {
9670  this.element
9671  .addClass( "ui-state-disabled" )
9672  .attr( "aria-disabled", "true" );
9673  }
9674 
9675  this._on({
9676  // Prevent focus from sticking to links inside menu after clicking
9677  // them (focus should always stay on UL during navigation).
9678  "mousedown .ui-menu-item > a": function( event ) {
9679  event.preventDefault();
9680  },
9681  "click .ui-state-disabled > a": function( event ) {
9682  event.preventDefault();
9683  },
9684  "click .ui-menu-item:has(a)": function( event ) {
9685  var target = $( event.target ).closest( ".ui-menu-item" );
9686  if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
9687  this.mouseHandled = true;
9688 
9689  this.select( event );
9690  // Open submenu on click
9691  if ( target.has( ".ui-menu" ).length ) {
9692  this.expand( event );
9693  } else if ( !this.element.is( ":focus" ) ) {
9694  // Redirect focus to the menu
9695  this.element.trigger( "focus", [ true ] );
9696 
9697  // If the active item is on the top level, let it stay active.
9698  // Otherwise, blur the active item since it is no longer visible.
9699  if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
9700  clearTimeout( this.timer );
9701  }
9702  }
9703  }
9704  },
9705  "mouseenter .ui-menu-item": function( event ) {
9706  var target = $( event.currentTarget );
9707  // Remove ui-state-active class from siblings of the newly focused menu item
9708  // to avoid a jump caused by adjacent elements both having a class with a border
9709  target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
9710  this.focus( event, target );
9711  },
9712  mouseleave: "collapseAll",
9713  "mouseleave .ui-menu": "collapseAll",
9714  focus: function( event, keepActiveItem ) {
9715  // If there's already an active item, keep it active
9716  // If not, activate the first item
9717  var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
9718 
9719  if ( !keepActiveItem ) {
9720  this.focus( event, item );
9721  }
9722  },
9723  blur: function( event ) {
9724  this._delay(function() {
9725  if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
9726  this.collapseAll( event );
9727  }
9728  });
9729  },
9730  keydown: "_keydown"
9731  });
9732 
9733  this.refresh();
9734 
9735  // Clicks outside of a menu collapse any open menus
9736  this._on( this.document, {
9737  click: function( event ) {
9738  if ( !$( event.target ).closest( ".ui-menu" ).length ) {
9739  this.collapseAll( event );
9740  }
9741 
9742  // Reset the mouseHandled flag
9743  this.mouseHandled = false;
9744  }
9745  });
9746  },
9747 
9748  _destroy: function() {
9749  // Destroy (sub)menus
9750  this.element
9751  .removeAttr( "aria-activedescendant" )
9752  .find( ".ui-menu" ).addBack()
9753  .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
9754  .removeAttr( "role" )
9755  .removeAttr( "tabIndex" )
9756  .removeAttr( "aria-labelledby" )
9757  .removeAttr( "aria-expanded" )
9758  .removeAttr( "aria-hidden" )
9759  .removeAttr( "aria-disabled" )
9760  .removeUniqueId()
9761  .show();
9762 
9763  // Destroy menu items
9764  this.element.find( ".ui-menu-item" )
9765  .removeClass( "ui-menu-item" )
9766  .removeAttr( "role" )
9767  .removeAttr( "aria-disabled" )
9768  .children( "a" )
9769  .removeUniqueId()
9770  .removeClass( "ui-corner-all ui-state-hover" )
9771  .removeAttr( "tabIndex" )
9772  .removeAttr( "role" )
9773  .removeAttr( "aria-haspopup" )
9774  .children().each( function() {
9775  var elem = $( this );
9776  if ( elem.data( "ui-menu-submenu-carat" ) ) {
9777  elem.remove();
9778  }
9779  });
9780 
9781  // Destroy menu dividers
9782  this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
9783  },
9784 
9785  _keydown: function( event ) {
9786  /*jshint maxcomplexity:20*/
9787  var match, prev, character, skip, regex,
9788  preventDefault = true;
9789 
9790  function escape( value ) {
9791  return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
9792  }
9793 
9794  switch ( event.keyCode ) {
9795  case $.ui.keyCode.PAGE_UP:
9796  this.previousPage( event );
9797  break;
9798  case $.ui.keyCode.PAGE_DOWN:
9799  this.nextPage( event );
9800  break;
9801  case $.ui.keyCode.HOME:
9802  this._move( "first", "first", event );
9803  break;
9804  case $.ui.keyCode.END:
9805  this._move( "last", "last", event );
9806  break;
9807  case $.ui.keyCode.UP:
9808  this.previous( event );
9809  break;
9810  case $.ui.keyCode.DOWN:
9811  this.next( event );
9812  break;
9813  case $.ui.keyCode.LEFT:
9814  this.collapse( event );
9815  break;
9816  case $.ui.keyCode.RIGHT:
9817  if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
9818  this.expand( event );
9819  }
9820  break;
9821  case $.ui.keyCode.ENTER:
9822  case $.ui.keyCode.SPACE:
9823  this._activate( event );
9824  break;
9825  case $.ui.keyCode.ESCAPE:
9826  this.collapse( event );
9827  break;
9828  default:
9829  preventDefault = false;
9830  prev = this.previousFilter || "";
9831  character = String.fromCharCode( event.keyCode );
9832  skip = false;
9833 
9834  clearTimeout( this.filterTimer );
9835 
9836  if ( character === prev ) {
9837  skip = true;
9838  } else {
9839  character = prev + character;
9840  }
9841 
9842  regex = new RegExp( "^" + escape( character ), "i" );
9843  match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9844  return regex.test( $( this ).children( "a" ).text() );
9845  });
9846  match = skip && match.index( this.active.next() ) !== -1 ?
9847  this.active.nextAll( ".ui-menu-item" ) :
9848  match;
9849 
9850  // If no matches on the current filter, reset to the last character pressed
9851  // to move down the menu to the first item that starts with that character
9852  if ( !match.length ) {
9853  character = String.fromCharCode( event.keyCode );
9854  regex = new RegExp( "^" + escape( character ), "i" );
9855  match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
9856  return regex.test( $( this ).children( "a" ).text() );
9857  });
9858  }
9859 
9860  if ( match.length ) {
9861  this.focus( event, match );
9862  if ( match.length > 1 ) {
9863  this.previousFilter = character;
9864  this.filterTimer = this._delay(function() {
9865  delete this.previousFilter;
9866  }, 1000 );
9867  } else {
9868  delete this.previousFilter;
9869  }
9870  } else {
9871  delete this.previousFilter;
9872  }
9873  }
9874 
9875  if ( preventDefault ) {
9876  event.preventDefault();
9877  }
9878  },
9879 
9880  _activate: function( event ) {
9881  if ( !this.active.is( ".ui-state-disabled" ) ) {
9882  if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
9883  this.expand( event );
9884  } else {
9885  this.select( event );
9886  }
9887  }
9888  },
9889 
9890  refresh: function() {
9891  var menus,
9892  icon = this.options.icons.submenu,
9893  submenus = this.element.find( this.options.menus );
9894 
9895  // Initialize nested menus
9896  submenus.filter( ":not(.ui-menu)" )
9897  .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
9898  .hide()
9899  .attr({
9900  role: this.options.role,
9901  "aria-hidden": "true",
9902  "aria-expanded": "false"
9903  })
9904  .each(function() {
9905  var menu = $( this ),
9906  item = menu.prev( "a" ),
9907  submenuCarat = $( "<span>" )
9908  .addClass( "ui-menu-icon ui-icon " + icon )
9909  .data( "ui-menu-submenu-carat", true );
9910 
9911  item
9912  .attr( "aria-haspopup", "true" )
9913  .prepend( submenuCarat );
9914  menu.attr( "aria-labelledby", item.attr( "id" ) );
9915  });
9916 
9917  menus = submenus.add( this.element );
9918 
9919  // Don't refresh list items that are already adapted
9920  menus.children( ":not(.ui-menu-item):has(a)" )
9921  .addClass( "ui-menu-item" )
9922  .attr( "role", "presentation" )
9923  .children( "a" )
9924  .uniqueId()
9925  .addClass( "ui-corner-all" )
9926  .attr({
9927  tabIndex: -1,
9928  role: this._itemRole()
9929  });
9930 
9931  // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
9932  menus.children( ":not(.ui-menu-item)" ).each(function() {
9933  var item = $( this );
9934  // hyphen, em dash, en dash
9935  if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
9936  item.addClass( "ui-widget-content ui-menu-divider" );
9937  }
9938  });
9939 
9940  // Add aria-disabled attribute to any disabled menu item
9941  menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
9942 
9943  // If the active item has been removed, blur the menu
9944  if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
9945  this.blur();
9946  }
9947  },
9948 
9949  _itemRole: function() {
9950  return {
9951  menu: "menuitem",
9952  listbox: "option"
9953  }[ this.options.role ];
9954  },
9955 
9956  _setOption: function( key, value ) {
9957  if ( key === "icons" ) {
9958  this.element.find( ".ui-menu-icon" )
9959  .removeClass( this.options.icons.submenu )
9960  .addClass( value.submenu );
9961  }
9962  this._super( key, value );
9963  },
9964 
9965  focus: function( event, item ) {
9966  var nested, focused;
9967  this.blur( event, event && event.type === "focus" );
9968 
9969  this._scrollIntoView( item );
9970 
9971  this.active = item.first();
9972  focused = this.active.children( "a" ).addClass( "ui-state-focus" );
9973  // Only update aria-activedescendant if there's a role
9974  // otherwise we assume focus is managed elsewhere
9975  if ( this.options.role ) {
9976  this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
9977  }
9978 
9979  // Highlight active parent menu item, if any
9980  this.active
9981  .parent()
9982  .closest( ".ui-menu-item" )
9983  .children( "a:first" )
9984  .addClass( "ui-state-active" );
9985 
9986  if ( event && event.type === "keydown" ) {
9987  this._close();
9988  } else {
9989  this.timer = this._delay(function() {
9990  this._close();
9991  }, this.delay );
9992  }
9993 
9994  nested = item.children( ".ui-menu" );
9995  if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
9996  this._startOpening(nested);
9997  }
9998  this.activeMenu = item.parent();
9999 
10000  this._trigger( "focus", event, { item: item } );
10001  },
10002 
10003  _scrollIntoView: function( item ) {
10004  var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
10005  if ( this._hasScroll() ) {
10006  borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
10007  paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
10008  offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
10009  scroll = this.activeMenu.scrollTop();
10010  elementHeight = this.activeMenu.height();
10011  itemHeight = item.height();
10012 
10013  if ( offset < 0 ) {
10014  this.activeMenu.scrollTop( scroll + offset );
10015  } else if ( offset + itemHeight > elementHeight ) {
10016  this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
10017  }
10018  }
10019  },
10020 
10021  blur: function( event, fromFocus ) {
10022  if ( !fromFocus ) {
10023  clearTimeout( this.timer );
10024  }
10025 
10026  if ( !this.active ) {
10027  return;
10028  }
10029 
10030  this.active.children( "a" ).removeClass( "ui-state-focus" );
10031  this.active = null;
10032 
10033  this._trigger( "blur", event, { item: this.active } );
10034  },
10035 
10036  _startOpening: function( submenu ) {
10037  clearTimeout( this.timer );
10038 
10039  // Don't open if already open fixes a Firefox bug that caused a .5 pixel
10040  // shift in the submenu position when mousing over the carat icon
10041  if ( submenu.attr( "aria-hidden" ) !== "true" ) {
10042  return;
10043  }
10044 
10045  this.timer = this._delay(function() {
10046  this._close();
10047  this._open( submenu );
10048  }, this.delay );
10049  },
10050 
10051  _open: function( submenu ) {
10052  var position = $.extend({
10053  of: this.active
10054  }, this.options.position );
10055 
10056  clearTimeout( this.timer );
10057  this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
10058  .hide()
10059  .attr( "aria-hidden", "true" );
10060 
10061  submenu
10062  .show()
10063  .removeAttr( "aria-hidden" )
10064  .attr( "aria-expanded", "true" )
10065  .position( position );
10066  },
10067 
10068  collapseAll: function( event, all ) {
10069  clearTimeout( this.timer );
10070  this.timer = this._delay(function() {
10071  // If we were passed an event, look for the submenu that contains the event
10072  var currentMenu = all ? this.element :
10073  $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
10074 
10075  // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
10076  if ( !currentMenu.length ) {
10077  currentMenu = this.element;
10078  }
10079 
10080  this._close( currentMenu );
10081 
10082  this.blur( event );
10083  this.activeMenu = currentMenu;
10084  }, this.delay );
10085  },
10086 
10087  // With no arguments, closes the currently active menu - if nothing is active
10088  // it closes all menus. If passed an argument, it will search for menus BELOW
10089  _close: function( startMenu ) {
10090  if ( !startMenu ) {
10091  startMenu = this.active ? this.active.parent() : this.element;
10092  }
10093 
10094  startMenu
10095  .find( ".ui-menu" )
10096  .hide()
10097  .attr( "aria-hidden", "true" )
10098  .attr( "aria-expanded", "false" )
10099  .end()
10100  .find( "a.ui-state-active" )
10101  .removeClass( "ui-state-active" );
10102  },
10103 
10104  collapse: function( event ) {
10105  var newItem = this.active &&
10106  this.active.parent().closest( ".ui-menu-item", this.element );
10107  if ( newItem && newItem.length ) {
10108  this._close();
10109  this.focus( event, newItem );
10110  }
10111  },
10112 
10113  expand: function( event ) {
10114  var newItem = this.active &&
10115  this.active
10116  .children( ".ui-menu " )
10117  .children( ".ui-menu-item" )
10118  .first();
10119 
10120  if ( newItem && newItem.length ) {
10121  this._open( newItem.parent() );
10122 
10123  // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
10124  this._delay(function() {
10125  this.focus( event, newItem );
10126  });
10127  }
10128  },
10129 
10130  next: function( event ) {
10131  this._move( "next", "first", event );
10132  },
10133 
10134  previous: function( event ) {
10135  this._move( "prev", "last", event );
10136  },
10137 
10138  isFirstItem: function() {
10139  return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
10140  },
10141 
10142  isLastItem: function() {
10143  return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
10144  },
10145 
10146  _move: function( direction, filter, event ) {
10147  var next;
10148  if ( this.active ) {
10149  if ( direction === "first" || direction === "last" ) {
10150  next = this.active
10151  [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
10152  .eq( -1 );
10153  } else {
10154  next = this.active
10155  [ direction + "All" ]( ".ui-menu-item" )
10156  .eq( 0 );
10157  }
10158  }
10159  if ( !next || !next.length || !this.active ) {
10160  next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
10161  }
10162 
10163  this.focus( event, next );
10164  },
10165 
10166  nextPage: function( event ) {
10167  var item, base, height;
10168 
10169  if ( !this.active ) {
10170  this.next( event );
10171  return;
10172  }
10173  if ( this.isLastItem() ) {
10174  return;
10175  }
10176  if ( this._hasScroll() ) {
10177  base = this.active.offset().top;
10178  height = this.element.height();
10179  this.active.nextAll( ".ui-menu-item" ).each(function() {
10180  item = $( this );
10181  return item.offset().top - base - height < 0;
10182  });
10183 
10184  this.focus( event, item );
10185  } else {
10186  this.focus( event, this.activeMenu.children( ".ui-menu-item" )
10187  [ !this.active ? "first" : "last" ]() );
10188  }
10189  },
10190 
10191  previousPage: function( event ) {
10192  var item, base, height;
10193  if ( !this.active ) {
10194  this.next( event );
10195  return;
10196  }
10197  if ( this.isFirstItem() ) {
10198  return;
10199  }
10200  if ( this._hasScroll() ) {
10201  base = this.active.offset().top;
10202  height = this.element.height();
10203  this.active.prevAll( ".ui-menu-item" ).each(function() {
10204  item = $( this );
10205  return item.offset().top - base + height > 0;
10206  });
10207 
10208  this.focus( event, item );
10209  } else {
10210  this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
10211  }
10212  },
10213 
10214  _hasScroll: function() {
10215  return this.element.outerHeight() < this.element.prop( "scrollHeight" );
10216  },
10217 
10218  select: function( event ) {
10219  // TODO: It should never be possible to not have an active item at this
10220  // point, but the tests don't trigger mouseenter before click.
10221  this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
10222  var ui = { item: this.active };
10223  if ( !this.active.has( ".ui-menu" ).length ) {
10224  this.collapseAll( event, true );
10225  }
10226  this._trigger( "select", event, ui );
10227  }
10228 });
10229 
10230 }( jQuery ));
10231 (function( $, undefined ) {
10232 
10233 $.widget( "ui.progressbar", {
10234  version: "1.10.3",
10235  options: {
10236  max: 100,
10237  value: 0,
10238 
10239  change: null,
10240  complete: null
10241  },
10242 
10243  min: 0,
10244 
10245  _create: function() {
10246  // Constrain initial value
10247  this.oldValue = this.options.value = this._constrainedValue();
10248 
10249  this.element
10250  .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10251  .attr({
10252  // Only set static values, aria-valuenow and aria-valuemax are
10253  // set inside _refreshValue()
10254  role: "progressbar",
10255  "aria-valuemin": this.min
10256  });
10257 
10258  this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10259  .appendTo( this.element );
10260 
10261  this._refreshValue();
10262  },
10263 
10264  _destroy: function() {
10265  this.element
10266  .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10267  .removeAttr( "role" )
10268  .removeAttr( "aria-valuemin" )
10269  .removeAttr( "aria-valuemax" )
10270  .removeAttr( "aria-valuenow" );
10271 
10272  this.valueDiv.remove();
10273  },
10274 
10275  value: function( newValue ) {
10276  if ( newValue === undefined ) {
10277  return this.options.value;
10278  }
10279 
10280  this.options.value = this._constrainedValue( newValue );
10281  this._refreshValue();
10282  },
10283 
10284  _constrainedValue: function( newValue ) {
10285  if ( newValue === undefined ) {
10286  newValue = this.options.value;
10287  }
10288 
10289  this.indeterminate = newValue === false;
10290 
10291  // sanitize value
10292  if ( typeof newValue !== "number" ) {
10293  newValue = 0;
10294  }
10295 
10296  return this.indeterminate ? false :
10297  Math.min( this.options.max, Math.max( this.min, newValue ) );
10298  },
10299 
10300  _setOptions: function( options ) {
10301  // Ensure "value" option is set after other values (like max)
10302  var value = options.value;
10303  delete options.value;
10304 
10305  this._super( options );
10306 
10307  this.options.value = this._constrainedValue( value );
10308  this._refreshValue();
10309  },
10310 
10311  _setOption: function( key, value ) {
10312  if ( key === "max" ) {
10313  // Don't allow a max less than min
10314  value = Math.max( this.min, value );
10315  }
10316 
10317  this._super( key, value );
10318  },
10319 
10320  _percentage: function() {
10321  return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
10322  },
10323 
10324  _refreshValue: function() {
10325  var value = this.options.value,
10326  percentage = this._percentage();
10327 
10328  this.valueDiv
10329  .toggle( this.indeterminate || value > this.min )
10330  .toggleClass( "ui-corner-right", value === this.options.max )
10331  .width( percentage.toFixed(0) + "%" );
10332 
10333  this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
10334 
10335  if ( this.indeterminate ) {
10336  this.element.removeAttr( "aria-valuenow" );
10337  if ( !this.overlayDiv ) {
10338  this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
10339  }
10340  } else {
10341  this.element.attr({
10342  "aria-valuemax": this.options.max,
10343  "aria-valuenow": value
10344  });
10345  if ( this.overlayDiv ) {
10346  this.overlayDiv.remove();
10347  this.overlayDiv = null;
10348  }
10349  }
10350 
10351  if ( this.oldValue !== value ) {
10352  this.oldValue = value;
10353  this._trigger( "change" );
10354  }
10355  if ( value === this.options.max ) {
10356  this._trigger( "complete" );
10357  }
10358  }
10359 });
10360 
10361 })( jQuery );
10362 (function( $, undefined ) {
10363 
10364 // number of pages in a slider
10365 // (how many times can you page up/down to go through the whole range)
10366 var numPages = 5;
10367 
10368 $.widget( "ui.slider", $.ui.mouse, {
10369  version: "1.10.3",
10370  widgetEventPrefix: "slide",
10371 
10372  options: {
10373  animate: false,
10374  distance: 0,
10375  max: 100,
10376  min: 0,
10377  orientation: "horizontal",
10378  range: false,
10379  step: 1,
10380  value: 0,
10381  values: null,
10382 
10383  // callbacks
10384  change: null,
10385  slide: null,
10386  start: null,
10387  stop: null
10388  },
10389 
10390  _create: function() {
10391  this._keySliding = false;
10392  this._mouseSliding = false;
10393  this._animateOff = true;
10394  this._handleIndex = null;
10395  this._detectOrientation();
10396  this._mouseInit();
10397 
10398  this.element
10399  .addClass( "ui-slider" +
10400  " ui-slider-" + this.orientation +
10401  " ui-widget" +
10402  " ui-widget-content" +
10403  " ui-corner-all");
10404 
10405  this._refresh();
10406  this._setOption( "disabled", this.options.disabled );
10407 
10408  this._animateOff = false;
10409  },
10410 
10411  _refresh: function() {
10412  this._createRange();
10413  this._createHandles();
10414  this._setupEvents();
10415  this._refreshValue();
10416  },
10417 
10418  _createHandles: function() {
10419  var i, handleCount,
10420  options = this.options,
10421  existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10422  handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10423  handles = [];
10424 
10425  handleCount = ( options.values && options.values.length ) || 1;
10426 
10427  if ( existingHandles.length > handleCount ) {
10428  existingHandles.slice( handleCount ).remove();
10429  existingHandles = existingHandles.slice( 0, handleCount );
10430  }
10431 
10432  for ( i = existingHandles.length; i < handleCount; i++ ) {
10433  handles.push( handle );
10434  }
10435 
10436  this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
10437 
10438  this.handle = this.handles.eq( 0 );
10439 
10440  this.handles.each(function( i ) {
10441  $( this ).data( "ui-slider-handle-index", i );
10442  });
10443  },
10444 
10445  _createRange: function() {
10446  var options = this.options,
10447  classes = "";
10448 
10449  if ( options.range ) {
10450  if ( options.range === true ) {
10451  if ( !options.values ) {
10452  options.values = [ this._valueMin(), this._valueMin() ];
10453  } else if ( options.values.length && options.values.length !== 2 ) {
10454  options.values = [ options.values[0], options.values[0] ];
10455  } else if ( $.isArray( options.values ) ) {
10456  options.values = options.values.slice(0);
10457  }
10458  }
10459 
10460  if ( !this.range || !this.range.length ) {
10461  this.range = $( "<div></div>" )
10462  .appendTo( this.element );
10463 
10464  classes = "ui-slider-range" +
10465  // note: this isn't the most fittingly semantic framework class for this element,
10466  // but worked best visually with a variety of themes
10467  " ui-widget-header ui-corner-all";
10468  } else {
10469  this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
10470  // Handle range switching from true to min/max
10471  .css({
10472  "left": "",
10473  "bottom": ""
10474  });
10475  }
10476 
10477  this.range.addClass( classes +
10478  ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
10479  } else {
10480  this.range = $([]);
10481  }
10482  },
10483 
10484  _setupEvents: function() {
10485  var elements = this.handles.add( this.range ).filter( "a" );
10486  this._off( elements );
10487  this._on( elements, this._handleEvents );
10488  this._hoverable( elements );
10489  this._focusable( elements );
10490  },
10491 
10492  _destroy: function() {
10493  this.handles.remove();
10494  this.range.remove();
10495 
10496  this.element
10497  .removeClass( "ui-slider" +
10498  " ui-slider-horizontal" +
10499  " ui-slider-vertical" +
10500  " ui-widget" +
10501  " ui-widget-content" +
10502  " ui-corner-all" );
10503 
10504  this._mouseDestroy();
10505  },
10506 
10507  _mouseCapture: function( event ) {
10508  var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
10509  that = this,
10510  o = this.options;
10511 
10512  if ( o.disabled ) {
10513  return false;
10514  }
10515 
10516  this.elementSize = {
10517  width: this.element.outerWidth(),
10518  height: this.element.outerHeight()
10519  };
10520  this.elementOffset = this.element.offset();
10521 
10522  position = { x: event.pageX, y: event.pageY };
10523  normValue = this._normValueFromMouse( position );
10524  distance = this._valueMax() - this._valueMin() + 1;
10525  this.handles.each(function( i ) {
10526  var thisDistance = Math.abs( normValue - that.values(i) );
10527  if (( distance > thisDistance ) ||
10528  ( distance === thisDistance &&
10529  (i === that._lastChangedValue || that.values(i) === o.min ))) {
10530  distance = thisDistance;
10531  closestHandle = $( this );
10532  index = i;
10533  }
10534  });
10535 
10536  allowed = this._start( event, index );
10537  if ( allowed === false ) {
10538  return false;
10539  }
10540  this._mouseSliding = true;
10541 
10542  this._handleIndex = index;
10543 
10544  closestHandle
10545  .addClass( "ui-state-active" )
10546  .focus();
10547 
10548  offset = closestHandle.offset();
10549  mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
10550  this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10551  left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10552  top: event.pageY - offset.top -
10553  ( closestHandle.height() / 2 ) -
10554  ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10555  ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10556  ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10557  };
10558 
10559  if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10560  this._slide( event, index, normValue );
10561  }
10562  this._animateOff = true;
10563  return true;
10564  },
10565 
10566  _mouseStart: function() {
10567  return true;
10568  },
10569 
10570  _mouseDrag: function( event ) {
10571  var position = { x: event.pageX, y: event.pageY },
10572  normValue = this._normValueFromMouse( position );
10573 
10574  this._slide( event, this._handleIndex, normValue );
10575 
10576  return false;
10577  },
10578 
10579  _mouseStop: function( event ) {
10580  this.handles.removeClass( "ui-state-active" );
10581  this._mouseSliding = false;
10582 
10583  this._stop( event, this._handleIndex );
10584  this._change( event, this._handleIndex );
10585 
10586  this._handleIndex = null;
10587  this._clickOffset = null;
10588  this._animateOff = false;
10589 
10590  return false;
10591  },
10592 
10593  _detectOrientation: function() {
10594  this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10595  },
10596 
10597  _normValueFromMouse: function( position ) {
10598  var pixelTotal,
10599  pixelMouse,
10600  percentMouse,
10601  valueTotal,
10602  valueMouse;
10603 
10604  if ( this.orientation === "horizontal" ) {
10605  pixelTotal = this.elementSize.width;
10606  pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10607  } else {
10608  pixelTotal = this.elementSize.height;
10609  pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10610  }
10611 
10612  percentMouse = ( pixelMouse / pixelTotal );
10613  if ( percentMouse > 1 ) {
10614  percentMouse = 1;
10615  }
10616  if ( percentMouse < 0 ) {
10617  percentMouse = 0;
10618  }
10619  if ( this.orientation === "vertical" ) {
10620  percentMouse = 1 - percentMouse;
10621  }
10622 
10623  valueTotal = this._valueMax() - this._valueMin();
10624  valueMouse = this._valueMin() + percentMouse * valueTotal;
10625 
10626  return this._trimAlignValue( valueMouse );
10627  },
10628 
10629  _start: function( event, index ) {
10630  var uiHash = {
10631  handle: this.handles[ index ],
10632  value: this.value()
10633  };
10634  if ( this.options.values && this.options.values.length ) {
10635  uiHash.value = this.values( index );
10636  uiHash.values = this.values();
10637  }
10638  return this._trigger( "start", event, uiHash );
10639  },
10640 
10641  _slide: function( event, index, newVal ) {
10642  var otherVal,
10643  newValues,
10644  allowed;
10645 
10646  if ( this.options.values && this.options.values.length ) {
10647  otherVal = this.values( index ? 0 : 1 );
10648 
10649  if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10650  ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10651  ) {
10652  newVal = otherVal;
10653  }
10654 
10655  if ( newVal !== this.values( index ) ) {
10656  newValues = this.values();
10657  newValues[ index ] = newVal;
10658  // A slide can be canceled by returning false from the slide callback
10659  allowed = this._trigger( "slide", event, {
10660  handle: this.handles[ index ],
10661  value: newVal,
10662  values: newValues
10663  } );
10664  otherVal = this.values( index ? 0 : 1 );
10665  if ( allowed !== false ) {
10666  this.values( index, newVal, true );
10667  }
10668  }
10669  } else {
10670  if ( newVal !== this.value() ) {
10671  // A slide can be canceled by returning false from the slide callback
10672  allowed = this._trigger( "slide", event, {
10673  handle: this.handles[ index ],
10674  value: newVal
10675  } );
10676  if ( allowed !== false ) {
10677  this.value( newVal );
10678  }
10679  }
10680  }
10681  },
10682 
10683  _stop: function( event, index ) {
10684  var uiHash = {
10685  handle: this.handles[ index ],
10686  value: this.value()
10687  };
10688  if ( this.options.values && this.options.values.length ) {
10689  uiHash.value = this.values( index );
10690  uiHash.values = this.values();
10691  }
10692 
10693  this._trigger( "stop", event, uiHash );
10694  },
10695 
10696  _change: function( event, index ) {
10697  if ( !this._keySliding && !this._mouseSliding ) {
10698  var uiHash = {
10699  handle: this.handles[ index ],
10700  value: this.value()
10701  };
10702  if ( this.options.values && this.options.values.length ) {
10703  uiHash.value = this.values( index );
10704  uiHash.values = this.values();
10705  }
10706 
10707  //store the last changed value index for reference when handles overlap
10708  this._lastChangedValue = index;
10709 
10710  this._trigger( "change", event, uiHash );
10711  }
10712  },
10713 
10714  value: function( newValue ) {
10715  if ( arguments.length ) {
10716  this.options.value = this._trimAlignValue( newValue );
10717  this._refreshValue();
10718  this._change( null, 0 );
10719  return;
10720  }
10721 
10722  return this._value();
10723  },
10724 
10725  values: function( index, newValue ) {
10726  var vals,
10727  newValues,
10728  i;
10729 
10730  if ( arguments.length > 1 ) {
10731  this.options.values[ index ] = this._trimAlignValue( newValue );
10732  this._refreshValue();
10733  this._change( null, index );
10734  return;
10735  }
10736 
10737  if ( arguments.length ) {
10738  if ( $.isArray( arguments[ 0 ] ) ) {
10739  vals = this.options.values;
10740  newValues = arguments[ 0 ];
10741  for ( i = 0; i < vals.length; i += 1 ) {
10742  vals[ i ] = this._trimAlignValue( newValues[ i ] );
10743  this._change( null, i );
10744  }
10745  this._refreshValue();
10746  } else {
10747  if ( this.options.values && this.options.values.length ) {
10748  return this._values( index );
10749  } else {
10750  return this.value();
10751  }
10752  }
10753  } else {
10754  return this._values();
10755  }
10756  },
10757 
10758  _setOption: function( key, value ) {
10759  var i,
10760  valsLength = 0;
10761 
10762  if ( key === "range" && this.options.range === true ) {
10763  if ( value === "min" ) {
10764  this.options.value = this._values( 0 );
10765  this.options.values = null;
10766  } else if ( value === "max" ) {
10767  this.options.value = this._values( this.options.values.length-1 );
10768  this.options.values = null;
10769  }
10770  }
10771 
10772  if ( $.isArray( this.options.values ) ) {
10773  valsLength = this.options.values.length;
10774  }
10775 
10776  $.Widget.prototype._setOption.apply( this, arguments );
10777 
10778  switch ( key ) {
10779  case "orientation":
10780  this._detectOrientation();
10781  this.element
10782  .removeClass( "ui-slider-horizontal ui-slider-vertical" )
10783  .addClass( "ui-slider-" + this.orientation );
10784  this._refreshValue();
10785  break;
10786  case "value":
10787  this._animateOff = true;
10788  this._refreshValue();
10789  this._change( null, 0 );
10790  this._animateOff = false;
10791  break;
10792  case "values":
10793  this._animateOff = true;
10794  this._refreshValue();
10795  for ( i = 0; i < valsLength; i += 1 ) {
10796  this._change( null, i );
10797  }
10798  this._animateOff = false;
10799  break;
10800  case "min":
10801  case "max":
10802  this._animateOff = true;
10803  this._refreshValue();
10804  this._animateOff = false;
10805  break;
10806  case "range":
10807  this._animateOff = true;
10808  this._refresh();
10809  this._animateOff = false;
10810  break;
10811  }
10812  },
10813 
10814  //internal value getter
10815  // _value() returns value trimmed by min and max, aligned by step
10816  _value: function() {
10817  var val = this.options.value;
10818  val = this._trimAlignValue( val );
10819 
10820  return val;
10821  },
10822 
10823  //internal values getter
10824  // _values() returns array of values trimmed by min and max, aligned by step
10825  // _values( index ) returns single value trimmed by min and max, aligned by step
10826  _values: function( index ) {
10827  var val,
10828  vals,
10829  i;
10830 
10831  if ( arguments.length ) {
10832  val = this.options.values[ index ];
10833  val = this._trimAlignValue( val );
10834 
10835  return val;
10836  } else if ( this.options.values && this.options.values.length ) {
10837  // .slice() creates a copy of the array
10838  // this copy gets trimmed by min and max and then returned
10839  vals = this.options.values.slice();
10840  for ( i = 0; i < vals.length; i+= 1) {
10841  vals[ i ] = this._trimAlignValue( vals[ i ] );
10842  }
10843 
10844  return vals;
10845  } else {
10846  return [];
10847  }
10848  },
10849 
10850  // returns the step-aligned value that val is closest to, between (inclusive) min and max
10851  _trimAlignValue: function( val ) {
10852  if ( val <= this._valueMin() ) {
10853  return this._valueMin();
10854  }
10855  if ( val >= this._valueMax() ) {
10856  return this._valueMax();
10857  }
10858  var step = ( this.options.step > 0 ) ? this.options.step : 1,
10859  valModStep = (val - this._valueMin()) % step,
10860  alignValue = val - valModStep;
10861 
10862  if ( Math.abs(valModStep) * 2 >= step ) {
10863  alignValue += ( valModStep > 0 ) ? step : ( -step );
10864  }
10865 
10866  // Since JavaScript has problems with large floats, round
10867  // the final value to 5 digits after the decimal point (see #4124)
10868  return parseFloat( alignValue.toFixed(5) );
10869  },
10870 
10871  _valueMin: function() {
10872  return this.options.min;
10873  },
10874 
10875  _valueMax: function() {
10876  return this.options.max;
10877  },
10878 
10879  _refreshValue: function() {
10880  var lastValPercent, valPercent, value, valueMin, valueMax,
10881  oRange = this.options.range,
10882  o = this.options,
10883  that = this,
10884  animate = ( !this._animateOff ) ? o.animate : false,
10885  _set = {};
10886 
10887  if ( this.options.values && this.options.values.length ) {
10888  this.handles.each(function( i ) {
10889  valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
10890  _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10891  $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10892  if ( that.options.range === true ) {
10893  if ( that.orientation === "horizontal" ) {
10894  if ( i === 0 ) {
10895  that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
10896  }
10897  if ( i === 1 ) {
10898  that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10899  }
10900  } else {
10901  if ( i === 0 ) {
10902  that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
10903  }
10904  if ( i === 1 ) {
10905  that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
10906  }
10907  }
10908  }
10909  lastValPercent = valPercent;
10910  });
10911  } else {
10912  value = this.value();
10913  valueMin = this._valueMin();
10914  valueMax = this._valueMax();
10915  valPercent = ( valueMax !== valueMin ) ?
10916  ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
10917  0;
10918  _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10919  this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10920 
10921  if ( oRange === "min" && this.orientation === "horizontal" ) {
10922  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
10923  }
10924  if ( oRange === "max" && this.orientation === "horizontal" ) {
10925  this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10926  }
10927  if ( oRange === "min" && this.orientation === "vertical" ) {
10928  this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
10929  }
10930  if ( oRange === "max" && this.orientation === "vertical" ) {
10931  this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
10932  }
10933  }
10934  },
10935 
10936  _handleEvents: {
10937  keydown: function( event ) {
10938  /*jshint maxcomplexity:25*/
10939  var allowed, curVal, newVal, step,
10940  index = $( event.target ).data( "ui-slider-handle-index" );
10941 
10942  switch ( event.keyCode ) {
10943  case $.ui.keyCode.HOME:
10944  case $.ui.keyCode.END:
10945  case $.ui.keyCode.PAGE_UP:
10946  case $.ui.keyCode.PAGE_DOWN:
10947  case $.ui.keyCode.UP:
10948  case $.ui.keyCode.RIGHT:
10949  case $.ui.keyCode.DOWN:
10950  case $.ui.keyCode.LEFT:
10951  event.preventDefault();
10952  if ( !this._keySliding ) {
10953  this._keySliding = true;
10954  $( event.target ).addClass( "ui-state-active" );
10955  allowed = this._start( event, index );
10956  if ( allowed === false ) {
10957  return;
10958  }
10959  }
10960  break;
10961  }
10962 
10963  step = this.options.step;
10964  if ( this.options.values && this.options.values.length ) {
10965  curVal = newVal = this.values( index );
10966  } else {
10967  curVal = newVal = this.value();
10968  }
10969 
10970  switch ( event.keyCode ) {
10971  case $.ui.keyCode.HOME:
10972  newVal = this._valueMin();
10973  break;
10974  case $.ui.keyCode.END:
10975  newVal = this._valueMax();
10976  break;
10977  case $.ui.keyCode.PAGE_UP:
10978  newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
10979  break;
10980  case $.ui.keyCode.PAGE_DOWN:
10981  newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
10982  break;
10983  case $.ui.keyCode.UP:
10984  case $.ui.keyCode.RIGHT:
10985  if ( curVal === this._valueMax() ) {
10986  return;
10987  }
10988  newVal = this._trimAlignValue( curVal + step );
10989  break;
10990  case $.ui.keyCode.DOWN:
10991  case $.ui.keyCode.LEFT:
10992  if ( curVal === this._valueMin() ) {
10993  return;
10994  }
10995  newVal = this._trimAlignValue( curVal - step );
10996  break;
10997  }
10998 
10999  this._slide( event, index, newVal );
11000  },
11001  click: function( event ) {
11002  event.preventDefault();
11003  },
11004  keyup: function( event ) {
11005  var index = $( event.target ).data( "ui-slider-handle-index" );
11006 
11007  if ( this._keySliding ) {
11008  this._keySliding = false;
11009  this._stop( event, index );
11010  this._change( event, index );
11011  $( event.target ).removeClass( "ui-state-active" );
11012  }
11013  }
11014  }
11015 
11016 });
11017 
11018 }(jQuery));
11019 (function( $ ) {
11020 
11021 function modifier( fn ) {
11022  return function() {
11023  var previous = this.element.val();
11024  fn.apply( this, arguments );
11025  this._refresh();
11026  if ( previous !== this.element.val() ) {
11027  this._trigger( "change" );
11028  }
11029  };
11030 }
11031 
11032 $.widget( "ui.spinner", {
11033  version: "1.10.3",
11034  defaultElement: "<input>",
11035  widgetEventPrefix: "spin",
11036  options: {
11037  culture: null,
11038  icons: {
11039  down: "ui-icon-triangle-1-s",
11040  up: "ui-icon-triangle-1-n"
11041  },
11042  incremental: true,
11043  max: null,
11044  min: null,
11045  numberFormat: null,
11046  page: 10,
11047  step: 1,
11048 
11049  change: null,
11050  spin: null,
11051  start: null,
11052  stop: null
11053  },
11054 
11055  _create: function() {
11056  // handle string values that need to be parsed
11057  this._setOption( "max", this.options.max );
11058  this._setOption( "min", this.options.min );
11059  this._setOption( "step", this.options.step );
11060 
11061  // format the value, but don't constrain
11062  this._value( this.element.val(), true );
11063 
11064  this._draw();
11065  this._on( this._events );
11066  this._refresh();
11067 
11068  // turning off autocomplete prevents the browser from remembering the
11069  // value when navigating through history, so we re-enable autocomplete
11070  // if the page is unloaded before the widget is destroyed. #7790
11071  this._on( this.window, {
11072  beforeunload: function() {
11073  this.element.removeAttr( "autocomplete" );
11074  }
11075  });
11076  },
11077 
11078  _getCreateOptions: function() {
11079  var options = {},
11080  element = this.element;
11081 
11082  $.each( [ "min", "max", "step" ], function( i, option ) {
11083  var value = element.attr( option );
11084  if ( value !== undefined && value.length ) {
11085  options[ option ] = value;
11086  }
11087  });
11088 
11089  return options;
11090  },
11091 
11092  _events: {
11093  keydown: function( event ) {
11094  if ( this._start( event ) && this._keydown( event ) ) {
11095  event.preventDefault();
11096  }
11097  },
11098  keyup: "_stop",
11099  focus: function() {
11100  this.previous = this.element.val();
11101  },
11102  blur: function( event ) {
11103  if ( this.cancelBlur ) {
11104  delete this.cancelBlur;
11105  return;
11106  }
11107 
11108  this._stop();
11109  this._refresh();
11110  if ( this.previous !== this.element.val() ) {
11111  this._trigger( "change", event );
11112  }
11113  },
11114  mousewheel: function( event, delta ) {
11115  if ( !delta ) {
11116  return;
11117  }
11118  if ( !this.spinning && !this._start( event ) ) {
11119  return false;
11120  }
11121 
11122  this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
11123  clearTimeout( this.mousewheelTimer );
11124  this.mousewheelTimer = this._delay(function() {
11125  if ( this.spinning ) {
11126  this._stop( event );
11127  }
11128  }, 100 );
11129  event.preventDefault();
11130  },
11131  "mousedown .ui-spinner-button": function( event ) {
11132  var previous;
11133 
11134  // We never want the buttons to have focus; whenever the user is
11135  // interacting with the spinner, the focus should be on the input.
11136  // If the input is focused then this.previous is properly set from
11137  // when the input first received focus. If the input is not focused
11138  // then we need to set this.previous based on the value before spinning.
11139  previous = this.element[0] === this.document[0].activeElement ?
11140  this.previous : this.element.val();
11141  function checkFocus() {
11142  var isActive = this.element[0] === this.document[0].activeElement;
11143  if ( !isActive ) {
11144  this.element.focus();
11145  this.previous = previous;
11146  // support: IE
11147  // IE sets focus asynchronously, so we need to check if focus
11148  // moved off of the input because the user clicked on the button.
11149  this._delay(function() {
11150  this.previous = previous;
11151  });
11152  }
11153  }
11154 
11155  // ensure focus is on (or stays on) the text field
11156  event.preventDefault();
11157  checkFocus.call( this );
11158 
11159  // support: IE
11160  // IE doesn't prevent moving focus even with event.preventDefault()
11161  // so we set a flag to know when we should ignore the blur event
11162  // and check (again) if focus moved off of the input.
11163  this.cancelBlur = true;
11164  this._delay(function() {
11165  delete this.cancelBlur;
11166  checkFocus.call( this );
11167  });
11168 
11169  if ( this._start( event ) === false ) {
11170  return;
11171  }
11172 
11173  this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11174  },
11175  "mouseup .ui-spinner-button": "_stop",
11176  "mouseenter .ui-spinner-button": function( event ) {
11177  // button will add ui-state-active if mouse was down while mouseleave and kept down
11178  if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
11179  return;
11180  }
11181 
11182  if ( this._start( event ) === false ) {
11183  return false;
11184  }
11185  this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
11186  },
11187  // TODO: do we really want to consider this a stop?
11188  // shouldn't we just stop the repeater and wait until mouseup before
11189  // we trigger the stop event?
11190  "mouseleave .ui-spinner-button": "_stop"
11191  },
11192 
11193  _draw: function() {
11194  var uiSpinner = this.uiSpinner = this.element
11195  .addClass( "ui-spinner-input" )
11196  .attr( "autocomplete", "off" )
11197  .wrap( this._uiSpinnerHtml() )
11198  .parent()
11199  // add buttons
11200  .append( this._buttonHtml() );
11201 
11202  this.element.attr( "role", "spinbutton" );
11203 
11204  // button bindings
11205  this.buttons = uiSpinner.find( ".ui-spinner-button" )
11206  .attr( "tabIndex", -1 )
11207  .button()
11208  .removeClass( "ui-corner-all" );
11209 
11210  // IE 6 doesn't understand height: 50% for the buttons
11211  // unless the wrapper has an explicit height
11212  if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
11213  uiSpinner.height() > 0 ) {
11214  uiSpinner.height( uiSpinner.height() );
11215  }
11216 
11217  // disable spinner if element was already disabled
11218  if ( this.options.disabled ) {
11219  this.disable();
11220  }
11221  },
11222 
11223  _keydown: function( event ) {
11224  var options = this.options,
11225  keyCode = $.ui.keyCode;
11226 
11227  switch ( event.keyCode ) {
11228  case keyCode.UP:
11229  this._repeat( null, 1, event );
11230  return true;
11231  case keyCode.DOWN:
11232  this._repeat( null, -1, event );
11233  return true;
11234  case keyCode.PAGE_UP:
11235  this._repeat( null, options.page, event );
11236  return true;
11237  case keyCode.PAGE_DOWN:
11238  this._repeat( null, -options.page, event );
11239  return true;
11240  }
11241 
11242  return false;
11243  },
11244 
11245  _uiSpinnerHtml: function() {
11246  return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
11247  },
11248 
11249  _buttonHtml: function() {
11250  return "" +
11251  "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
11252  "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
11253  "</a>" +
11254  "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
11255  "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
11256  "</a>";
11257  },
11258 
11259  _start: function( event ) {
11260  if ( !this.spinning && this._trigger( "start", event ) === false ) {
11261  return false;
11262  }
11263 
11264  if ( !this.counter ) {
11265  this.counter = 1;
11266  }
11267  this.spinning = true;
11268  return true;
11269  },
11270 
11271  _repeat: function( i, steps, event ) {
11272  i = i || 500;
11273 
11274  clearTimeout( this.timer );
11275  this.timer = this._delay(function() {
11276  this._repeat( 40, steps, event );
11277  }, i );
11278 
11279  this._spin( steps * this.options.step, event );
11280  },
11281 
11282  _spin: function( step, event ) {
11283  var value = this.value() || 0;
11284 
11285  if ( !this.counter ) {
11286  this.counter = 1;
11287  }
11288 
11289  value = this._adjustValue( value + step * this._increment( this.counter ) );
11290 
11291  if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
11292  this._value( value );
11293  this.counter++;
11294  }
11295  },
11296 
11297  _increment: function( i ) {
11298  var incremental = this.options.incremental;
11299 
11300  if ( incremental ) {
11301  return $.isFunction( incremental ) ?
11302  incremental( i ) :
11303  Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
11304  }
11305 
11306  return 1;
11307  },
11308 
11309  _precision: function() {
11310  var precision = this._precisionOf( this.options.step );
11311  if ( this.options.min !== null ) {
11312  precision = Math.max( precision, this._precisionOf( this.options.min ) );
11313  }
11314  return precision;
11315  },
11316 
11317  _precisionOf: function( num ) {
11318  var str = num.toString(),
11319  decimal = str.indexOf( "." );
11320  return decimal === -1 ? 0 : str.length - decimal - 1;
11321  },
11322 
11323  _adjustValue: function( value ) {
11324  var base, aboveMin,
11325  options = this.options;
11326 
11327  // make sure we're at a valid step
11328  // - find out where we are relative to the base (min or 0)
11329  base = options.min !== null ? options.min : 0;
11330  aboveMin = value - base;
11331  // - round to the nearest step
11332  aboveMin = Math.round(aboveMin / options.step) * options.step;
11333  // - rounding is based on 0, so adjust back to our base
11334  value = base + aboveMin;
11335 
11336  // fix precision from bad JS floating point math
11337  value = parseFloat( value.toFixed( this._precision() ) );
11338 
11339  // clamp the value
11340  if ( options.max !== null && value > options.max) {
11341  return options.max;
11342  }
11343  if ( options.min !== null && value < options.min ) {
11344  return options.min;
11345  }
11346 
11347  return value;
11348  },
11349 
11350  _stop: function( event ) {
11351  if ( !this.spinning ) {
11352  return;
11353  }
11354 
11355  clearTimeout( this.timer );
11356  clearTimeout( this.mousewheelTimer );
11357  this.counter = 0;
11358  this.spinning = false;
11359  this._trigger( "stop", event );
11360  },
11361 
11362  _setOption: function( key, value ) {
11363  if ( key === "culture" || key === "numberFormat" ) {
11364  var prevValue = this._parse( this.element.val() );
11365  this.options[ key ] = value;
11366  this.element.val( this._format( prevValue ) );
11367  return;
11368  }
11369 
11370  if ( key === "max" || key === "min" || key === "step" ) {
11371  if ( typeof value === "string" ) {
11372  value = this._parse( value );
11373  }
11374  }
11375  if ( key === "icons" ) {
11376  this.buttons.first().find( ".ui-icon" )
11377  .removeClass( this.options.icons.up )
11378  .addClass( value.up );
11379  this.buttons.last().find( ".ui-icon" )
11380  .removeClass( this.options.icons.down )
11381  .addClass( value.down );
11382  }
11383 
11384  this._super( key, value );
11385 
11386  if ( key === "disabled" ) {
11387  if ( value ) {
11388  this.element.prop( "disabled", true );
11389  this.buttons.button( "disable" );
11390  } else {
11391  this.element.prop( "disabled", false );
11392  this.buttons.button( "enable" );
11393  }
11394  }
11395  },
11396 
11397  _setOptions: modifier(function( options ) {
11398  this._super( options );
11399  this._value( this.element.val() );
11400  }),
11401 
11402  _parse: function( val ) {
11403  if ( typeof val === "string" && val !== "" ) {
11404  val = window.Globalize && this.options.numberFormat ?
11405  Globalize.parseFloat( val, 10, this.options.culture ) : +val;
11406  }
11407  return val === "" || isNaN( val ) ? null : val;
11408  },
11409 
11410  _format: function( value ) {
11411  if ( value === "" ) {
11412  return "";
11413  }
11414  return window.Globalize && this.options.numberFormat ?
11415  Globalize.format( value, this.options.numberFormat, this.options.culture ) :
11416  value;
11417  },
11418 
11419  _refresh: function() {
11420  this.element.attr({
11421  "aria-valuemin": this.options.min,
11422  "aria-valuemax": this.options.max,
11423  // TODO: what should we do with values that can't be parsed?
11424  "aria-valuenow": this._parse( this.element.val() )
11425  });
11426  },
11427 
11428  // update the value without triggering change
11429  _value: function( value, allowAny ) {
11430  var parsed;
11431  if ( value !== "" ) {
11432  parsed = this._parse( value );
11433  if ( parsed !== null ) {
11434  if ( !allowAny ) {
11435  parsed = this._adjustValue( parsed );
11436  }
11437  value = this._format( parsed );
11438  }
11439  }
11440  this.element.val( value );
11441  this._refresh();
11442  },
11443 
11444  _destroy: function() {
11445  this.element
11446  .removeClass( "ui-spinner-input" )
11447  .prop( "disabled", false )
11448  .removeAttr( "autocomplete" )
11449  .removeAttr( "role" )
11450  .removeAttr( "aria-valuemin" )
11451  .removeAttr( "aria-valuemax" )
11452  .removeAttr( "aria-valuenow" );
11453  this.uiSpinner.replaceWith( this.element );
11454  },
11455 
11456  stepUp: modifier(function( steps ) {
11457  this._stepUp( steps );
11458  }),
11459  _stepUp: function( steps ) {
11460  if ( this._start() ) {
11461  this._spin( (steps || 1) * this.options.step );
11462  this._stop();
11463  }
11464  },
11465 
11466  stepDown: modifier(function( steps ) {
11467  this._stepDown( steps );
11468  }),
11469  _stepDown: function( steps ) {
11470  if ( this._start() ) {
11471  this._spin( (steps || 1) * -this.options.step );
11472  this._stop();
11473  }
11474  },
11475 
11476  pageUp: modifier(function( pages ) {
11477  this._stepUp( (pages || 1) * this.options.page );
11478  }),
11479 
11480  pageDown: modifier(function( pages ) {
11481  this._stepDown( (pages || 1) * this.options.page );
11482  }),
11483 
11484  value: function( newVal ) {
11485  if ( !arguments.length ) {
11486  return this._parse( this.element.val() );
11487  }
11488  modifier( this._value ).call( this, newVal );
11489  },
11490 
11491  widget: function() {
11492  return this.uiSpinner;
11493  }
11494 });
11495 
11496 }( jQuery ) );
11497 (function( $, undefined ) {
11498 
11499 var tabId = 0,
11500  rhash = /#.*$/;
11501 
11502 function getNextTabId() {
11503  return ++tabId;
11504 }
11505 
11506 function isLocal( anchor ) {
11507  return anchor.hash.length > 1 &&
11508  decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
11509  decodeURIComponent( location.href.replace( rhash, "" ) );
11510 }
11511 
11512 $.widget( "ui.tabs", {
11513  version: "1.10.3",
11514  delay: 300,
11515  options: {
11516  active: null,
11517  collapsible: false,
11518  event: "click",
11519  heightStyle: "content",
11520  hide: null,
11521  show: null,
11522 
11523  // callbacks
11524  activate: null,
11525  beforeActivate: null,
11526  beforeLoad: null,
11527  load: null
11528  },
11529 
11530  _create: function() {
11531  var that = this,
11532  options = this.options;
11533 
11534  this.running = false;
11535 
11536  this.element
11537  .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
11538  .toggleClass( "ui-tabs-collapsible", options.collapsible )
11539  // Prevent users from focusing disabled tabs via click
11540  .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
11541  if ( $( this ).is( ".ui-state-disabled" ) ) {
11542  event.preventDefault();
11543  }
11544  })
11545  // support: IE <9
11546  // Preventing the default action in mousedown doesn't prevent IE
11547  // from focusing the element, so if the anchor gets focused, blur.
11548  // We don't have to worry about focusing the previously focused
11549  // element since clicking on a non-focusable element should focus
11550  // the body anyway.
11551  .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
11552  if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
11553  this.blur();
11554  }
11555  });
11556 
11557  this._processTabs();
11558  options.active = this._initialActive();
11559 
11560  // Take disabling tabs via class attribute from HTML
11561  // into account and update option properly.
11562  if ( $.isArray( options.disabled ) ) {
11563  options.disabled = $.unique( options.disabled.concat(
11564  $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
11565  return that.tabs.index( li );
11566  })
11567  ) ).sort();
11568  }
11569 
11570  // check for length avoids error when initializing empty list
11571  if ( this.options.active !== false && this.anchors.length ) {
11572  this.active = this._findActive( options.active );
11573  } else {
11574  this.active = $();
11575  }
11576 
11577  this._refresh();
11578 
11579  if ( this.active.length ) {
11580  this.load( options.active );
11581  }
11582  },
11583 
11584  _initialActive: function() {
11585  var active = this.options.active,
11586  collapsible = this.options.collapsible,
11587  locationHash = location.hash.substring( 1 );
11588 
11589  if ( active === null ) {
11590  // check the fragment identifier in the URL
11591  if ( locationHash ) {
11592  this.tabs.each(function( i, tab ) {
11593  if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
11594  active = i;
11595  return false;
11596  }
11597  });
11598  }
11599 
11600  // check for a tab marked active via a class
11601  if ( active === null ) {
11602  active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
11603  }
11604 
11605  // no active tab, set to false
11606  if ( active === null || active === -1 ) {
11607  active = this.tabs.length ? 0 : false;
11608  }
11609  }
11610 
11611  // handle numbers: negative, out of range
11612  if ( active !== false ) {
11613  active = this.tabs.index( this.tabs.eq( active ) );
11614  if ( active === -1 ) {
11615  active = collapsible ? false : 0;
11616  }
11617  }
11618 
11619  // don't allow collapsible: false and active: false
11620  if ( !collapsible && active === false && this.anchors.length ) {
11621  active = 0;
11622  }
11623 
11624  return active;
11625  },
11626 
11627  _getCreateEventData: function() {
11628  return {
11629  tab: this.active,
11630  panel: !this.active.length ? $() : this._getPanelForTab( this.active )
11631  };
11632  },
11633 
11634  _tabKeydown: function( event ) {
11635  /*jshint maxcomplexity:15*/
11636  var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
11637  selectedIndex = this.tabs.index( focusedTab ),
11638  goingForward = true;
11639 
11640  if ( this._handlePageNav( event ) ) {
11641  return;
11642  }
11643 
11644  switch ( event.keyCode ) {
11645  case $.ui.keyCode.RIGHT:
11646  case $.ui.keyCode.DOWN:
11647  selectedIndex++;
11648  break;
11649  case $.ui.keyCode.UP:
11650  case $.ui.keyCode.LEFT:
11651  goingForward = false;
11652  selectedIndex--;
11653  break;
11654  case $.ui.keyCode.END:
11655  selectedIndex = this.anchors.length - 1;
11656  break;
11657  case $.ui.keyCode.HOME:
11658  selectedIndex = 0;
11659  break;
11660  case $.ui.keyCode.SPACE:
11661  // Activate only, no collapsing
11662  event.preventDefault();
11663  clearTimeout( this.activating );
11664  this._activate( selectedIndex );
11665  return;
11666  case $.ui.keyCode.ENTER:
11667  // Toggle (cancel delayed activation, allow collapsing)
11668  event.preventDefault();
11669  clearTimeout( this.activating );
11670  // Determine if we should collapse or activate
11671  this._activate( selectedIndex === this.options.active ? false : selectedIndex );
11672  return;
11673  default:
11674  return;
11675  }
11676 
11677  // Focus the appropriate tab, based on which key was pressed
11678  event.preventDefault();
11679  clearTimeout( this.activating );
11680  selectedIndex = this._focusNextTab( selectedIndex, goingForward );
11681 
11682  // Navigating with control key will prevent automatic activation
11683  if ( !event.ctrlKey ) {
11684  // Update aria-selected immediately so that AT think the tab is already selected.
11685  // Otherwise AT may confuse the user by stating that they need to activate the tab,
11686  // but the tab will already be activated by the time the announcement finishes.
11687  focusedTab.attr( "aria-selected", "false" );
11688  this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
11689 
11690  this.activating = this._delay(function() {
11691  this.option( "active", selectedIndex );
11692  }, this.delay );
11693  }
11694  },
11695 
11696  _panelKeydown: function( event ) {
11697  if ( this._handlePageNav( event ) ) {
11698  return;
11699  }
11700 
11701  // Ctrl+up moves focus to the current tab
11702  if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
11703  event.preventDefault();
11704  this.active.focus();
11705  }
11706  },
11707 
11708  // Alt+page up/down moves focus to the previous/next tab (and activates)
11709  _handlePageNav: function( event ) {
11710  if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
11711  this._activate( this._focusNextTab( this.options.active - 1, false ) );
11712  return true;
11713  }
11714  if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
11715  this._activate( this._focusNextTab( this.options.active + 1, true ) );
11716  return true;
11717  }
11718  },
11719 
11720  _findNextTab: function( index, goingForward ) {
11721  var lastTabIndex = this.tabs.length - 1;
11722 
11723  function constrain() {
11724  if ( index > lastTabIndex ) {
11725  index = 0;
11726  }
11727  if ( index < 0 ) {
11728  index = lastTabIndex;
11729  }
11730  return index;
11731  }
11732 
11733  while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
11734  index = goingForward ? index + 1 : index - 1;
11735  }
11736 
11737  return index;
11738  },
11739 
11740  _focusNextTab: function( index, goingForward ) {
11741  index = this._findNextTab( index, goingForward );
11742  this.tabs.eq( index ).focus();
11743  return index;
11744  },
11745 
11746  _setOption: function( key, value ) {
11747  if ( key === "active" ) {
11748  // _activate() will handle invalid values and update this.options
11749  this._activate( value );
11750  return;
11751  }
11752 
11753  if ( key === "disabled" ) {
11754  // don't use the widget factory's disabled handling
11755  this._setupDisabled( value );
11756  return;
11757  }
11758 
11759  this._super( key, value);
11760 
11761  if ( key === "collapsible" ) {
11762  this.element.toggleClass( "ui-tabs-collapsible", value );
11763  // Setting collapsible: false while collapsed; open first panel
11764  if ( !value && this.options.active === false ) {
11765  this._activate( 0 );
11766  }
11767  }
11768 
11769  if ( key === "event" ) {
11770  this._setupEvents( value );
11771  }
11772 
11773  if ( key === "heightStyle" ) {
11774  this._setupHeightStyle( value );
11775  }
11776  },
11777 
11778  _tabId: function( tab ) {
11779  return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
11780  },
11781 
11782  _sanitizeSelector: function( hash ) {
11783  return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
11784  },
11785 
11786  refresh: function() {
11787  var options = this.options,
11788  lis = this.tablist.children( ":has(a[href])" );
11789 
11790  // get disabled tabs from class attribute from HTML
11791  // this will get converted to a boolean if needed in _refresh()
11792  options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
11793  return lis.index( tab );
11794  });
11795 
11796  this._processTabs();
11797 
11798  // was collapsed or no tabs
11799  if ( options.active === false || !this.anchors.length ) {
11800  options.active = false;
11801  this.active = $();
11802  // was active, but active tab is gone
11803  } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
11804  // all remaining tabs are disabled
11805  if ( this.tabs.length === options.disabled.length ) {
11806  options.active = false;
11807  this.active = $();
11808  // activate previous tab
11809  } else {
11810  this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
11811  }
11812  // was active, active tab still exists
11813  } else {
11814  // make sure active index is correct
11815  options.active = this.tabs.index( this.active );
11816  }
11817 
11818  this._refresh();
11819  },
11820 
11821  _refresh: function() {
11822  this._setupDisabled( this.options.disabled );
11823  this._setupEvents( this.options.event );
11824  this._setupHeightStyle( this.options.heightStyle );
11825 
11826  this.tabs.not( this.active ).attr({
11827  "aria-selected": "false",
11828  tabIndex: -1
11829  });
11830  this.panels.not( this._getPanelForTab( this.active ) )
11831  .hide()
11832  .attr({
11833  "aria-expanded": "false",
11834  "aria-hidden": "true"
11835  });
11836 
11837  // Make sure one tab is in the tab order
11838  if ( !this.active.length ) {
11839  this.tabs.eq( 0 ).attr( "tabIndex", 0 );
11840  } else {
11841  this.active
11842  .addClass( "ui-tabs-active ui-state-active" )
11843  .attr({
11844  "aria-selected": "true",
11845  tabIndex: 0
11846  });
11847  this._getPanelForTab( this.active )
11848  .show()
11849  .attr({
11850  "aria-expanded": "true",
11851  "aria-hidden": "false"
11852  });
11853  }
11854  },
11855 
11856  _processTabs: function() {
11857  var that = this;
11858 
11859  this.tablist = this._getList()
11860  .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
11861  .attr( "role", "tablist" );
11862 
11863  this.tabs = this.tablist.find( "> li:has(a[href])" )
11864  .addClass( "ui-state-default ui-corner-top" )
11865  .attr({
11866  role: "tab",
11867  tabIndex: -1
11868  });
11869 
11870  this.anchors = this.tabs.map(function() {
11871  return $( "a", this )[ 0 ];
11872  })
11873  .addClass( "ui-tabs-anchor" )
11874  .attr({
11875  role: "presentation",
11876  tabIndex: -1
11877  });
11878 
11879  this.panels = $();
11880 
11881  this.anchors.each(function( i, anchor ) {
11882  var selector, panel, panelId,
11883  anchorId = $( anchor ).uniqueId().attr( "id" ),
11884  tab = $( anchor ).closest( "li" ),
11885  originalAriaControls = tab.attr( "aria-controls" );
11886 
11887  // inline tab
11888  if ( isLocal( anchor ) ) {
11889  selector = anchor.hash;
11890  panel = that.element.find( that._sanitizeSelector( selector ) );
11891  // remote tab
11892  } else {
11893  panelId = that._tabId( tab );
11894  selector = "#" + panelId;
11895  panel = that.element.find( selector );
11896  if ( !panel.length ) {
11897  panel = that._createPanel( panelId );
11898  panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
11899  }
11900  panel.attr( "aria-live", "polite" );
11901  }
11902 
11903  if ( panel.length) {
11904  that.panels = that.panels.add( panel );
11905  }
11906  if ( originalAriaControls ) {
11907  tab.data( "ui-tabs-aria-controls", originalAriaControls );
11908  }
11909  tab.attr({
11910  "aria-controls": selector.substring( 1 ),
11911  "aria-labelledby": anchorId
11912  });
11913  panel.attr( "aria-labelledby", anchorId );
11914  });
11915 
11916  this.panels
11917  .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11918  .attr( "role", "tabpanel" );
11919  },
11920 
11921  // allow overriding how to find the list for rare usage scenarios (#7715)
11922  _getList: function() {
11923  return this.element.find( "ol,ul" ).eq( 0 );
11924  },
11925 
11926  _createPanel: function( id ) {
11927  return $( "<div>" )
11928  .attr( "id", id )
11929  .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11930  .data( "ui-tabs-destroy", true );
11931  },
11932 
11933  _setupDisabled: function( disabled ) {
11934  if ( $.isArray( disabled ) ) {
11935  if ( !disabled.length ) {
11936  disabled = false;
11937  } else if ( disabled.length === this.anchors.length ) {
11938  disabled = true;
11939  }
11940  }
11941 
11942  // disable tabs
11943  for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
11944  if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
11945  $( li )
11946  .addClass( "ui-state-disabled" )
11947  .attr( "aria-disabled", "true" );
11948  } else {
11949  $( li )
11950  .removeClass( "ui-state-disabled" )
11951  .removeAttr( "aria-disabled" );
11952  }
11953  }
11954 
11955  this.options.disabled = disabled;
11956  },
11957 
11958  _setupEvents: function( event ) {
11959  var events = {
11960  click: function( event ) {
11961  event.preventDefault();
11962  }
11963  };
11964  if ( event ) {
11965  $.each( event.split(" "), function( index, eventName ) {
11966  events[ eventName ] = "_eventHandler";
11967  });
11968  }
11969 
11970  this._off( this.anchors.add( this.tabs ).add( this.panels ) );
11971  this._on( this.anchors, events );
11972  this._on( this.tabs, { keydown: "_tabKeydown" } );
11973  this._on( this.panels, { keydown: "_panelKeydown" } );
11974 
11975  this._focusable( this.tabs );
11976  this._hoverable( this.tabs );
11977  },
11978 
11979  _setupHeightStyle: function( heightStyle ) {
11980  var maxHeight,
11981  parent = this.element.parent();
11982 
11983  if ( heightStyle === "fill" ) {
11984  maxHeight = parent.height();
11985  maxHeight -= this.element.outerHeight() - this.element.height();
11986 
11987  this.element.siblings( ":visible" ).each(function() {
11988  var elem = $( this ),
11989  position = elem.css( "position" );
11990 
11991  if ( position === "absolute" || position === "fixed" ) {
11992  return;
11993  }
11994  maxHeight -= elem.outerHeight( true );
11995  });
11996 
11997  this.element.children().not( this.panels ).each(function() {
11998  maxHeight -= $( this ).outerHeight( true );
11999  });
12000 
12001  this.panels.each(function() {
12002  $( this ).height( Math.max( 0, maxHeight -
12003  $( this ).innerHeight() + $( this ).height() ) );
12004  })
12005  .css( "overflow", "auto" );
12006  } else if ( heightStyle === "auto" ) {
12007  maxHeight = 0;
12008  this.panels.each(function() {
12009  maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
12010  }).height( maxHeight );
12011  }
12012  },
12013 
12014  _eventHandler: function( event ) {
12015  var options = this.options,
12016  active = this.active,
12017  anchor = $( event.currentTarget ),
12018  tab = anchor.closest( "li" ),
12019  clickedIsActive = tab[ 0 ] === active[ 0 ],
12020  collapsing = clickedIsActive && options.collapsible,
12021  toShow = collapsing ? $() : this._getPanelForTab( tab ),
12022  toHide = !active.length ? $() : this._getPanelForTab( active ),
12023  eventData = {
12024  oldTab: active,
12025  oldPanel: toHide,
12026  newTab: collapsing ? $() : tab,
12027  newPanel: toShow
12028  };
12029 
12030  event.preventDefault();
12031 
12032  if ( tab.hasClass( "ui-state-disabled" ) ||
12033  // tab is already loading
12034  tab.hasClass( "ui-tabs-loading" ) ||
12035  // can't switch durning an animation
12036  this.running ||
12037  // click on active header, but not collapsible
12038  ( clickedIsActive && !options.collapsible ) ||
12039  // allow canceling activation
12040  ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
12041  return;
12042  }
12043 
12044  options.active = collapsing ? false : this.tabs.index( tab );
12045 
12046  this.active = clickedIsActive ? $() : tab;
12047  if ( this.xhr ) {
12048  this.xhr.abort();
12049  }
12050 
12051  if ( !toHide.length && !toShow.length ) {
12052  $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
12053  }
12054 
12055  if ( toShow.length ) {
12056  this.load( this.tabs.index( tab ), event );
12057  }
12058  this._toggle( event, eventData );
12059  },
12060 
12061  // handles show/hide for selecting tabs
12062  _toggle: function( event, eventData ) {
12063  var that = this,
12064  toShow = eventData.newPanel,
12065  toHide = eventData.oldPanel;
12066 
12067  this.running = true;
12068 
12069  function complete() {
12070  that.running = false;
12071  that._trigger( "activate", event, eventData );
12072  }
12073 
12074  function show() {
12075  eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
12076 
12077  if ( toShow.length && that.options.show ) {
12078  that._show( toShow, that.options.show, complete );
12079  } else {
12080  toShow.show();
12081  complete();
12082  }
12083  }
12084 
12085  // start out by hiding, then showing, then completing
12086  if ( toHide.length && this.options.hide ) {
12087  this._hide( toHide, this.options.hide, function() {
12088  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12089  show();
12090  });
12091  } else {
12092  eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
12093  toHide.hide();
12094  show();
12095  }
12096 
12097  toHide.attr({
12098  "aria-expanded": "false",
12099  "aria-hidden": "true"
12100  });
12101  eventData.oldTab.attr( "aria-selected", "false" );
12102  // If we're switching tabs, remove the old tab from the tab order.
12103  // If we're opening from collapsed state, remove the previous tab from the tab order.
12104  // If we're collapsing, then keep the collapsing tab in the tab order.
12105  if ( toShow.length && toHide.length ) {
12106  eventData.oldTab.attr( "tabIndex", -1 );
12107  } else if ( toShow.length ) {
12108  this.tabs.filter(function() {
12109  return $( this ).attr( "tabIndex" ) === 0;
12110  })
12111  .attr( "tabIndex", -1 );
12112  }
12113 
12114  toShow.attr({
12115  "aria-expanded": "true",
12116  "aria-hidden": "false"
12117  });
12118  eventData.newTab.attr({
12119  "aria-selected": "true",
12120  tabIndex: 0
12121  });
12122  },
12123 
12124  _activate: function( index ) {
12125  var anchor,
12126  active = this._findActive( index );
12127 
12128  // trying to activate the already active panel
12129  if ( active[ 0 ] === this.active[ 0 ] ) {
12130  return;
12131  }
12132 
12133  // trying to collapse, simulate a click on the current active header
12134  if ( !active.length ) {
12135  active = this.active;
12136  }
12137 
12138  anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
12139  this._eventHandler({
12140  target: anchor,
12141  currentTarget: anchor,
12142  preventDefault: $.noop
12143  });
12144  },
12145 
12146  _findActive: function( index ) {
12147  return index === false ? $() : this.tabs.eq( index );
12148  },
12149 
12150  _getIndex: function( index ) {
12151  // meta-function to give users option to provide a href string instead of a numerical index.
12152  if ( typeof index === "string" ) {
12153  index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
12154  }
12155 
12156  return index;
12157  },
12158 
12159  _destroy: function() {
12160  if ( this.xhr ) {
12161  this.xhr.abort();
12162  }
12163 
12164  this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
12165 
12166  this.tablist
12167  .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
12168  .removeAttr( "role" );
12169 
12170  this.anchors
12171  .removeClass( "ui-tabs-anchor" )
12172  .removeAttr( "role" )
12173  .removeAttr( "tabIndex" )
12174  .removeUniqueId();
12175 
12176  this.tabs.add( this.panels ).each(function() {
12177  if ( $.data( this, "ui-tabs-destroy" ) ) {
12178  $( this ).remove();
12179  } else {
12180  $( this )
12181  .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
12182  "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
12183  .removeAttr( "tabIndex" )
12184  .removeAttr( "aria-live" )
12185  .removeAttr( "aria-busy" )
12186  .removeAttr( "aria-selected" )
12187  .removeAttr( "aria-labelledby" )
12188  .removeAttr( "aria-hidden" )
12189  .removeAttr( "aria-expanded" )
12190  .removeAttr( "role" );
12191  }
12192  });
12193 
12194  this.tabs.each(function() {
12195  var li = $( this ),
12196  prev = li.data( "ui-tabs-aria-controls" );
12197  if ( prev ) {
12198  li
12199  .attr( "aria-controls", prev )
12200  .removeData( "ui-tabs-aria-controls" );
12201  } else {
12202  li.removeAttr( "aria-controls" );
12203  }
12204  });
12205 
12206  this.panels.show();
12207 
12208  if ( this.options.heightStyle !== "content" ) {
12209  this.panels.css( "height", "" );
12210  }
12211  },
12212 
12213  enable: function( index ) {
12214  var disabled = this.options.disabled;
12215  if ( disabled === false ) {
12216  return;
12217  }
12218 
12219  if ( index === undefined ) {
12220  disabled = false;
12221  } else {
12222  index = this._getIndex( index );
12223  if ( $.isArray( disabled ) ) {
12224  disabled = $.map( disabled, function( num ) {
12225  return num !== index ? num : null;
12226  });
12227  } else {
12228  disabled = $.map( this.tabs, function( li, num ) {
12229  return num !== index ? num : null;
12230  });
12231  }
12232  }
12233  this._setupDisabled( disabled );
12234  },
12235 
12236  disable: function( index ) {
12237  var disabled = this.options.disabled;
12238  if ( disabled === true ) {
12239  return;
12240  }
12241 
12242  if ( index === undefined ) {
12243  disabled = true;
12244  } else {
12245  index = this._getIndex( index );
12246  if ( $.inArray( index, disabled ) !== -1 ) {
12247  return;
12248  }
12249  if ( $.isArray( disabled ) ) {
12250  disabled = $.merge( [ index ], disabled ).sort();
12251  } else {
12252  disabled = [ index ];
12253  }
12254  }
12255  this._setupDisabled( disabled );
12256  },
12257 
12258  load: function( index, event ) {
12259  index = this._getIndex( index );
12260  var that = this,
12261  tab = this.tabs.eq( index ),
12262  anchor = tab.find( ".ui-tabs-anchor" ),
12263  panel = this._getPanelForTab( tab ),
12264  eventData = {
12265  tab: tab,
12266  panel: panel
12267  };
12268 
12269  // not remote
12270  if ( isLocal( anchor[ 0 ] ) ) {
12271  return;
12272  }
12273 
12274  this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
12275 
12276  // support: jQuery <1.8
12277  // jQuery <1.8 returns false if the request is canceled in beforeSend,
12278  // but as of 1.8, $.ajax() always returns a jqXHR object.
12279  if ( this.xhr && this.xhr.statusText !== "canceled" ) {
12280  tab.addClass( "ui-tabs-loading" );
12281  panel.attr( "aria-busy", "true" );
12282 
12283  this.xhr
12284  .success(function( response ) {
12285  // support: jQuery <1.8
12286  // http://bugs.jquery.com/ticket/11778
12287  setTimeout(function() {
12288  panel.html( response );
12289  that._trigger( "load", event, eventData );
12290  }, 1 );
12291  })
12292  .complete(function( jqXHR, status ) {
12293  // support: jQuery <1.8
12294  // http://bugs.jquery.com/ticket/11778
12295  setTimeout(function() {
12296  if ( status === "abort" ) {
12297  that.panels.stop( false, true );
12298  }
12299 
12300  tab.removeClass( "ui-tabs-loading" );
12301  panel.removeAttr( "aria-busy" );
12302 
12303  if ( jqXHR === that.xhr ) {
12304  delete that.xhr;
12305  }
12306  }, 1 );
12307  });
12308  }
12309  },
12310 
12311  _ajaxSettings: function( anchor, event, eventData ) {
12312  var that = this;
12313  return {
12314  url: anchor.attr( "href" ),
12315  beforeSend: function( jqXHR, settings ) {
12316  return that._trigger( "beforeLoad", event,
12317  $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
12318  }
12319  };
12320  },
12321 
12322  _getPanelForTab: function( tab ) {
12323  var id = $( tab ).attr( "aria-controls" );
12324  return this.element.find( this._sanitizeSelector( "#" + id ) );
12325  }
12326 });
12327 
12328 })( jQuery );
12329 (function( $ ) {
12330 
12331 var increments = 0;
12332 
12333 function addDescribedBy( elem, id ) {
12334  var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
12335  describedby.push( id );
12336  elem
12337  .data( "ui-tooltip-id", id )
12338  .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
12339 }
12340 
12341 function removeDescribedBy( elem ) {
12342  var id = elem.data( "ui-tooltip-id" ),
12343  describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
12344  index = $.inArray( id, describedby );
12345  if ( index !== -1 ) {
12346  describedby.splice( index, 1 );
12347  }
12348 
12349  elem.removeData( "ui-tooltip-id" );
12350  describedby = $.trim( describedby.join( " " ) );
12351  if ( describedby ) {
12352  elem.attr( "aria-describedby", describedby );
12353  } else {
12354  elem.removeAttr( "aria-describedby" );
12355  }
12356 }
12357 
12358 $.widget( "ui.tooltip", {
12359  version: "1.10.3",
12360  options: {
12361  content: function() {
12362  // support: IE<9, Opera in jQuery <1.7
12363  // .text() can't accept undefined, so coerce to a string
12364  var title = $( this ).attr( "title" ) || "";
12365  // Escape title, since we're going from an attribute to raw HTML
12366  return $( "<a>" ).text( title ).html();
12367  },
12368  hide: true,
12369  // Disabled elements have inconsistent behavior across browsers (#8661)
12370  items: "[title]:not([disabled])",
12371  position: {
12372  my: "left top+15",
12373  at: "left bottom",
12374  collision: "flipfit flip"
12375  },
12376  show: true,
12377  tooltipClass: null,
12378  track: false,
12379 
12380  // callbacks
12381  close: null,
12382  open: null
12383  },
12384 
12385  _create: function() {
12386  this._on({
12387  mouseover: "open",
12388  focusin: "open"
12389  });
12390 
12391  // IDs of generated tooltips, needed for destroy
12392  this.tooltips = {};
12393  // IDs of parent tooltips where we removed the title attribute
12394  this.parents = {};
12395 
12396  if ( this.options.disabled ) {
12397  this._disable();
12398  }
12399  },
12400 
12401  _setOption: function( key, value ) {
12402  var that = this;
12403 
12404  if ( key === "disabled" ) {
12405  this[ value ? "_disable" : "_enable" ]();
12406  this.options[ key ] = value;
12407  // disable element style changes
12408  return;
12409  }
12410 
12411  this._super( key, value );
12412 
12413  if ( key === "content" ) {
12414  $.each( this.tooltips, function( id, element ) {
12415  that._updateContent( element );
12416  });
12417  }
12418  },
12419 
12420  _disable: function() {
12421  var that = this;
12422 
12423  // close open tooltips
12424  $.each( this.tooltips, function( id, element ) {
12425  var event = $.Event( "blur" );
12426  event.target = event.currentTarget = element[0];
12427  that.close( event, true );
12428  });
12429 
12430  // remove title attributes to prevent native tooltips
12431  this.element.find( this.options.items ).addBack().each(function() {
12432  var element = $( this );
12433  if ( element.is( "[title]" ) ) {
12434  element
12435  .data( "ui-tooltip-title", element.attr( "title" ) )
12436  .attr( "title", "" );
12437  }
12438  });
12439  },
12440 
12441  _enable: function() {
12442  // restore title attributes
12443  this.element.find( this.options.items ).addBack().each(function() {
12444  var element = $( this );
12445  if ( element.data( "ui-tooltip-title" ) ) {
12446  element.attr( "title", element.data( "ui-tooltip-title" ) );
12447  }
12448  });
12449  },
12450 
12451  open: function( event ) {
12452  var that = this,
12453  target = $( event ? event.target : this.element )
12454  // we need closest here due to mouseover bubbling,
12455  // but always pointing at the same event target
12456  .closest( this.options.items );
12457 
12458  // No element to show a tooltip for or the tooltip is already open
12459  if ( !target.length || target.data( "ui-tooltip-id" ) ) {
12460  return;
12461  }
12462 
12463  if ( target.attr( "title" ) ) {
12464  target.data( "ui-tooltip-title", target.attr( "title" ) );
12465  }
12466 
12467  target.data( "ui-tooltip-open", true );
12468 
12469  // kill parent tooltips, custom or native, for hover
12470  if ( event && event.type === "mouseover" ) {
12471  target.parents().each(function() {
12472  var parent = $( this ),
12473  blurEvent;
12474  if ( parent.data( "ui-tooltip-open" ) ) {
12475  blurEvent = $.Event( "blur" );
12476  blurEvent.target = blurEvent.currentTarget = this;
12477  that.close( blurEvent, true );
12478  }
12479  if ( parent.attr( "title" ) ) {
12480  parent.uniqueId();
12481  that.parents[ this.id ] = {
12482  element: this,
12483  title: parent.attr( "title" )
12484  };
12485  parent.attr( "title", "" );
12486  }
12487  });
12488  }
12489 
12490  this._updateContent( target, event );
12491  },
12492 
12493  _updateContent: function( target, event ) {
12494  var content,
12495  contentOption = this.options.content,
12496  that = this,
12497  eventType = event ? event.type : null;
12498 
12499  if ( typeof contentOption === "string" ) {
12500  return this._open( event, target, contentOption );
12501  }
12502 
12503  content = contentOption.call( target[0], function( response ) {
12504  // ignore async response if tooltip was closed already
12505  if ( !target.data( "ui-tooltip-open" ) ) {
12506  return;
12507  }
12508  // IE may instantly serve a cached response for ajax requests
12509  // delay this call to _open so the other call to _open runs first
12510  that._delay(function() {
12511  // jQuery creates a special event for focusin when it doesn't
12512  // exist natively. To improve performance, the native event
12513  // object is reused and the type is changed. Therefore, we can't
12514  // rely on the type being correct after the event finished
12515  // bubbling, so we set it back to the previous value. (#8740)
12516  if ( event ) {
12517  event.type = eventType;
12518  }
12519  this._open( event, target, response );
12520  });
12521  });
12522  if ( content ) {
12523  this._open( event, target, content );
12524  }
12525  },
12526 
12527  _open: function( event, target, content ) {
12528  var tooltip, events, delayedShow,
12529  positionOption = $.extend( {}, this.options.position );
12530 
12531  if ( !content ) {
12532  return;
12533  }
12534 
12535  // Content can be updated multiple times. If the tooltip already
12536  // exists, then just update the content and bail.
12537  tooltip = this._find( target );
12538  if ( tooltip.length ) {
12539  tooltip.find( ".ui-tooltip-content" ).html( content );
12540  return;
12541  }
12542 
12543  // if we have a title, clear it to prevent the native tooltip
12544  // we have to check first to avoid defining a title if none exists
12545  // (we don't want to cause an element to start matching [title])
12546  //
12547  // We use removeAttr only for key events, to allow IE to export the correct
12548  // accessible attributes. For mouse events, set to empty string to avoid
12549  // native tooltip showing up (happens only when removing inside mouseover).
12550  if ( target.is( "[title]" ) ) {
12551  if ( event && event.type === "mouseover" ) {
12552  target.attr( "title", "" );
12553  } else {
12554  target.removeAttr( "title" );
12555  }
12556  }
12557 
12558  tooltip = this._tooltip( target );
12559  addDescribedBy( target, tooltip.attr( "id" ) );
12560  tooltip.find( ".ui-tooltip-content" ).html( content );
12561 
12562  function position( event ) {
12563  positionOption.of = event;
12564  if ( tooltip.is( ":hidden" ) ) {
12565  return;
12566  }
12567  tooltip.position( positionOption );
12568  }
12569  if ( this.options.track && event && /^mouse/.test( event.type ) ) {
12570  this._on( this.document, {
12571  mousemove: position
12572  });
12573  // trigger once to override element-relative positioning
12574  position( event );
12575  } else {
12576  tooltip.position( $.extend({
12577  of: target
12578  }, this.options.position ) );
12579  }
12580 
12581  tooltip.hide();
12582 
12583  this._show( tooltip, this.options.show );
12584  // Handle tracking tooltips that are shown with a delay (#8644). As soon
12585  // as the tooltip is visible, position the tooltip using the most recent
12586  // event.
12587  if ( this.options.show && this.options.show.delay ) {
12588  delayedShow = this.delayedShow = setInterval(function() {
12589  if ( tooltip.is( ":visible" ) ) {
12590  position( positionOption.of );
12591  clearInterval( delayedShow );
12592  }
12593  }, $.fx.interval );
12594  }
12595 
12596  this._trigger( "open", event, { tooltip: tooltip } );
12597 
12598  events = {
12599  keyup: function( event ) {
12600  if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
12601  var fakeEvent = $.Event(event);
12602  fakeEvent.currentTarget = target[0];
12603  this.close( fakeEvent, true );
12604  }
12605  },
12606  remove: function() {
12607  this._removeTooltip( tooltip );
12608  }
12609  };
12610  if ( !event || event.type === "mouseover" ) {
12611  events.mouseleave = "close";
12612  }
12613  if ( !event || event.type === "focusin" ) {
12614  events.focusout = "close";
12615  }
12616  this._on( true, target, events );
12617  },
12618 
12619  close: function( event ) {
12620  var that = this,
12621  target = $( event ? event.currentTarget : this.element ),
12622  tooltip = this._find( target );
12623 
12624  // disabling closes the tooltip, so we need to track when we're closing
12625  // to avoid an infinite loop in case the tooltip becomes disabled on close
12626  if ( this.closing ) {
12627  return;
12628  }
12629 
12630  // Clear the interval for delayed tracking tooltips
12631  clearInterval( this.delayedShow );
12632 
12633  // only set title if we had one before (see comment in _open())
12634  if ( target.data( "ui-tooltip-title" ) ) {
12635  target.attr( "title", target.data( "ui-tooltip-title" ) );
12636  }
12637 
12638  removeDescribedBy( target );
12639 
12640  tooltip.stop( true );
12641  this._hide( tooltip, this.options.hide, function() {
12642  that._removeTooltip( $( this ) );
12643  });
12644 
12645  target.removeData( "ui-tooltip-open" );
12646  this._off( target, "mouseleave focusout keyup" );
12647  // Remove 'remove' binding only on delegated targets
12648  if ( target[0] !== this.element[0] ) {
12649  this._off( target, "remove" );
12650  }
12651  this._off( this.document, "mousemove" );
12652 
12653  if ( event && event.type === "mouseleave" ) {
12654  $.each( this.parents, function( id, parent ) {
12655  $( parent.element ).attr( "title", parent.title );
12656  delete that.parents[ id ];
12657  });
12658  }
12659 
12660  this.closing = true;
12661  this._trigger( "close", event, { tooltip: tooltip } );
12662  this.closing = false;
12663  },
12664 
12665  _tooltip: function( element ) {
12666  var id = "ui-tooltip-" + increments++,
12667  tooltip = $( "<div>" )
12668  .attr({
12669  id: id,
12670  role: "tooltip"
12671  })
12672  .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
12673  ( this.options.tooltipClass || "" ) );
12674  $( "<div>" )
12675  .addClass( "ui-tooltip-content" )
12676  .appendTo( tooltip );
12677  tooltip.appendTo( this.document[0].body );
12678  this.tooltips[ id ] = element;
12679  return tooltip;
12680  },
12681 
12682  _find: function( target ) {
12683  var id = target.data( "ui-tooltip-id" );
12684  return id ? $( "#" + id ) : $();
12685  },
12686 
12687  _removeTooltip: function( tooltip ) {
12688  tooltip.remove();
12689  delete this.tooltips[ tooltip.attr( "id" ) ];
12690  },
12691 
12692  _destroy: function() {
12693  var that = this;
12694 
12695  // close open tooltips
12696  $.each( this.tooltips, function( id, element ) {
12697  // Delegate to close method to handle common cleanup
12698  var event = $.Event( "blur" );
12699  event.target = event.currentTarget = element[0];
12700  that.close( event, true );
12701 
12702  // Remove immediately; destroying an open tooltip doesn't use the
12703  // hide animation
12704  $( "#" + id ).remove();
12705 
12706  // Restore the title
12707  if ( element.data( "ui-tooltip-title" ) ) {
12708  element.attr( "title", element.data( "ui-tooltip-title" ) );
12709  element.removeData( "ui-tooltip-title" );
12710  }
12711  });
12712  }
12713 });
12714 
12715 }( jQuery ) );
12716 (function($, undefined) {
12717 
12718 var dataSpace = "ui-effects-";
12719 
12720 $.effects = {
12721  effect: {}
12722 };
12723 
12724 /*!
12725  * jQuery Color Animations v2.1.2
12726  * https://github.com/jquery/jquery-color
12727  *
12728  * Copyright 2013 jQuery Foundation and other contributors
12729  * Released under the MIT license.
12730  * http://jquery.org/license
12731  *
12732  * Date: Wed Jan 16 08:47:09 2013 -0600
12733  */
12734 (function( jQuery, undefined ) {
12735 
12736  var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
12737 
12738  // plusequals test for += 100 -= 100
12739  rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
12740  // a set of RE's that can match strings and generate color tuples.
12741  stringParsers = [{
12742  re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12743  parse: function( execResult ) {
12744  return [
12745  execResult[ 1 ],
12746  execResult[ 2 ],
12747  execResult[ 3 ],
12748  execResult[ 4 ]
12749  ];
12750  }
12751  }, {
12752  re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12753  parse: function( execResult ) {
12754  return [
12755  execResult[ 1 ] * 2.55,
12756  execResult[ 2 ] * 2.55,
12757  execResult[ 3 ] * 2.55,
12758  execResult[ 4 ]
12759  ];
12760  }
12761  }, {
12762  // this regex ignores A-F because it's compared against an already lowercased string
12763  re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
12764  parse: function( execResult ) {
12765  return [
12766  parseInt( execResult[ 1 ], 16 ),
12767  parseInt( execResult[ 2 ], 16 ),
12768  parseInt( execResult[ 3 ], 16 )
12769  ];
12770  }
12771  }, {
12772  // this regex ignores A-F because it's compared against an already lowercased string
12773  re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
12774  parse: function( execResult ) {
12775  return [
12776  parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
12777  parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
12778  parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
12779  ];
12780  }
12781  }, {
12782  re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
12783  space: "hsla",
12784  parse: function( execResult ) {
12785  return [
12786  execResult[ 1 ],
12787  execResult[ 2 ] / 100,
12788  execResult[ 3 ] / 100,
12789  execResult[ 4 ]
12790  ];
12791  }
12792  }],
12793 
12794  // jQuery.Color( )
12795  color = jQuery.Color = function( color, green, blue, alpha ) {
12796  return new jQuery.Color.fn.parse( color, green, blue, alpha );
12797  },
12798  spaces = {
12799  rgba: {
12800  props: {
12801  red: {
12802  idx: 0,
12803  type: "byte"
12804  },
12805  green: {
12806  idx: 1,
12807  type: "byte"
12808  },
12809  blue: {
12810  idx: 2,
12811  type: "byte"
12812  }
12813  }
12814  },
12815 
12816  hsla: {
12817  props: {
12818  hue: {
12819  idx: 0,
12820  type: "degrees"
12821  },
12822  saturation: {
12823  idx: 1,
12824  type: "percent"
12825  },
12826  lightness: {
12827  idx: 2,
12828  type: "percent"
12829  }
12830  }
12831  }
12832  },
12833  propTypes = {
12834  "byte": {
12835  floor: true,
12836  max: 255
12837  },
12838  "percent": {
12839  max: 1
12840  },
12841  "degrees": {
12842  mod: 360,
12843  floor: true
12844  }
12845  },
12846  support = color.support = {},
12847 
12848  // element for support tests
12849  supportElem = jQuery( "<p>" )[ 0 ],
12850 
12851  // colors = jQuery.Color.names
12852  colors,
12853 
12854  // local aliases of functions called often
12855  each = jQuery.each;
12856 
12857 // determine rgba support immediately
12858 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
12859 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
12860 
12861 // define cache name and alpha properties
12862 // for rgba and hsla spaces
12863 each( spaces, function( spaceName, space ) {
12864  space.cache = "_" + spaceName;
12865  space.props.alpha = {
12866  idx: 3,
12867  type: "percent",
12868  def: 1
12869  };
12870 });
12871 
12872 function clamp( value, prop, allowEmpty ) {
12873  var type = propTypes[ prop.type ] || {};
12874 
12875  if ( value == null ) {
12876  return (allowEmpty || !prop.def) ? null : prop.def;
12877  }
12878 
12879  // ~~ is an short way of doing floor for positive numbers
12880  value = type.floor ? ~~value : parseFloat( value );
12881 
12882  // IE will pass in empty strings as value for alpha,
12883  // which will hit this case
12884  if ( isNaN( value ) ) {
12885  return prop.def;
12886  }
12887 
12888  if ( type.mod ) {
12889  // we add mod before modding to make sure that negatives values
12890  // get converted properly: -10 -> 350
12891  return (value + type.mod) % type.mod;
12892  }
12893 
12894  // for now all property types without mod have min and max
12895  return 0 > value ? 0 : type.max < value ? type.max : value;
12896 }
12897 
12898 function stringParse( string ) {
12899  var inst = color(),
12900  rgba = inst._rgba = [];
12901 
12902  string = string.toLowerCase();
12903 
12904  each( stringParsers, function( i, parser ) {
12905  var parsed,
12906  match = parser.re.exec( string ),
12907  values = match && parser.parse( match ),
12908  spaceName = parser.space || "rgba";
12909 
12910  if ( values ) {
12911  parsed = inst[ spaceName ]( values );
12912 
12913  // if this was an rgba parse the assignment might happen twice
12914  // oh well....
12915  inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12916  rgba = inst._rgba = parsed._rgba;
12917 
12918  // exit each( stringParsers ) here because we matched
12919  return false;
12920  }
12921  });
12922 
12923  // Found a stringParser that handled it
12924  if ( rgba.length ) {
12925 
12926  // if this came from a parsed string, force "transparent" when alpha is 0
12927  // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12928  if ( rgba.join() === "0,0,0,0" ) {
12929  jQuery.extend( rgba, colors.transparent );
12930  }
12931  return inst;
12932  }
12933 
12934  // named colors
12935  return colors[ string ];
12936 }
12937 
12938 color.fn = jQuery.extend( color.prototype, {
12939  parse: function( red, green, blue, alpha ) {
12940  if ( red === undefined ) {
12941  this._rgba = [ null, null, null, null ];
12942  return this;
12943  }
12944  if ( red.jquery || red.nodeType ) {
12945  red = jQuery( red ).css( green );
12946  green = undefined;
12947  }
12948 
12949  var inst = this,
12950  type = jQuery.type( red ),
12951  rgba = this._rgba = [];
12952 
12953  // more than 1 argument specified - assume ( red, green, blue, alpha )
12954  if ( green !== undefined ) {
12955  red = [ red, green, blue, alpha ];
12956  type = "array";
12957  }
12958 
12959  if ( type === "string" ) {
12960  return this.parse( stringParse( red ) || colors._default );
12961  }
12962 
12963  if ( type === "array" ) {
12964  each( spaces.rgba.props, function( key, prop ) {
12965  rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12966  });
12967  return this;
12968  }
12969 
12970  if ( type === "object" ) {
12971  if ( red instanceof color ) {
12972  each( spaces, function( spaceName, space ) {
12973  if ( red[ space.cache ] ) {
12974  inst[ space.cache ] = red[ space.cache ].slice();
12975  }
12976  });
12977  } else {
12978  each( spaces, function( spaceName, space ) {
12979  var cache = space.cache;
12980  each( space.props, function( key, prop ) {
12981 
12982  // if the cache doesn't exist, and we know how to convert
12983  if ( !inst[ cache ] && space.to ) {
12984 
12985  // if the value was null, we don't need to copy it
12986  // if the key was alpha, we don't need to copy it either
12987  if ( key === "alpha" || red[ key ] == null ) {
12988  return;
12989  }
12990  inst[ cache ] = space.to( inst._rgba );
12991  }
12992 
12993  // this is the only case where we allow nulls for ALL properties.
12994  // call clamp with alwaysAllowEmpty
12995  inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12996  });
12997 
12998  // everything defined but alpha?
12999  if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
13000  // use the default of 1
13001  inst[ cache ][ 3 ] = 1;
13002  if ( space.from ) {
13003  inst._rgba = space.from( inst[ cache ] );
13004  }
13005  }
13006  });
13007  }
13008  return this;
13009  }
13010  },
13011  is: function( compare ) {
13012  var is = color( compare ),
13013  same = true,
13014  inst = this;
13015 
13016  each( spaces, function( _, space ) {
13017  var localCache,
13018  isCache = is[ space.cache ];
13019  if (isCache) {
13020  localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
13021  each( space.props, function( _, prop ) {
13022  if ( isCache[ prop.idx ] != null ) {
13023  same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
13024  return same;
13025  }
13026  });
13027  }
13028  return same;
13029  });
13030  return same;
13031  },
13032  _space: function() {
13033  var used = [],
13034  inst = this;
13035  each( spaces, function( spaceName, space ) {
13036  if ( inst[ space.cache ] ) {
13037  used.push( spaceName );
13038  }
13039  });
13040  return used.pop();
13041  },
13042  transition: function( other, distance ) {
13043  var end = color( other ),
13044  spaceName = end._space(),
13045  space = spaces[ spaceName ],
13046  startColor = this.alpha() === 0 ? color( "transparent" ) : this,
13047  start = startColor[ space.cache ] || space.to( startColor._rgba ),
13048  result = start.slice();
13049 
13050  end = end[ space.cache ];
13051  each( space.props, function( key, prop ) {
13052  var index = prop.idx,
13053  startValue = start[ index ],
13054  endValue = end[ index ],
13055  type = propTypes[ prop.type ] || {};
13056 
13057  // if null, don't override start value
13058  if ( endValue === null ) {
13059  return;
13060  }
13061  // if null - use end
13062  if ( startValue === null ) {
13063  result[ index ] = endValue;
13064  } else {
13065  if ( type.mod ) {
13066  if ( endValue - startValue > type.mod / 2 ) {
13067  startValue += type.mod;
13068  } else if ( startValue - endValue > type.mod / 2 ) {
13069  startValue -= type.mod;
13070  }
13071  }
13072  result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
13073  }
13074  });
13075  return this[ spaceName ]( result );
13076  },
13077  blend: function( opaque ) {
13078  // if we are already opaque - return ourself
13079  if ( this._rgba[ 3 ] === 1 ) {
13080  return this;
13081  }
13082 
13083  var rgb = this._rgba.slice(),
13084  a = rgb.pop(),
13085  blend = color( opaque )._rgba;
13086 
13087  return color( jQuery.map( rgb, function( v, i ) {
13088  return ( 1 - a ) * blend[ i ] + a * v;
13089  }));
13090  },
13091  toRgbaString: function() {
13092  var prefix = "rgba(",
13093  rgba = jQuery.map( this._rgba, function( v, i ) {
13094  return v == null ? ( i > 2 ? 1 : 0 ) : v;
13095  });
13096 
13097  if ( rgba[ 3 ] === 1 ) {
13098  rgba.pop();
13099  prefix = "rgb(";
13100  }
13101 
13102  return prefix + rgba.join() + ")";
13103  },
13104  toHslaString: function() {
13105  var prefix = "hsla(",
13106  hsla = jQuery.map( this.hsla(), function( v, i ) {
13107  if ( v == null ) {
13108  v = i > 2 ? 1 : 0;
13109  }
13110 
13111  // catch 1 and 2
13112  if ( i && i < 3 ) {
13113  v = Math.round( v * 100 ) + "%";
13114  }
13115  return v;
13116  });
13117 
13118  if ( hsla[ 3 ] === 1 ) {
13119  hsla.pop();
13120  prefix = "hsl(";
13121  }
13122  return prefix + hsla.join() + ")";
13123  },
13124  toHexString: function( includeAlpha ) {
13125  var rgba = this._rgba.slice(),
13126  alpha = rgba.pop();
13127 
13128  if ( includeAlpha ) {
13129  rgba.push( ~~( alpha * 255 ) );
13130  }
13131 
13132  return "#" + jQuery.map( rgba, function( v ) {
13133 
13134  // default to 0 when nulls exist
13135  v = ( v || 0 ).toString( 16 );
13136  return v.length === 1 ? "0" + v : v;
13137  }).join("");
13138  },
13139  toString: function() {
13140  return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
13141  }
13142 });
13143 color.fn.parse.prototype = color.fn;
13144 
13145 // hsla conversions adapted from:
13146 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
13147 
13148 function hue2rgb( p, q, h ) {
13149  h = ( h + 1 ) % 1;
13150  if ( h * 6 < 1 ) {
13151  return p + (q - p) * h * 6;
13152  }
13153  if ( h * 2 < 1) {
13154  return q;
13155  }
13156  if ( h * 3 < 2 ) {
13157  return p + (q - p) * ((2/3) - h) * 6;
13158  }
13159  return p;
13160 }
13161 
13162 spaces.hsla.to = function ( rgba ) {
13163  if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
13164  return [ null, null, null, rgba[ 3 ] ];
13165  }
13166  var r = rgba[ 0 ] / 255,
13167  g = rgba[ 1 ] / 255,
13168  b = rgba[ 2 ] / 255,
13169  a = rgba[ 3 ],
13170  max = Math.max( r, g, b ),
13171  min = Math.min( r, g, b ),
13172  diff = max - min,
13173  add = max + min,
13174  l = add * 0.5,
13175  h, s;
13176 
13177  if ( min === max ) {
13178  h = 0;
13179  } else if ( r === max ) {
13180  h = ( 60 * ( g - b ) / diff ) + 360;
13181  } else if ( g === max ) {
13182  h = ( 60 * ( b - r ) / diff ) + 120;
13183  } else {
13184  h = ( 60 * ( r - g ) / diff ) + 240;
13185  }
13186 
13187  // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
13188  // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
13189  if ( diff === 0 ) {
13190  s = 0;
13191  } else if ( l <= 0.5 ) {
13192  s = diff / add;
13193  } else {
13194  s = diff / ( 2 - add );
13195  }
13196  return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
13197 };
13198 
13199 spaces.hsla.from = function ( hsla ) {
13200  if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
13201  return [ null, null, null, hsla[ 3 ] ];
13202  }
13203  var h = hsla[ 0 ] / 360,
13204  s = hsla[ 1 ],
13205  l = hsla[ 2 ],
13206  a = hsla[ 3 ],
13207  q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
13208  p = 2 * l - q;
13209 
13210  return [
13211  Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
13212  Math.round( hue2rgb( p, q, h ) * 255 ),
13213  Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
13214  a
13215  ];
13216 };
13217 
13218 
13219 each( spaces, function( spaceName, space ) {
13220  var props = space.props,
13221  cache = space.cache,
13222  to = space.to,
13223  from = space.from;
13224 
13225  // makes rgba() and hsla()
13226  color.fn[ spaceName ] = function( value ) {
13227 
13228  // generate a cache for this space if it doesn't exist
13229  if ( to && !this[ cache ] ) {
13230  this[ cache ] = to( this._rgba );
13231  }
13232  if ( value === undefined ) {
13233  return this[ cache ].slice();
13234  }
13235 
13236  var ret,
13237  type = jQuery.type( value ),
13238  arr = ( type === "array" || type === "object" ) ? value : arguments,
13239  local = this[ cache ].slice();
13240 
13241  each( props, function( key, prop ) {
13242  var val = arr[ type === "object" ? key : prop.idx ];
13243  if ( val == null ) {
13244  val = local[ prop.idx ];
13245  }
13246  local[ prop.idx ] = clamp( val, prop );
13247  });
13248 
13249  if ( from ) {
13250  ret = color( from( local ) );
13251  ret[ cache ] = local;
13252  return ret;
13253  } else {
13254  return color( local );
13255  }
13256  };
13257 
13258  // makes red() green() blue() alpha() hue() saturation() lightness()
13259  each( props, function( key, prop ) {
13260  // alpha is included in more than one space
13261  if ( color.fn[ key ] ) {
13262  return;
13263  }
13264  color.fn[ key ] = function( value ) {
13265  var vtype = jQuery.type( value ),
13266  fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
13267  local = this[ fn ](),
13268  cur = local[ prop.idx ],
13269  match;
13270 
13271  if ( vtype === "undefined" ) {
13272  return cur;
13273  }
13274 
13275  if ( vtype === "function" ) {
13276  value = value.call( this, cur );
13277  vtype = jQuery.type( value );
13278  }
13279  if ( value == null && prop.empty ) {
13280  return this;
13281  }
13282  if ( vtype === "string" ) {
13283  match = rplusequals.exec( value );
13284  if ( match ) {
13285  value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
13286  }
13287  }
13288  local[ prop.idx ] = value;
13289  return this[ fn ]( local );
13290  };
13291  });
13292 });
13293 
13294 // add cssHook and .fx.step function for each named hook.
13295 // accept a space separated string of properties
13296 color.hook = function( hook ) {
13297  var hooks = hook.split( " " );
13298  each( hooks, function( i, hook ) {
13299  jQuery.cssHooks[ hook ] = {
13300  set: function( elem, value ) {
13301  var parsed, curElem,
13302  backgroundColor = "";
13303 
13304  if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
13305  value = color( parsed || value );
13306  if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
13307  curElem = hook === "backgroundColor" ? elem.parentNode : elem;
13308  while (
13309  (backgroundColor === "" || backgroundColor === "transparent") &&
13310  curElem && curElem.style
13311  ) {
13312  try {
13313  backgroundColor = jQuery.css( curElem, "backgroundColor" );
13314  curElem = curElem.parentNode;
13315  } catch ( e ) {
13316  }
13317  }
13318 
13319  value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
13320  backgroundColor :
13321  "_default" );
13322  }
13323 
13324  value = value.toRgbaString();
13325  }
13326  try {
13327  elem.style[ hook ] = value;
13328  } catch( e ) {
13329  // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
13330  }
13331  }
13332  };
13333  jQuery.fx.step[ hook ] = function( fx ) {
13334  if ( !fx.colorInit ) {
13335  fx.start = color( fx.elem, hook );
13336  fx.end = color( fx.end );
13337  fx.colorInit = true;
13338  }
13339  jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
13340  };
13341  });
13342 
13343 };
13344 
13345 color.hook( stepHooks );
13346 
13347 jQuery.cssHooks.borderColor = {
13348  expand: function( value ) {
13349  var expanded = {};
13350 
13351  each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
13352  expanded[ "border" + part + "Color" ] = value;
13353  });
13354  return expanded;
13355  }
13356 };
13357 
13358 // Basic color names only.
13359 // Usage of any of the other color names requires adding yourself or including
13360 // jquery.color.svg-names.js.
13361 colors = jQuery.Color.names = {
13362  // 4.1. Basic color keywords
13363  aqua: "#00ffff",
13364  black: "#000000",
13365  blue: "#0000ff",
13366  fuchsia: "#ff00ff",
13367  gray: "#808080",
13368  green: "#008000",
13369  lime: "#00ff00",
13370  maroon: "#800000",
13371  navy: "#000080",
13372  olive: "#808000",
13373  purple: "#800080",
13374  red: "#ff0000",
13375  silver: "#c0c0c0",
13376  teal: "#008080",
13377  white: "#ffffff",
13378  yellow: "#ffff00",
13379 
13380  // 4.2.3. "transparent" color keyword
13381  transparent: [ null, null, null, 0 ],
13382 
13383  _default: "#ffffff"
13384 };
13385 
13386 })( jQuery );
13387 
13388 
13389 /******************************************************************************/
13390 /****************************** CLASS ANIMATIONS ******************************/
13391 /******************************************************************************/
13392 (function() {
13393 
13394 var classAnimationActions = [ "add", "remove", "toggle" ],
13395  shorthandStyles = {
13396  border: 1,
13397  borderBottom: 1,
13398  borderColor: 1,
13399  borderLeft: 1,
13400  borderRight: 1,
13401  borderTop: 1,
13402  borderWidth: 1,
13403  margin: 1,
13404  padding: 1
13405  };
13406 
13407 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
13408  $.fx.step[ prop ] = function( fx ) {
13409  if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
13410  jQuery.style( fx.elem, prop, fx.end );
13411  fx.setAttr = true;
13412  }
13413  };
13414 });
13415 
13416 function getElementStyles( elem ) {
13417  var key, len,
13418  style = elem.ownerDocument.defaultView ?
13419  elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
13420  elem.currentStyle,
13421  styles = {};
13422 
13423  if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
13424  len = style.length;
13425  while ( len-- ) {
13426  key = style[ len ];
13427  if ( typeof style[ key ] === "string" ) {
13428  styles[ $.camelCase( key ) ] = style[ key ];
13429  }
13430  }
13431  // support: Opera, IE <9
13432  } else {
13433  for ( key in style ) {
13434  if ( typeof style[ key ] === "string" ) {
13435  styles[ key ] = style[ key ];
13436  }
13437  }
13438  }
13439 
13440  return styles;
13441 }
13442 
13443 
13444 function styleDifference( oldStyle, newStyle ) {
13445  var diff = {},
13446  name, value;
13447 
13448  for ( name in newStyle ) {
13449  value = newStyle[ name ];
13450  if ( oldStyle[ name ] !== value ) {
13451  if ( !shorthandStyles[ name ] ) {
13452  if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
13453  diff[ name ] = value;
13454  }
13455  }
13456  }
13457  }
13458 
13459  return diff;
13460 }
13461 
13462 // support: jQuery <1.8
13463 if ( !$.fn.addBack ) {
13464  $.fn.addBack = function( selector ) {
13465  return this.add( selector == null ?
13466  this.prevObject : this.prevObject.filter( selector )
13467  );
13468  };
13469 }
13470 
13471 $.effects.animateClass = function( value, duration, easing, callback ) {
13472  var o = $.speed( duration, easing, callback );
13473 
13474  return this.queue( function() {
13475  var animated = $( this ),
13476  baseClass = animated.attr( "class" ) || "",
13477  applyClassChange,
13478  allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
13479 
13480  // map the animated objects to store the original styles.
13481  allAnimations = allAnimations.map(function() {
13482  var el = $( this );
13483  return {
13484  el: el,
13485  start: getElementStyles( this )
13486  };
13487  });
13488 
13489  // apply class change
13490  applyClassChange = function() {
13491  $.each( classAnimationActions, function(i, action) {
13492  if ( value[ action ] ) {
13493  animated[ action + "Class" ]( value[ action ] );
13494  }
13495  });
13496  };
13497  applyClassChange();
13498 
13499  // map all animated objects again - calculate new styles and diff
13500  allAnimations = allAnimations.map(function() {
13501  this.end = getElementStyles( this.el[ 0 ] );
13502  this.diff = styleDifference( this.start, this.end );
13503  return this;
13504  });
13505 
13506  // apply original class
13507  animated.attr( "class", baseClass );
13508 
13509  // map all animated objects again - this time collecting a promise
13510  allAnimations = allAnimations.map(function() {
13511  var styleInfo = this,
13512  dfd = $.Deferred(),
13513  opts = $.extend({}, o, {
13514  queue: false,
13515  complete: function() {
13516  dfd.resolve( styleInfo );
13517  }
13518  });
13519 
13520  this.el.animate( this.diff, opts );
13521  return dfd.promise();
13522  });
13523 
13524  // once all animations have completed:
13525  $.when.apply( $, allAnimations.get() ).done(function() {
13526 
13527  // set the final class
13528  applyClassChange();
13529 
13530  // for each animated element,
13531  // clear all css properties that were animated
13532  $.each( arguments, function() {
13533  var el = this.el;
13534  $.each( this.diff, function(key) {
13535  el.css( key, "" );
13536  });
13537  });
13538 
13539  // this is guarnteed to be there if you use jQuery.speed()
13540  // it also handles dequeuing the next anim...
13541  o.complete.call( animated[ 0 ] );
13542  });
13543  });
13544 };
13545 
13546 $.fn.extend({
13547  addClass: (function( orig ) {
13548  return function( classNames, speed, easing, callback ) {
13549  return speed ?
13550  $.effects.animateClass.call( this,
13551  { add: classNames }, speed, easing, callback ) :
13552  orig.apply( this, arguments );
13553  };
13554  })( $.fn.addClass ),
13555 
13556  removeClass: (function( orig ) {
13557  return function( classNames, speed, easing, callback ) {
13558  return arguments.length > 1 ?
13559  $.effects.animateClass.call( this,
13560  { remove: classNames }, speed, easing, callback ) :
13561  orig.apply( this, arguments );
13562  };
13563  })( $.fn.removeClass ),
13564 
13565  toggleClass: (function( orig ) {
13566  return function( classNames, force, speed, easing, callback ) {
13567  if ( typeof force === "boolean" || force === undefined ) {
13568  if ( !speed ) {
13569  // without speed parameter
13570  return orig.apply( this, arguments );
13571  } else {
13572  return $.effects.animateClass.call( this,
13573  (force ? { add: classNames } : { remove: classNames }),
13574  speed, easing, callback );
13575  }
13576  } else {
13577  // without force parameter
13578  return $.effects.animateClass.call( this,
13579  { toggle: classNames }, force, speed, easing );
13580  }
13581  };
13582  })( $.fn.toggleClass ),
13583 
13584  switchClass: function( remove, add, speed, easing, callback) {
13585  return $.effects.animateClass.call( this, {
13586  add: add,
13587  remove: remove
13588  }, speed, easing, callback );
13589  }
13590 });
13591 
13592 })();
13593 
13594 /******************************************************************************/
13595 /*********************************** EFFECTS **********************************/
13596 /******************************************************************************/
13597 
13598 (function() {
13599 
13600 $.extend( $.effects, {
13601  version: "1.10.3",
13602 
13603  // Saves a set of properties in a data storage
13604  save: function( element, set ) {
13605  for( var i=0; i < set.length; i++ ) {
13606  if ( set[ i ] !== null ) {
13607  element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
13608  }
13609  }
13610  },
13611 
13612  // Restores a set of previously saved properties from a data storage
13613  restore: function( element, set ) {
13614  var val, i;
13615  for( i=0; i < set.length; i++ ) {
13616  if ( set[ i ] !== null ) {
13617  val = element.data( dataSpace + set[ i ] );
13618  // support: jQuery 1.6.2
13619  // http://bugs.jquery.com/ticket/9917
13620  // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
13621  // We can't differentiate between "" and 0 here, so we just assume
13622  // empty string since it's likely to be a more common value...
13623  if ( val === undefined ) {
13624  val = "";
13625  }
13626  element.css( set[ i ], val );
13627  }
13628  }
13629  },
13630 
13631  setMode: function( el, mode ) {
13632  if (mode === "toggle") {
13633  mode = el.is( ":hidden" ) ? "show" : "hide";
13634  }
13635  return mode;
13636  },
13637 
13638  // Translates a [top,left] array into a baseline value
13639  // this should be a little more flexible in the future to handle a string & hash
13640  getBaseline: function( origin, original ) {
13641  var y, x;
13642  switch ( origin[ 0 ] ) {
13643  case "top": y = 0; break;
13644  case "middle": y = 0.5; break;
13645  case "bottom": y = 1; break;
13646  default: y = origin[ 0 ] / original.height;
13647  }
13648  switch ( origin[ 1 ] ) {
13649  case "left": x = 0; break;
13650  case "center": x = 0.5; break;
13651  case "right": x = 1; break;
13652  default: x = origin[ 1 ] / original.width;
13653  }
13654  return {
13655  x: x,
13656  y: y
13657  };
13658  },
13659 
13660  // Wraps the element around a wrapper that copies position properties
13661  createWrapper: function( element ) {
13662 
13663  // if the element is already wrapped, return it
13664  if ( element.parent().is( ".ui-effects-wrapper" )) {
13665  return element.parent();
13666  }
13667 
13668  // wrap the element
13669  var props = {
13670  width: element.outerWidth(true),
13671  height: element.outerHeight(true),
13672  "float": element.css( "float" )
13673  },
13674  wrapper = $( "<div></div>" )
13675  .addClass( "ui-effects-wrapper" )
13676  .css({
13677  fontSize: "100%",
13678  background: "transparent",
13679  border: "none",
13680  margin: 0,
13681  padding: 0
13682  }),
13683  // Store the size in case width/height are defined in % - Fixes #5245
13684  size = {
13685  width: element.width(),
13686  height: element.height()
13687  },
13688  active = document.activeElement;
13689 
13690  // support: Firefox
13691  // Firefox incorrectly exposes anonymous content
13692  // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
13693  try {
13694  active.id;
13695  } catch( e ) {
13696  active = document.body;
13697  }
13698 
13699  element.wrap( wrapper );
13700 
13701  // Fixes #7595 - Elements lose focus when wrapped.
13702  if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13703  $( active ).focus();
13704  }
13705 
13706  wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
13707 
13708  // transfer positioning properties to the wrapper
13709  if ( element.css( "position" ) === "static" ) {
13710  wrapper.css({ position: "relative" });
13711  element.css({ position: "relative" });
13712  } else {
13713  $.extend( props, {
13714  position: element.css( "position" ),
13715  zIndex: element.css( "z-index" )
13716  });
13717  $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
13718  props[ pos ] = element.css( pos );
13719  if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
13720  props[ pos ] = "auto";
13721  }
13722  });
13723  element.css({
13724  position: "relative",
13725  top: 0,
13726  left: 0,
13727  right: "auto",
13728  bottom: "auto"
13729  });
13730  }
13731  element.css(size);
13732 
13733  return wrapper.css( props ).show();
13734  },
13735 
13736  removeWrapper: function( element ) {
13737  var active = document.activeElement;
13738 
13739  if ( element.parent().is( ".ui-effects-wrapper" ) ) {
13740  element.parent().replaceWith( element );
13741 
13742  // Fixes #7595 - Elements lose focus when wrapped.
13743  if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
13744  $( active ).focus();
13745  }
13746  }
13747 
13748 
13749  return element;
13750  },
13751 
13752  setTransition: function( element, list, factor, value ) {
13753  value = value || {};
13754  $.each( list, function( i, x ) {
13755  var unit = element.cssUnit( x );
13756  if ( unit[ 0 ] > 0 ) {
13757  value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13758  }
13759  });
13760  return value;
13761  }
13762 });
13763 
13764 // return an effect options object for the given parameters:
13765 function _normalizeArguments( effect, options, speed, callback ) {
13766 
13767  // allow passing all options as the first parameter
13768  if ( $.isPlainObject( effect ) ) {
13769  options = effect;
13770  effect = effect.effect;
13771  }
13772 
13773  // convert to an object
13774  effect = { effect: effect };
13775 
13776  // catch (effect, null, ...)
13777  if ( options == null ) {
13778  options = {};
13779  }
13780 
13781  // catch (effect, callback)
13782  if ( $.isFunction( options ) ) {
13783  callback = options;
13784  speed = null;
13785  options = {};
13786  }
13787 
13788  // catch (effect, speed, ?)
13789  if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13790  callback = speed;
13791  speed = options;
13792  options = {};
13793  }
13794 
13795  // catch (effect, options, callback)
13796  if ( $.isFunction( speed ) ) {
13797  callback = speed;
13798  speed = null;
13799  }
13800 
13801  // add options to effect
13802  if ( options ) {
13803  $.extend( effect, options );
13804  }
13805 
13806  speed = speed || options.duration;
13807  effect.duration = $.fx.off ? 0 :
13808  typeof speed === "number" ? speed :
13809  speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13810  $.fx.speeds._default;
13811 
13812  effect.complete = callback || options.complete;
13813 
13814  return effect;
13815 }
13816 
13817 function standardAnimationOption( option ) {
13818  // Valid standard speeds (nothing, number, named speed)
13819  if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13820  return true;
13821  }
13822 
13823  // Invalid strings - treat as "normal" speed
13824  if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13825  return true;
13826  }
13827 
13828  // Complete callback
13829  if ( $.isFunction( option ) ) {
13830  return true;
13831  }
13832 
13833  // Options hash (but not naming an effect)
13834  if ( typeof option === "object" && !option.effect ) {
13835  return true;
13836  }
13837 
13838  // Didn't match any standard API
13839  return false;
13840 }
13841 
13842 $.fn.extend({
13843  effect: function( /* effect, options, speed, callback */ ) {
13844  var args = _normalizeArguments.apply( this, arguments ),
13845  mode = args.mode,
13846  queue = args.queue,
13847  effectMethod = $.effects.effect[ args.effect ];
13848 
13849  if ( $.fx.off || !effectMethod ) {
13850  // delegate to the original method (e.g., .show()) if possible
13851  if ( mode ) {
13852  return this[ mode ]( args.duration, args.complete );
13853  } else {
13854  return this.each( function() {
13855  if ( args.complete ) {
13856  args.complete.call( this );
13857  }
13858  });
13859  }
13860  }
13861 
13862  function run( next ) {
13863  var elem = $( this ),
13864  complete = args.complete,
13865  mode = args.mode;
13866 
13867  function done() {
13868  if ( $.isFunction( complete ) ) {
13869  complete.call( elem[0] );
13870  }
13871  if ( $.isFunction( next ) ) {
13872  next();
13873  }
13874  }
13875 
13876  // If the element already has the correct final state, delegate to
13877  // the core methods so the internal tracking of "olddisplay" works.
13878  if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13879  elem[ mode ]();
13880  done();
13881  } else {
13882  effectMethod.call( elem[0], args, done );
13883  }
13884  }
13885 
13886  return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
13887  },
13888 
13889  show: (function( orig ) {
13890  return function( option ) {
13891  if ( standardAnimationOption( option ) ) {
13892  return orig.apply( this, arguments );
13893  } else {
13894  var args = _normalizeArguments.apply( this, arguments );
13895  args.mode = "show";
13896  return this.effect.call( this, args );
13897  }
13898  };
13899  })( $.fn.show ),
13900 
13901  hide: (function( orig ) {
13902  return function( option ) {
13903  if ( standardAnimationOption( option ) ) {
13904  return orig.apply( this, arguments );
13905  } else {
13906  var args = _normalizeArguments.apply( this, arguments );
13907  args.mode = "hide";
13908  return this.effect.call( this, args );
13909  }
13910  };
13911  })( $.fn.hide ),
13912 
13913  toggle: (function( orig ) {
13914  return function( option ) {
13915  if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13916  return orig.apply( this, arguments );
13917  } else {
13918  var args = _normalizeArguments.apply( this, arguments );
13919  args.mode = "toggle";
13920  return this.effect.call( this, args );
13921  }
13922  };
13923  })( $.fn.toggle ),
13924 
13925  // helper functions
13926  cssUnit: function(key) {
13927  var style = this.css( key ),
13928  val = [];
13929 
13930  $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13931  if ( style.indexOf( unit ) > 0 ) {
13932  val = [ parseFloat( style ), unit ];
13933  }
13934  });
13935  return val;
13936  }
13937 });
13938 
13939 })();
13940 
13941 /******************************************************************************/
13942 /*********************************** EASING ***********************************/
13943 /******************************************************************************/
13944 
13945 (function() {
13946 
13947 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
13948 
13949 var baseEasings = {};
13950 
13951 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13952  baseEasings[ name ] = function( p ) {
13953  return Math.pow( p, i + 2 );
13954  };
13955 });
13956 
13957 $.extend( baseEasings, {
13958  Sine: function ( p ) {
13959  return 1 - Math.cos( p * Math.PI / 2 );
13960  },
13961  Circ: function ( p ) {
13962  return 1 - Math.sqrt( 1 - p * p );
13963  },
13964  Elastic: function( p ) {
13965  return p === 0 || p === 1 ? p :
13966  -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
13967  },
13968  Back: function( p ) {
13969  return p * p * ( 3 * p - 2 );
13970  },
13971  Bounce: function ( p ) {
13972  var pow2,
13973  bounce = 4;
13974 
13975  while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13976  return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13977  }
13978 });
13979 
13980 $.each( baseEasings, function( name, easeIn ) {
13981  $.easing[ "easeIn" + name ] = easeIn;
13982  $.easing[ "easeOut" + name ] = function( p ) {
13983  return 1 - easeIn( 1 - p );
13984  };
13985  $.easing[ "easeInOut" + name ] = function( p ) {
13986  return p < 0.5 ?
13987  easeIn( p * 2 ) / 2 :
13988  1 - easeIn( p * -2 + 2 ) / 2;
13989  };
13990 });
13991 
13992 })();
13993 
13994 })(jQuery);
13995 (function( $, undefined ) {
13996 
13997 var rvertical = /up|down|vertical/,
13998  rpositivemotion = /up|left|vertical|horizontal/;
13999 
14000 $.effects.effect.blind = function( o, done ) {
14001  // Create element
14002  var el = $( this ),
14003  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14004  mode = $.effects.setMode( el, o.mode || "hide" ),
14005  direction = o.direction || "up",
14006  vertical = rvertical.test( direction ),
14007  ref = vertical ? "height" : "width",
14008  ref2 = vertical ? "top" : "left",
14009  motion = rpositivemotion.test( direction ),
14010  animation = {},
14011  show = mode === "show",
14012  wrapper, distance, margin;
14013 
14014  // if already wrapped, the wrapper's properties are my property. #6245
14015  if ( el.parent().is( ".ui-effects-wrapper" ) ) {
14016  $.effects.save( el.parent(), props );
14017  } else {
14018  $.effects.save( el, props );
14019  }
14020  el.show();
14021  wrapper = $.effects.createWrapper( el ).css({
14022  overflow: "hidden"
14023  });
14024 
14025  distance = wrapper[ ref ]();
14026  margin = parseFloat( wrapper.css( ref2 ) ) || 0;
14027 
14028  animation[ ref ] = show ? distance : 0;
14029  if ( !motion ) {
14030  el
14031  .css( vertical ? "bottom" : "right", 0 )
14032  .css( vertical ? "top" : "left", "auto" )
14033  .css({ position: "absolute" });
14034 
14035  animation[ ref2 ] = show ? margin : distance + margin;
14036  }
14037 
14038  // start at 0 if we are showing
14039  if ( show ) {
14040  wrapper.css( ref, 0 );
14041  if ( ! motion ) {
14042  wrapper.css( ref2, margin + distance );
14043  }
14044  }
14045 
14046  // Animate
14047  wrapper.animate( animation, {
14048  duration: o.duration,
14049  easing: o.easing,
14050  queue: false,
14051  complete: function() {
14052  if ( mode === "hide" ) {
14053  el.hide();
14054  }
14055  $.effects.restore( el, props );
14056  $.effects.removeWrapper( el );
14057  done();
14058  }
14059  });
14060 
14061 };
14062 
14063 })(jQuery);
14064 (function( $, undefined ) {
14065 
14066 $.effects.effect.bounce = function( o, done ) {
14067  var el = $( this ),
14068  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14069 
14070  // defaults:
14071  mode = $.effects.setMode( el, o.mode || "effect" ),
14072  hide = mode === "hide",
14073  show = mode === "show",
14074  direction = o.direction || "up",
14075  distance = o.distance,
14076  times = o.times || 5,
14077 
14078  // number of internal animations
14079  anims = times * 2 + ( show || hide ? 1 : 0 ),
14080  speed = o.duration / anims,
14081  easing = o.easing,
14082 
14083  // utility:
14084  ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14085  motion = ( direction === "up" || direction === "left" ),
14086  i,
14087  upAnim,
14088  downAnim,
14089 
14090  // we will need to re-assemble the queue to stack our animations in place
14091  queue = el.queue(),
14092  queuelen = queue.length;
14093 
14094  // Avoid touching opacity to prevent clearType and PNG issues in IE
14095  if ( show || hide ) {
14096  props.push( "opacity" );
14097  }
14098 
14099  $.effects.save( el, props );
14100  el.show();
14101  $.effects.createWrapper( el ); // Create Wrapper
14102 
14103  // default distance for the BIGGEST bounce is the outer Distance / 3
14104  if ( !distance ) {
14105  distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14106  }
14107 
14108  if ( show ) {
14109  downAnim = { opacity: 1 };
14110  downAnim[ ref ] = 0;
14111 
14112  // if we are showing, force opacity 0 and set the initial position
14113  // then do the "first" animation
14114  el.css( "opacity", 0 )
14115  .css( ref, motion ? -distance * 2 : distance * 2 )
14116  .animate( downAnim, speed, easing );
14117  }
14118 
14119  // start at the smallest distance if we are hiding
14120  if ( hide ) {
14121  distance = distance / Math.pow( 2, times - 1 );
14122  }
14123 
14124  downAnim = {};
14125  downAnim[ ref ] = 0;
14126  // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14127  for ( i = 0; i < times; i++ ) {
14128  upAnim = {};
14129  upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14130 
14131  el.animate( upAnim, speed, easing )
14132  .animate( downAnim, speed, easing );
14133 
14134  distance = hide ? distance * 2 : distance / 2;
14135  }
14136 
14137  // Last Bounce when Hiding
14138  if ( hide ) {
14139  upAnim = { opacity: 0 };
14140  upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14141 
14142  el.animate( upAnim, speed, easing );
14143  }
14144 
14145  el.queue(function() {
14146  if ( hide ) {
14147  el.hide();
14148  }
14149  $.effects.restore( el, props );
14150  $.effects.removeWrapper( el );
14151  done();
14152  });
14153 
14154  // inject all the animations we just queued to be first in line (after "inprogress")
14155  if ( queuelen > 1) {
14156  queue.splice.apply( queue,
14157  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14158  }
14159  el.dequeue();
14160 
14161 };
14162 
14163 })(jQuery);
14164 (function( $, undefined ) {
14165 
14166 $.effects.effect.clip = function( o, done ) {
14167  // Create element
14168  var el = $( this ),
14169  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14170  mode = $.effects.setMode( el, o.mode || "hide" ),
14171  show = mode === "show",
14172  direction = o.direction || "vertical",
14173  vert = direction === "vertical",
14174  size = vert ? "height" : "width",
14175  position = vert ? "top" : "left",
14176  animation = {},
14177  wrapper, animate, distance;
14178 
14179  // Save & Show
14180  $.effects.save( el, props );
14181  el.show();
14182 
14183  // Create Wrapper
14184  wrapper = $.effects.createWrapper( el ).css({
14185  overflow: "hidden"
14186  });
14187  animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
14188  distance = animate[ size ]();
14189 
14190  // Shift
14191  if ( show ) {
14192  animate.css( size, 0 );
14193  animate.css( position, distance / 2 );
14194  }
14195 
14196  // Create Animation Object:
14197  animation[ size ] = show ? distance : 0;
14198  animation[ position ] = show ? 0 : distance / 2;
14199 
14200  // Animate
14201  animate.animate( animation, {
14202  queue: false,
14203  duration: o.duration,
14204  easing: o.easing,
14205  complete: function() {
14206  if ( !show ) {
14207  el.hide();
14208  }
14209  $.effects.restore( el, props );
14210  $.effects.removeWrapper( el );
14211  done();
14212  }
14213  });
14214 
14215 };
14216 
14217 })(jQuery);
14218 (function( $, undefined ) {
14219 
14220 $.effects.effect.drop = function( o, done ) {
14221 
14222  var el = $( this ),
14223  props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
14224  mode = $.effects.setMode( el, o.mode || "hide" ),
14225  show = mode === "show",
14226  direction = o.direction || "left",
14227  ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14228  motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
14229  animation = {
14230  opacity: show ? 1 : 0
14231  },
14232  distance;
14233 
14234  // Adjust
14235  $.effects.save( el, props );
14236  el.show();
14237  $.effects.createWrapper( el );
14238 
14239  distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
14240 
14241  if ( show ) {
14242  el
14243  .css( "opacity", 0 )
14244  .css( ref, motion === "pos" ? -distance : distance );
14245  }
14246 
14247  // Animation
14248  animation[ ref ] = ( show ?
14249  ( motion === "pos" ? "+=" : "-=" ) :
14250  ( motion === "pos" ? "-=" : "+=" ) ) +
14251  distance;
14252 
14253  // Animate
14254  el.animate( animation, {
14255  queue: false,
14256  duration: o.duration,
14257  easing: o.easing,
14258  complete: function() {
14259  if ( mode === "hide" ) {
14260  el.hide();
14261  }
14262  $.effects.restore( el, props );
14263  $.effects.removeWrapper( el );
14264  done();
14265  }
14266  });
14267 };
14268 
14269 })(jQuery);
14270 (function( $, undefined ) {
14271 
14272 $.effects.effect.explode = function( o, done ) {
14273 
14274  var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
14275  cells = rows,
14276  el = $( this ),
14277  mode = $.effects.setMode( el, o.mode || "hide" ),
14278  show = mode === "show",
14279 
14280  // show and then visibility:hidden the element before calculating offset
14281  offset = el.show().css( "visibility", "hidden" ).offset(),
14282 
14283  // width and height of a piece
14284  width = Math.ceil( el.outerWidth() / cells ),
14285  height = Math.ceil( el.outerHeight() / rows ),
14286  pieces = [],
14287 
14288  // loop
14289  i, j, left, top, mx, my;
14290 
14291  // children animate complete:
14292  function childComplete() {
14293  pieces.push( this );
14294  if ( pieces.length === rows * cells ) {
14295  animComplete();
14296  }
14297  }
14298 
14299  // clone the element for each row and cell.
14300  for( i = 0; i < rows ; i++ ) { // ===>
14301  top = offset.top + i * height;
14302  my = i - ( rows - 1 ) / 2 ;
14303 
14304  for( j = 0; j < cells ; j++ ) { // |||
14305  left = offset.left + j * width;
14306  mx = j - ( cells - 1 ) / 2 ;
14307 
14308  // Create a clone of the now hidden main element that will be absolute positioned
14309  // within a wrapper div off the -left and -top equal to size of our pieces
14310  el
14311  .clone()
14312  .appendTo( "body" )
14313  .wrap( "<div></div>" )
14314  .css({
14315  position: "absolute",
14316  visibility: "visible",
14317  left: -j * width,
14318  top: -i * height
14319  })
14320 
14321  // select the wrapper - make it overflow: hidden and absolute positioned based on
14322  // where the original was located +left and +top equal to the size of pieces
14323  .parent()
14324  .addClass( "ui-effects-explode" )
14325  .css({
14326  position: "absolute",
14327  overflow: "hidden",
14328  width: width,
14329  height: height,
14330  left: left + ( show ? mx * width : 0 ),
14331  top: top + ( show ? my * height : 0 ),
14332  opacity: show ? 0 : 1
14333  }).animate({
14334  left: left + ( show ? 0 : mx * width ),
14335  top: top + ( show ? 0 : my * height ),
14336  opacity: show ? 1 : 0
14337  }, o.duration || 500, o.easing, childComplete );
14338  }
14339  }
14340 
14341  function animComplete() {
14342  el.css({
14343  visibility: "visible"
14344  });
14345  $( pieces ).remove();
14346  if ( !show ) {
14347  el.hide();
14348  }
14349  done();
14350  }
14351 };
14352 
14353 })(jQuery);
14354 (function( $, undefined ) {
14355 
14356 $.effects.effect.fade = function( o, done ) {
14357  var el = $( this ),
14358  mode = $.effects.setMode( el, o.mode || "toggle" );
14359 
14360  el.animate({
14361  opacity: mode
14362  }, {
14363  queue: false,
14364  duration: o.duration,
14365  easing: o.easing,
14366  complete: done
14367  });
14368 };
14369 
14370 })( jQuery );
14371 (function( $, undefined ) {
14372 
14373 $.effects.effect.fold = function( o, done ) {
14374 
14375  // Create element
14376  var el = $( this ),
14377  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14378  mode = $.effects.setMode( el, o.mode || "hide" ),
14379  show = mode === "show",
14380  hide = mode === "hide",
14381  size = o.size || 15,
14382  percent = /([0-9]+)%/.exec( size ),
14383  horizFirst = !!o.horizFirst,
14384  widthFirst = show !== horizFirst,
14385  ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
14386  duration = o.duration / 2,
14387  wrapper, distance,
14388  animation1 = {},
14389  animation2 = {};
14390 
14391  $.effects.save( el, props );
14392  el.show();
14393 
14394  // Create Wrapper
14395  wrapper = $.effects.createWrapper( el ).css({
14396  overflow: "hidden"
14397  });
14398  distance = widthFirst ?
14399  [ wrapper.width(), wrapper.height() ] :
14400  [ wrapper.height(), wrapper.width() ];
14401 
14402  if ( percent ) {
14403  size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
14404  }
14405  if ( show ) {
14406  wrapper.css( horizFirst ? {
14407  height: 0,
14408  width: size
14409  } : {
14410  height: size,
14411  width: 0
14412  });
14413  }
14414 
14415  // Animation
14416  animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
14417  animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
14418 
14419  // Animate
14420  wrapper
14421  .animate( animation1, duration, o.easing )
14422  .animate( animation2, duration, o.easing, function() {
14423  if ( hide ) {
14424  el.hide();
14425  }
14426  $.effects.restore( el, props );
14427  $.effects.removeWrapper( el );
14428  done();
14429  });
14430 
14431 };
14432 
14433 })(jQuery);
14434 (function( $, undefined ) {
14435 
14436 $.effects.effect.highlight = function( o, done ) {
14437  var elem = $( this ),
14438  props = [ "backgroundImage", "backgroundColor", "opacity" ],
14439  mode = $.effects.setMode( elem, o.mode || "show" ),
14440  animation = {
14441  backgroundColor: elem.css( "backgroundColor" )
14442  };
14443 
14444  if (mode === "hide") {
14445  animation.opacity = 0;
14446  }
14447 
14448  $.effects.save( elem, props );
14449 
14450  elem
14451  .show()
14452  .css({
14453  backgroundImage: "none",
14454  backgroundColor: o.color || "#ffff99"
14455  })
14456  .animate( animation, {
14457  queue: false,
14458  duration: o.duration,
14459  easing: o.easing,
14460  complete: function() {
14461  if ( mode === "hide" ) {
14462  elem.hide();
14463  }
14464  $.effects.restore( elem, props );
14465  done();
14466  }
14467  });
14468 };
14469 
14470 })(jQuery);
14471 (function( $, undefined ) {
14472 
14473 $.effects.effect.pulsate = function( o, done ) {
14474  var elem = $( this ),
14475  mode = $.effects.setMode( elem, o.mode || "show" ),
14476  show = mode === "show",
14477  hide = mode === "hide",
14478  showhide = ( show || mode === "hide" ),
14479 
14480  // showing or hiding leaves of the "last" animation
14481  anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
14482  duration = o.duration / anims,
14483  animateTo = 0,
14484  queue = elem.queue(),
14485  queuelen = queue.length,
14486  i;
14487 
14488  if ( show || !elem.is(":visible")) {
14489  elem.css( "opacity", 0 ).show();
14490  animateTo = 1;
14491  }
14492 
14493  // anims - 1 opacity "toggles"
14494  for ( i = 1; i < anims; i++ ) {
14495  elem.animate({
14496  opacity: animateTo
14497  }, duration, o.easing );
14498  animateTo = 1 - animateTo;
14499  }
14500 
14501  elem.animate({
14502  opacity: animateTo
14503  }, duration, o.easing);
14504 
14505  elem.queue(function() {
14506  if ( hide ) {
14507  elem.hide();
14508  }
14509  done();
14510  });
14511 
14512  // We just queued up "anims" animations, we need to put them next in the queue
14513  if ( queuelen > 1 ) {
14514  queue.splice.apply( queue,
14515  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14516  }
14517  elem.dequeue();
14518 };
14519 
14520 })(jQuery);
14521 (function( $, undefined ) {
14522 
14523 $.effects.effect.puff = function( o, done ) {
14524  var elem = $( this ),
14525  mode = $.effects.setMode( elem, o.mode || "hide" ),
14526  hide = mode === "hide",
14527  percent = parseInt( o.percent, 10 ) || 150,
14528  factor = percent / 100,
14529  original = {
14530  height: elem.height(),
14531  width: elem.width(),
14532  outerHeight: elem.outerHeight(),
14533  outerWidth: elem.outerWidth()
14534  };
14535 
14536  $.extend( o, {
14537  effect: "scale",
14538  queue: false,
14539  fade: true,
14540  mode: mode,
14541  complete: done,
14542  percent: hide ? percent : 100,
14543  from: hide ?
14544  original :
14545  {
14546  height: original.height * factor,
14547  width: original.width * factor,
14548  outerHeight: original.outerHeight * factor,
14549  outerWidth: original.outerWidth * factor
14550  }
14551  });
14552 
14553  elem.effect( o );
14554 };
14555 
14556 $.effects.effect.scale = function( o, done ) {
14557 
14558  // Create element
14559  var el = $( this ),
14560  options = $.extend( true, {}, o ),
14561  mode = $.effects.setMode( el, o.mode || "effect" ),
14562  percent = parseInt( o.percent, 10 ) ||
14563  ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
14564  direction = o.direction || "both",
14565  origin = o.origin,
14566  original = {
14567  height: el.height(),
14568  width: el.width(),
14569  outerHeight: el.outerHeight(),
14570  outerWidth: el.outerWidth()
14571  },
14572  factor = {
14573  y: direction !== "horizontal" ? (percent / 100) : 1,
14574  x: direction !== "vertical" ? (percent / 100) : 1
14575  };
14576 
14577  // We are going to pass this effect to the size effect:
14578  options.effect = "size";
14579  options.queue = false;
14580  options.complete = done;
14581 
14582  // Set default origin and restore for show/hide
14583  if ( mode !== "effect" ) {
14584  options.origin = origin || ["middle","center"];
14585  options.restore = true;
14586  }
14587 
14588  options.from = o.from || ( mode === "show" ? {
14589  height: 0,
14590  width: 0,
14591  outerHeight: 0,
14592  outerWidth: 0
14593  } : original );
14594  options.to = {
14595  height: original.height * factor.y,
14596  width: original.width * factor.x,
14597  outerHeight: original.outerHeight * factor.y,
14598  outerWidth: original.outerWidth * factor.x
14599  };
14600 
14601  // Fade option to support puff
14602  if ( options.fade ) {
14603  if ( mode === "show" ) {
14604  options.from.opacity = 0;
14605  options.to.opacity = 1;
14606  }
14607  if ( mode === "hide" ) {
14608  options.from.opacity = 1;
14609  options.to.opacity = 0;
14610  }
14611  }
14612 
14613  // Animate
14614  el.effect( options );
14615 
14616 };
14617 
14618 $.effects.effect.size = function( o, done ) {
14619 
14620  // Create element
14621  var original, baseline, factor,
14622  el = $( this ),
14623  props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
14624 
14625  // Always restore
14626  props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
14627 
14628  // Copy for children
14629  props2 = [ "width", "height", "overflow" ],
14630  cProps = [ "fontSize" ],
14631  vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
14632  hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
14633 
14634  // Set options
14635  mode = $.effects.setMode( el, o.mode || "effect" ),
14636  restore = o.restore || mode !== "effect",
14637  scale = o.scale || "both",
14638  origin = o.origin || [ "middle", "center" ],
14639  position = el.css( "position" ),
14640  props = restore ? props0 : props1,
14641  zero = {
14642  height: 0,
14643  width: 0,
14644  outerHeight: 0,
14645  outerWidth: 0
14646  };
14647 
14648  if ( mode === "show" ) {
14649  el.show();
14650  }
14651  original = {
14652  height: el.height(),
14653  width: el.width(),
14654  outerHeight: el.outerHeight(),
14655  outerWidth: el.outerWidth()
14656  };
14657 
14658  if ( o.mode === "toggle" && mode === "show" ) {
14659  el.from = o.to || zero;
14660  el.to = o.from || original;
14661  } else {
14662  el.from = o.from || ( mode === "show" ? zero : original );
14663  el.to = o.to || ( mode === "hide" ? zero : original );
14664  }
14665 
14666  // Set scaling factor
14667  factor = {
14668  from: {
14669  y: el.from.height / original.height,
14670  x: el.from.width / original.width
14671  },
14672  to: {
14673  y: el.to.height / original.height,
14674  x: el.to.width / original.width
14675  }
14676  };
14677 
14678  // Scale the css box
14679  if ( scale === "box" || scale === "both" ) {
14680 
14681  // Vertical props scaling
14682  if ( factor.from.y !== factor.to.y ) {
14683  props = props.concat( vProps );
14684  el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
14685  el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
14686  }
14687 
14688  // Horizontal props scaling
14689  if ( factor.from.x !== factor.to.x ) {
14690  props = props.concat( hProps );
14691  el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
14692  el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
14693  }
14694  }
14695 
14696  // Scale the content
14697  if ( scale === "content" || scale === "both" ) {
14698 
14699  // Vertical props scaling
14700  if ( factor.from.y !== factor.to.y ) {
14701  props = props.concat( cProps ).concat( props2 );
14702  el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
14703  el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
14704  }
14705  }
14706 
14707  $.effects.save( el, props );
14708  el.show();
14709  $.effects.createWrapper( el );
14710  el.css( "overflow", "hidden" ).css( el.from );
14711 
14712  // Adjust
14713  if (origin) { // Calculate baseline shifts
14714  baseline = $.effects.getBaseline( origin, original );
14715  el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
14716  el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
14717  el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
14718  el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
14719  }
14720  el.css( el.from ); // set top & left
14721 
14722  // Animate
14723  if ( scale === "content" || scale === "both" ) { // Scale the children
14724 
14725  // Add margins/font-size
14726  vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
14727  hProps = hProps.concat([ "marginLeft", "marginRight" ]);
14728  props2 = props0.concat(vProps).concat(hProps);
14729 
14730  el.find( "*[width]" ).each( function(){
14731  var child = $( this ),
14732  c_original = {
14733  height: child.height(),
14734  width: child.width(),
14735  outerHeight: child.outerHeight(),
14736  outerWidth: child.outerWidth()
14737  };
14738  if (restore) {
14739  $.effects.save(child, props2);
14740  }
14741 
14742  child.from = {
14743  height: c_original.height * factor.from.y,
14744  width: c_original.width * factor.from.x,
14745  outerHeight: c_original.outerHeight * factor.from.y,
14746  outerWidth: c_original.outerWidth * factor.from.x
14747  };
14748  child.to = {
14749  height: c_original.height * factor.to.y,
14750  width: c_original.width * factor.to.x,
14751  outerHeight: c_original.height * factor.to.y,
14752  outerWidth: c_original.width * factor.to.x
14753  };
14754 
14755  // Vertical props scaling
14756  if ( factor.from.y !== factor.to.y ) {
14757  child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
14758  child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
14759  }
14760 
14761  // Horizontal props scaling
14762  if ( factor.from.x !== factor.to.x ) {
14763  child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
14764  child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
14765  }
14766 
14767  // Animate children
14768  child.css( child.from );
14769  child.animate( child.to, o.duration, o.easing, function() {
14770 
14771  // Restore children
14772  if ( restore ) {
14773  $.effects.restore( child, props2 );
14774  }
14775  });
14776  });
14777  }
14778 
14779  // Animate
14780  el.animate( el.to, {
14781  queue: false,
14782  duration: o.duration,
14783  easing: o.easing,
14784  complete: function() {
14785  if ( el.to.opacity === 0 ) {
14786  el.css( "opacity", el.from.opacity );
14787  }
14788  if( mode === "hide" ) {
14789  el.hide();
14790  }
14791  $.effects.restore( el, props );
14792  if ( !restore ) {
14793 
14794  // we need to calculate our new positioning based on the scaling
14795  if ( position === "static" ) {
14796  el.css({
14797  position: "relative",
14798  top: el.to.top,
14799  left: el.to.left
14800  });
14801  } else {
14802  $.each([ "top", "left" ], function( idx, pos ) {
14803  el.css( pos, function( _, str ) {
14804  var val = parseInt( str, 10 ),
14805  toRef = idx ? el.to.left : el.to.top;
14806 
14807  // if original was "auto", recalculate the new value from wrapper
14808  if ( str === "auto" ) {
14809  return toRef + "px";
14810  }
14811 
14812  return val + toRef + "px";
14813  });
14814  });
14815  }
14816  }
14817 
14818  $.effects.removeWrapper( el );
14819  done();
14820  }
14821  });
14822 
14823 };
14824 
14825 })(jQuery);
14826 (function( $, undefined ) {
14827 
14828 $.effects.effect.shake = function( o, done ) {
14829 
14830  var el = $( this ),
14831  props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
14832  mode = $.effects.setMode( el, o.mode || "effect" ),
14833  direction = o.direction || "left",
14834  distance = o.distance || 20,
14835  times = o.times || 3,
14836  anims = times * 2 + 1,
14837  speed = Math.round(o.duration/anims),
14838  ref = (direction === "up" || direction === "down") ? "top" : "left",
14839  positiveMotion = (direction === "up" || direction === "left"),
14840  animation = {},
14841  animation1 = {},
14842  animation2 = {},
14843  i,
14844 
14845  // we will need to re-assemble the queue to stack our animations in place
14846  queue = el.queue(),
14847  queuelen = queue.length;
14848 
14849  $.effects.save( el, props );
14850  el.show();
14851  $.effects.createWrapper( el );
14852 
14853  // Animation
14854  animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
14855  animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
14856  animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
14857 
14858  // Animate
14859  el.animate( animation, speed, o.easing );
14860 
14861  // Shakes
14862  for ( i = 1; i < times; i++ ) {
14863  el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
14864  }
14865  el
14866  .animate( animation1, speed, o.easing )
14867  .animate( animation, speed / 2, o.easing )
14868  .queue(function() {
14869  if ( mode === "hide" ) {
14870  el.hide();
14871  }
14872  $.effects.restore( el, props );
14873  $.effects.removeWrapper( el );
14874  done();
14875  });
14876 
14877  // inject all the animations we just queued to be first in line (after "inprogress")
14878  if ( queuelen > 1) {
14879  queue.splice.apply( queue,
14880  [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
14881  }
14882  el.dequeue();
14883 
14884 };
14885 
14886 })(jQuery);
14887 (function( $, undefined ) {
14888 
14889 $.effects.effect.slide = function( o, done ) {
14890 
14891  // Create element
14892  var el = $( this ),
14893  props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
14894  mode = $.effects.setMode( el, o.mode || "show" ),
14895  show = mode === "show",
14896  direction = o.direction || "left",
14897  ref = (direction === "up" || direction === "down") ? "top" : "left",
14898  positiveMotion = (direction === "up" || direction === "left"),
14899  distance,
14900  animation = {};
14901 
14902  // Adjust
14903  $.effects.save( el, props );
14904  el.show();
14905  distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
14906 
14907  $.effects.createWrapper( el ).css({
14908  overflow: "hidden"
14909  });
14910 
14911  if ( show ) {
14912  el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
14913  }
14914 
14915  // Animation
14916  animation[ ref ] = ( show ?
14917  ( positiveMotion ? "+=" : "-=") :
14918  ( positiveMotion ? "-=" : "+=")) +
14919  distance;
14920 
14921  // Animate
14922  el.animate( animation, {
14923  queue: false,
14924  duration: o.duration,
14925  easing: o.easing,
14926  complete: function() {
14927  if ( mode === "hide" ) {
14928  el.hide();
14929  }
14930  $.effects.restore( el, props );
14931  $.effects.removeWrapper( el );
14932  done();
14933  }
14934  });
14935 };
14936 
14937 })(jQuery);
14938 (function( $, undefined ) {
14939 
14940 $.effects.effect.transfer = function( o, done ) {
14941  var elem = $( this ),
14942  target = $( o.to ),
14943  targetFixed = target.css( "position" ) === "fixed",
14944  body = $("body"),
14945  fixTop = targetFixed ? body.scrollTop() : 0,
14946  fixLeft = targetFixed ? body.scrollLeft() : 0,
14947  endPosition = target.offset(),
14948  animation = {
14949  top: endPosition.top - fixTop ,
14950  left: endPosition.left - fixLeft ,
14951  height: target.innerHeight(),
14952  width: target.innerWidth()
14953  },
14954  startPosition = elem.offset(),
14955  transfer = $( "<div class='ui-effects-transfer'></div>" )
14956  .appendTo( document.body )
14957  .addClass( o.className )
14958  .css({
14959  top: startPosition.top - fixTop ,
14960  left: startPosition.left - fixLeft ,
14961  height: elem.innerHeight(),
14962  width: elem.innerWidth(),
14963  position: targetFixed ? "fixed" : "absolute"
14964  })
14965  .animate( animation, o.duration, o.easing, function() {
14966  transfer.remove();
14967  done();
14968  });
14969 };
14970 
14971 })(jQuery);