Index: admin/_charte.php
===================================================================
--- admin/_charte.php	(revision 3639)
+++ admin/_charte.php	(revision 3685)
@@ -39,5 +39,4 @@
 	<script type="text/javascript" src="js/jquery/jquery.pageTabs.js"></script>
 	<script type="text/javascript" src="js/jquery/jquery.biscuit.js"></script>
-	<script type="text/javascript" src="js/jquery/jquery.bgFade.js"></script>
 	<script type="text/javascript" src="js/common.js"></script>
 	<script type="text/javascript" src="js/prelude.js"></script>
Index: admin/js/_preferences.js
===================================================================
--- admin/js/_preferences.js	(revision 2736)
+++ admin/js/_preferences.js	(revision 3685)
@@ -1,22 +1,20 @@
 $(function() {
-	if ($('#new_pwd').length == 0) {
-		return;
-	}
-
-	var user_email = $('#user_email').val();
-
-	$('#user-form').submit(function() {
-		var e = this.elements['cur_pwd'];
-		if (e.value != '') {
-			return true;
-		}
-		if ($('#user_email').val() != user_email || $('#new_pwd').val() != '') {
-			e.focus();
-			$(e).backgroundFade({sColor: dotclear.fadeColor.beginUserMail, eColor: dotclear.fadeColor.endUserMail, steps: 50},function() {
-				$(this).backgroundFade({sColor: dotclear.fadeColor.endUserMail, eColor: dotclear.fadeColor.beginUserMail});
-			});
-			return false;
-		}
-		return true;
-	});
+  if ($('#new_pwd').length == 0) {
+    return;
+  }
+  var user_email = $('#user_email').val();
+  $('#user-form').submit(function() {
+    var e = this.elements['cur_pwd'];
+    if (e.value != '') {
+      return true;
+    }
+    if ($('#user_email').val() != user_email || $('#new_pwd').val() != '') {
+      $(e).addClass('missing').focusout(function() {
+        $(this).removeClass('missing')
+      });
+      e.focus();
+      return false;
+    }
+    return true;
+  });
 });
Index: admin/js/common.js
===================================================================
--- admin/js/common.js	(revision 3648)
+++ admin/js/common.js	(revision 3685)
@@ -3,659 +3,574 @@
 // set base font-size of body (62.5% default, usually : 50% to 75%)
 if (typeof dotclear_htmlFontSize !== 'undefined') {
-	document.documentElement.style.setProperty('--html-font-size',dotclear_htmlFontSize);
+  document.documentElement.style.setProperty('--html-font-size', dotclear_htmlFontSize);
 }
-
 /* ChainHandler, py Peter van der Beken
 -------------------------------------------------------- */
 function chainHandler(obj, handlerName, handler) {
-	obj[handlerName] = (function(existingFunction) {
-		return function() {
-			handler.apply(this, arguments);
-			if (existingFunction)
-				existingFunction.apply(this, arguments);
-		};
-	})(handlerName in obj ? obj[handlerName] : null);
-};
-
+  obj[handlerName] = (function(existingFunction) {
+    return function() {
+      handler.apply(this, arguments);
+      if (existingFunction) existingFunction.apply(this, arguments);
+    };
+  })(handlerName in obj ? obj[handlerName] : null);
+};
 /* jQuery extensions
 -------------------------------------------------------- */
 jQuery.fn.check = function() {
-	return this.each(function() {
-		if (this.checked != undefined) { this.checked = true; }
-	});
+  return this.each(function() {
+    if (this.checked != undefined) {
+      this.checked = true;
+    }
+  });
 };
 jQuery.fn.unCheck = function() {
-	return this.each(function() {
-		if (this.checked != undefined) { this.checked = false; }
-	});
+  return this.each(function() {
+    if (this.checked != undefined) {
+      this.checked = false;
+    }
+  });
 };
 jQuery.fn.setChecked = function(status) {
-	return this.each(function() {
-		if (this.checked != undefined) { this.checked = status; }
-	});
+  return this.each(function() {
+    if (this.checked != undefined) {
+      this.checked = status;
+    }
+  });
 };
 jQuery.fn.toggleCheck = function() {
-	return this.each(function() {
-		if (this.checked != undefined) { this.checked = !this.checked; }
-	});
-};
-
+  return this.each(function() {
+    if (this.checked != undefined) {
+      this.checked = !this.checked;
+    }
+  });
+};
 jQuery.fn.enableShiftClick = function() {
-	this.click(
-	function (event) {
-		if (event.shiftKey) {
-			if (dotclear.lastclicked != '') {
-				var range;
-				var trparent = $(this).parents('tr');
-				if (trparent.nextAll('#'+dotclear.lastclicked).length != 0)
-					range = trparent.nextUntil('#'+dotclear.lastclicked);
-				else
-					range = trparent.prevUntil('#'+dotclear.lastclicked);
-
-				range.find('input[type=checkbox]').setChecked(dotclear.lastclickedstatus);
-				this.checked = dotclear.lastclickedstatus;
-			}
-		} else {
-			dotclear.lastclicked = $(this).parents('tr')[0].id;
-			dotclear.lastclickedstatus = this.checked;
-		}
-		return true;
-	});
+  this.click(function(event) {
+    if (event.shiftKey) {
+      if (dotclear.lastclicked != '') {
+        var range;
+        var trparent = $(this).parents('tr');
+        if (trparent.nextAll('#' + dotclear.lastclicked).length != 0) range = trparent.nextUntil('#' + dotclear.lastclicked);
+        else range = trparent.prevUntil('#' + dotclear.lastclicked);
+        range.find('input[type=checkbox]').setChecked(dotclear.lastclickedstatus);
+        this.checked = dotclear.lastclickedstatus;
+      }
+    } else {
+      dotclear.lastclicked = $(this).parents('tr')[0].id;
+      dotclear.lastclickedstatus = this.checked;
+    }
+    return true;
+  });
 }
-
-jQuery.fn.toggleWithLegend = function(target,s) {
-	var defaults = {
-		img_on_src: dotclear.img_plus_src,
-		img_on_alt: dotclear.img_plus_alt,
-		img_off_src: dotclear.img_minus_src,
-		img_off_alt: dotclear.img_minus_alt,
-		unfolded_sections: dotclear.unfolded_sections,
-		hide: true,
-		speed: 0,
-		legend_click: false,
-		fn: false, // A function called on first display,
-		user_pref: false,
-		reverse_user_pref: false // Reverse cookie behavior
-	};
-	var p = jQuery.extend(defaults,s);
-
-	if (!target) { return this; }
-
-	var set_cookie = p.hide ^ p.reverse_cookie;
-	if (p.cookie && jQuery.cookie(p.cookie)) {
-		p.hide = p.reverse_cookie;
-	}
-
-	var set_user_pref = p.hide ^ p.reverse_user_pref;
-	if (p.user_pref && p.unfolded_sections !== undefined && (p.user_pref in p.unfolded_sections)) {
-		p.hide = p.reverse_user_pref;
-	}
-	var toggle = function(i,speed) {
-		speed = speed || 0;
-		if (p.hide) {
-			$(i).get(0).src = p.img_on_src;
-			$(i).get(0).alt = p.img_on_alt;
-			target.addClass('hide');
-		} else {
-			$(i).get(0).src = p.img_off_src;
-			$(i).get(0).alt = p.img_off_alt;
-			target.removeClass('hide');
-			if (p.fn) {
-				p.fn.apply(target);
-				p.fn = false;
-			}
-		}
-
-		if (p.cookie && set_cookie) {
-			if (p.hide ^ p.reverse_cookie) {
-				jQuery.cookie(p.cookie,'',{expires: -1});
-			} else {
-				jQuery.cookie(p.cookie,1,{expires: 30});
-			}
-		}
-		p.hide = !p.hide;
-	};
-
-	return this.each(function() {
-		var i = document.createElement('img');
-		i.src = p.img_off_src;
-		i.alt = p.img_off_alt;
-		var a = document.createElement('a');
-		a.href= '#';
-		$(a).append(i);
-		$(a).css({
-			border: 'none',
-			outline: 'none'
-		});
-
-		var ctarget = p.legend_click ? this : a;
-
-		$(ctarget).css('cursor','pointer');
-		if (p.legend_click) {
-			$(ctarget).find('label').css('cursor','pointer');
-		}
-		$(ctarget).click(function() {
-			if (p.user_pref && set_user_pref) {
-				if (p.hide ^ p.reverse_user_pref) {
-					jQuery.post('services.php',
-						{'f':'setSectionFold','section':p.user_pref,'value':1,xd_check: dotclear.nonce},
-						function(data) {});
-				} else {
-					jQuery.post('services.php',
-						{'f':'setSectionFold','section':p.user_pref,'value':0,xd_check: dotclear.nonce},
-						function(data) {});
-				}
-				jQuery.cookie(p.user_pref,'',{expires: -1});
-			}
-			toggle(i,p.speed);
-			return false;
-		});
-
-
-		toggle($(i).get(0));
-		$(this).prepend(' ').prepend(a);
-	});
-};
-
+jQuery.fn.toggleWithLegend = function(target, s) {
+  var defaults = {
+    img_on_src: dotclear.img_plus_src,
+    img_on_alt: dotclear.img_plus_alt,
+    img_off_src: dotclear.img_minus_src,
+    img_off_alt: dotclear.img_minus_alt,
+    unfolded_sections: dotclear.unfolded_sections,
+    hide: true,
+    speed: 0,
+    legend_click: false,
+    fn: false, // A function called on first display,
+    user_pref: false,
+    reverse_user_pref: false // Reverse cookie behavior
+  };
+  var p = jQuery.extend(defaults, s);
+  if (!target) {
+    return this;
+  }
+  var set_cookie = p.hide ^ p.reverse_cookie;
+  if (p.cookie && jQuery.cookie(p.cookie)) {
+    p.hide = p.reverse_cookie;
+  }
+  var set_user_pref = p.hide ^ p.reverse_user_pref;
+  if (p.user_pref && p.unfolded_sections !== undefined && (p.user_pref in p.unfolded_sections)) {
+    p.hide = p.reverse_user_pref;
+  }
+  var toggle = function(i, speed) {
+    speed = speed || 0;
+    if (p.hide) {
+      $(i).get(0).src = p.img_on_src;
+      $(i).get(0).alt = p.img_on_alt;
+      target.addClass('hide');
+    } else {
+      $(i).get(0).src = p.img_off_src;
+      $(i).get(0).alt = p.img_off_alt;
+      target.removeClass('hide');
+      if (p.fn) {
+        p.fn.apply(target);
+        p.fn = false;
+      }
+    }
+    if (p.cookie && set_cookie) {
+      if (p.hide ^ p.reverse_cookie) {
+        jQuery.cookie(p.cookie, '', {
+          expires: -1
+        });
+      } else {
+        jQuery.cookie(p.cookie, 1, {
+          expires: 30
+        });
+      }
+    }
+    p.hide = !p.hide;
+  };
+  return this.each(function() {
+    var i = document.createElement('img');
+    i.src = p.img_off_src;
+    i.alt = p.img_off_alt;
+    var a = document.createElement('a');
+    a.href = '#';
+    $(a).append(i);
+    $(a).css({
+      border: 'none',
+      outline: 'none'
+    });
+    var ctarget = p.legend_click ? this : a;
+    $(ctarget).css('cursor', 'pointer');
+    if (p.legend_click) {
+      $(ctarget).find('label').css('cursor', 'pointer');
+    }
+    $(ctarget).click(function() {
+      if (p.user_pref && set_user_pref) {
+        if (p.hide ^ p.reverse_user_pref) {
+          jQuery.post('services.php', {
+            'f': 'setSectionFold',
+            'section': p.user_pref,
+            'value': 1,
+            xd_check: dotclear.nonce
+          }, function(data) {});
+        } else {
+          jQuery.post('services.php', {
+            'f': 'setSectionFold',
+            'section': p.user_pref,
+            'value': 0,
+            xd_check: dotclear.nonce
+          }, function(data) {});
+        }
+        jQuery.cookie(p.user_pref, '', {
+          expires: -1
+        });
+      }
+      toggle(i, p.speed);
+      return false;
+    });
+    toggle($(i).get(0));
+    $(this).prepend(' ').prepend(a);
+  });
+};
 (function($) {
-	'use strict';
-
-	$.expandContent = function(opts) {
-		var defaults = {};
-		$.expandContent.options = $.extend({},defaults,opts);
-
-		if (opts==undefined || opts.callback==undefined || !$.isFunction(opts.callback)) {
-			return;
-		}
-		if (opts.line!=undefined) {
-			multipleExpander(opts.line,opts.lines);
-		}
-		opts.lines.each(function() {
-			singleExpander(this);
-		});
-	}
-
-	var singleExpander = function singleExpander(line) {
-		$('<input type="image" src="'+dotclear.img_plus_src+'" alt="'+dotclear.img_plus_alt+'"/>')
-			.click(function(e) {
-				toggleArrow(this);
-				$.expandContent.options.callback.call(this,line);
-				e.preventDefault();
-			})
-			.prependTo($(line).children().get(0)); // first td
-	};
-
-	var multipleExpander = function multipleExpander(line,lines) {
-		$('<input type="image" src="'+dotclear.img_plus_src+'" alt="'+dotclear.img_plus_alt+'"/>')
-			.click(function(e) {
-				var that = this;
-				var action = toggleArrow(this);
-				lines.each(function() {
-					toggleArrow(this.firstChild.firstChild,action);
-					$.expandContent.options.callback.call(that,this,action);
-
-				});
-				e.preventDefault();
-			})
-			.prependTo($(line).children().get(0)); // first td
-	};
-
-	var toggleArrow = function toggleArrow(button,action) {
-		action = action || '';
-		if (action=='') {
-			if (button.alt==dotclear.img_plus_alt) {
-				action = 'open';
-			} else {
-				action = 'close';
-			}
-		}
-
-		if (action=='open') {
-			button.src = dotclear.img_minus_src;
-			button.alt = dotclear.img_minus_alt;
-		} else {
-			button.src = dotclear.img_plus_src;
-			button.alt = dotclear.img_plus_alt;
-		}
-
-		return action;
-	}
+  'use strict';
+  $.expandContent = function(opts) {
+    var defaults = {};
+    $.expandContent.options = $.extend({}, defaults, opts);
+    if (opts == undefined || opts.callback == undefined || !$.isFunction(opts.callback)) {
+      return;
+    }
+    if (opts.line != undefined) {
+      multipleExpander(opts.line, opts.lines);
+    }
+    opts.lines.each(function() {
+      singleExpander(this);
+    });
+  }
+  var singleExpander = function singleExpander(line) {
+    $('<input type="image" src="' + dotclear.img_plus_src + '" alt="' + dotclear.img_plus_alt + '"/>').click(function(e) {
+      toggleArrow(this);
+      $.expandContent.options.callback.call(this, line);
+      e.preventDefault();
+    }).prependTo($(line).children().get(0)); // first td
+  };
+  var multipleExpander = function multipleExpander(line, lines) {
+    $('<input type="image" src="' + dotclear.img_plus_src + '" alt="' + dotclear.img_plus_alt + '"/>').click(function(e) {
+      var that = this;
+      var action = toggleArrow(this);
+      lines.each(function() {
+        toggleArrow(this.firstChild.firstChild, action);
+        $.expandContent.options.callback.call(that, this, action);
+      });
+      e.preventDefault();
+    }).prependTo($(line).children().get(0)); // first td
+  };
+  var toggleArrow = function toggleArrow(button, action) {
+    action = action || '';
+    if (action == '') {
+      if (button.alt == dotclear.img_plus_alt) {
+        action = 'open';
+      } else {
+        action = 'close';
+      }
+    }
+    if (action == 'open') {
+      button.src = dotclear.img_minus_src;
+      button.alt = dotclear.img_minus_alt;
+    } else {
+      button.src = dotclear.img_plus_src;
+      button.alt = dotclear.img_plus_alt;
+    }
+    return action;
+  }
 })(jQuery);
-
 jQuery.fn.helpViewer = function() {
-	if (this.length < 1) {
-		return this;
-	}
-
-	var p = {
-		img_on_src: dotclear.img_plus_src,
-		img_on_alt: dotclear.img_plus_alt,
-		img_off_src: dotclear.img_minus_src,
-		img_off_alt: dotclear.img_minus_alt
-	};
-	var This = this;
-	var toggle = function() {
-		$('#content').toggleClass('with-help');
-		if (document.all) {
-			if ($('#content').hasClass('with-help')) {
-				select = $('#content select:visible').hide();
-			} else {
-				select.show();
-			}
-		}
-		$('p#help-button span a').text($('#content').hasClass('with-help') ? dotclear.msg.help_hide : dotclear.msg.help);
-		sizeBox();
-		return false;
-	};
-
-	var sizeBox = function() {
-		This.css('height','auto');
-		if ($('#wrapper').height() > This.height()) {
-			This.css('height',$('#wrapper').height() + 'px');
-		}
-	};
-
-	var textToggler = function(o) {
-		var i = $('<img src="'+p.img_on_src+'" alt="'+p.img_on_alt+'" />');
-		o.css('cursor','pointer');
-		var hide = true;
-
-		o.prepend(' ').prepend(i);
-		o.click(function() {
-			$(this).nextAll().each(function() {
-				if ($(this).is('h4')) {
-					return false;
-				}
-				$(this).toggle();
-				sizeBox();
-				return true;
-			});
-			hide = !hide;
-			var img = $(this).find('img');
-			if (!hide) {
-				img.attr('src',p.img_off_src);
-			} else {
-				img.attr('src',p.img_on_src);
-			}
-		});
-	};
-
-	this.addClass('help-box');
-	this.find('>hr').remove();
-
-	this.find('h4').each(function() { textToggler($(this)); });
-	this.find('h4:first').nextAll('*:not(h4)').hide();
-	sizeBox();
-
-	var img = $('<p id="help-button"><span><a href="">'+dotclear.msg.help+'</a></span></p>');
-	var select = $();
-	img.click(function() { return toggle(); });
-
-	$('#content').append(img);
-
-	// listen for scroll
-	var peInPage = $('#help-button').offset().top;
-	$('#help-button').addClass("floatable");
-	var peInFloat = $('#help-button').offset().top - $(window).scrollTop();
-	$('#help-button').removeClass("floatable");
-	$(window).scroll(
-		function() {
-			if ($(window).scrollTop() >= peInPage - peInFloat ) {
-				$('#help-button').addClass("floatable");
-			} else {
-				$('#help-button').removeClass("floatable");
-			}
-		}
-	);
-
-	return this;
-};
-
-
+  if (this.length < 1) {
+    return this;
+  }
+  var p = {
+    img_on_src: dotclear.img_plus_src,
+    img_on_alt: dotclear.img_plus_alt,
+    img_off_src: dotclear.img_minus_src,
+    img_off_alt: dotclear.img_minus_alt
+  };
+  var This = this;
+  var toggle = function() {
+    $('#content').toggleClass('with-help');
+    if (document.all) {
+      if ($('#content').hasClass('with-help')) {
+        select = $('#content select:visible').hide();
+      } else {
+        select.show();
+      }
+    }
+    $('p#help-button span a').text($('#content').hasClass('with-help') ? dotclear.msg.help_hide : dotclear.msg.help);
+    sizeBox();
+    return false;
+  };
+  var sizeBox = function() {
+    This.css('height', 'auto');
+    if ($('#wrapper').height() > This.height()) {
+      This.css('height', $('#wrapper').height() + 'px');
+    }
+  };
+  var textToggler = function(o) {
+    var i = $('<img src="' + p.img_on_src + '" alt="' + p.img_on_alt + '" />');
+    o.css('cursor', 'pointer');
+    var hide = true;
+    o.prepend(' ').prepend(i);
+    o.click(function() {
+      $(this).nextAll().each(function() {
+        if ($(this).is('h4')) {
+          return false;
+        }
+        $(this).toggle();
+        sizeBox();
+        return true;
+      });
+      hide = !hide;
+      var img = $(this).find('img');
+      if (!hide) {
+        img.attr('src', p.img_off_src);
+      } else {
+        img.attr('src', p.img_on_src);
+      }
+    });
+  };
+  this.addClass('help-box');
+  this.find('>hr').remove();
+  this.find('h4').each(function() {
+    textToggler($(this));
+  });
+  this.find('h4:first').nextAll('*:not(h4)').hide();
+  sizeBox();
+  var img = $('<p id="help-button"><span><a href="">' + dotclear.msg.help + '</a></span></p>');
+  var select = $();
+  img.click(function() {
+    return toggle();
+  });
+  $('#content').append(img);
+  // listen for scroll
+  var peInPage = $('#help-button').offset().top;
+  $('#help-button').addClass("floatable");
+  var peInFloat = $('#help-button').offset().top - $(window).scrollTop();
+  $('#help-button').removeClass("floatable");
+  $(window).scroll(function() {
+    if ($(window).scrollTop() >= peInPage - peInFloat) {
+      $('#help-button').addClass("floatable");
+    } else {
+      $('#help-button').removeClass("floatable");
+    }
+  });
+  return this;
+};
 /* Dotclear common object
 -------------------------------------------------------- */
 var dotclear = {
-	msg: {},
-
-	condSubmit: function(chkboxes,target) {
-		var checkboxes = $(chkboxes),
-		    submitButt = $(target);
-
-		if (checkboxes === undefined || submitButt === undefined) {
-			return;
-		}
-
-		// Set initial state
-	    submitButt.attr("disabled", !checkboxes.is(":checked"));
-	    if (!checkboxes.is(":checked")) {
-	    	submitButt.addClass('disabled');
-	    } else {
-	    	submitButt.removeClass('disabled');
-	    }
-
-		checkboxes.click(function() {
-			// Update target state
-		    submitButt.attr("disabled", !checkboxes.is(":checked"));
-		    if (!checkboxes.is(":checked")) {
-		    	submitButt.addClass('disabled');
-		    } else {
-		    	submitButt.removeClass('disabled');
-		    }
-		});
-	},
-
-	hideLockable: function() {
-		$('div.lockable').each(function() {
-			var current_lockable_div = this;
-			$(this).find('p.form-note').hide();
-			$(this).find('input').each(function() {
-				this.disabled = true;
-				$(this).width(($(this).width()-14) + 'px');
-
-				var imgE = document.createElement('img');
-				imgE.src = 'images/locker.png';
-				imgE.style.position = 'absolute';
-				imgE.style.top = '1.8em';
-				imgE.style.left = ($(this).width()+14)+'px';
-				imgE.alt=dotclear.msg.click_to_unlock;
-				$(imgE).css('cursor','pointer');
-
-				$(imgE).click(function() {
-					$(this).hide();
-					$(this).prev('input').each(function() {
-						this.disabled = false;
-						$(this).width(($(this).width()+14) + 'px');
-					});
-					$(current_lockable_div).find('p.form-note').show();
-				});
-
-				$(this).parent().css('position','relative');
-				$(this).after(imgE);
-			});
-		});
-	},
-
-	checkboxesHelpers: function(e, target, c, s) {
-		$(e).append(document.createTextNode(dotclear.msg.to_select));
-		$(e).append(document.createTextNode(' '));
-
-		$('<button type="button" class="checkbox-helper select-all">'+dotclear.msg.select_all+'</button>').click(function() {
-			if (target !== undefined) {
-				target.check();
-			} else {
-				$(e).parents('form').find('input[type="checkbox"]').check();
-			}
-			if (c !== undefined && s !== undefined) {
-				dotclear.condSubmit(c,s);
-			}
-			return false;
-		}).appendTo($(e));
-		$(e).append(document.createTextNode(' '));
-
-		$('<button type="button" class="checkbox-helper select-none">'+dotclear.msg.no_selection+'</button>').click(function() {
-			if (target !== undefined) {
-				target.unCheck();
-			} else {
-				$(e).parents('form').find('input[type="checkbox"]').unCheck();
-			}
-			if (c !== undefined && s !== undefined) {
-				dotclear.condSubmit(c,s);
-			}
-			return false;
-		}).appendTo($(e));
-		$(e).append(document.createTextNode(' '));
-
-		$('<button type="button" class="checkbox-helper select-reverse">'+dotclear.msg.invert_sel+'</button>').click(function() {
-			if (target !== undefined) {
-				target.toggleCheck();
-			} else {
-				$(e).parents('form').find('input[type="checkbox"]').toggleCheck();
-			}
-			if (c !== undefined && s !== undefined) {
-				dotclear.condSubmit(c,s);
-			}
-			return false;
-		}).appendTo($(e));
-	},
-
-	postsActionsHelper: function() {
-		$('#form-entries').submit(function() {
-			var action = $(this).find('select[name="action"]').val();
-			if (action===undefined) {
-				return;
-			}
-			var checked = false;
-
-			$(this).find('input[name="entries[]"]').each(function() {
-				if (this.checked) {
-					checked = true;
-				}
-			});
-
-			if (!checked) { return false; }
-
-			if (action == 'delete') {
-				return window.confirm(dotclear.msg.confirm_delete_posts.replace('%s',$('input[name="entries[]"]:checked').size()));
-			}
-
-			return true;
-		});
-	},
-
-	commentsActionsHelper: function() {
-		$('#form-comments').submit(function() {
-			var action = $(this).find('select[name="action"]').val();
-			var checked = false;
-
-			$(this).find('input[name="comments[]"]').each(function() {
-				if (this.checked) {
-					checked = true;
-				}
-			});
-
-			if (!checked) { return false; }
-
-			if (action == 'delete') {
-				return window.confirm(dotclear.msg.confirm_delete_comments.replace('%s',$('input[name="comments[]"]:checked').size()));
-			}
-
-			return true;
-		});
-	},
-	getCSSColor : function ( clazz) {
-		$('<div class="'+clazz+'" id="dotclear-obj-test-color" style="display:none"></div>').appendTo(document.body);
-		var tag2 = $('#dotclear-obj-test-color');
-		var color = $.trim(tag2.css("color").toLowerCase());
-		tag2.remove();
-		if ( color.charAt(0) === '#') {
-			return color;
-		}
-		var result = /^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\)$/.exec(color);
-		if ( result === null) {
-			return '';
-		}
-		var ret = '#';
-		for ( var i = 1; i < 4; i++) {
-			var val = parseInt(result[i],10);
-			ret += (val < 16 ? '0'+val.toString(16) : val.toString(16));
-		}
-		return ret;
-	},
-	initFadeColor : function() {
-		dotclear.fadeColor = {
-			beginPassword : dotclear.getCSSColor('colorBeginPassword'),
-			endPassword : dotclear.getCSSColor('colorEndPassword'),
-			beginMessage : dotclear.getCSSColor('colorBeginMessage'),
-			endMessage : dotclear.getCSSColor('colorEndMessage'),
-			beginError : dotclear.getCSSColor('colorBeginError'),
-			endError : dotclear.getCSSColor('colorEndError'),
-			beginSuccess : dotclear.getCSSColor('colorBeginSuccess'),
-			endSuccess : dotclear.getCSSColor('colorEndSuccess'),
-			beginValidatorMsg : dotclear.getCSSColor('colorBeginValidatorMsg'),
-			endValidatorMsg : dotclear.getCSSColor('colorEndValidatorMsg'),
-			beginValidatorErr : dotclear.getCSSColor('colorBeginValidatorErr'),
-			endValidatorErr : dotclear.getCSSColor('colorEndValidatorErr'),
-			beginUserMail : dotclear.getCSSColor('colorBeginUserMail'),
-			endUserMail : dotclear.getCSSColor('colorEndUserMail')
-		};
-	}};
-
+  msg: {},
+  condSubmit: function(chkboxes, target) {
+    var checkboxes = $(chkboxes),
+      submitButt = $(target);
+    if (checkboxes === undefined || submitButt === undefined) {
+      return;
+    }
+    // Set initial state
+    submitButt.attr("disabled", !checkboxes.is(":checked"));
+    if (!checkboxes.is(":checked")) {
+      submitButt.addClass('disabled');
+    } else {
+      submitButt.removeClass('disabled');
+    }
+    checkboxes.click(function() {
+      // Update target state
+      submitButt.attr("disabled", !checkboxes.is(":checked"));
+      if (!checkboxes.is(":checked")) {
+        submitButt.addClass('disabled');
+      } else {
+        submitButt.removeClass('disabled');
+      }
+    });
+  },
+  hideLockable: function() {
+    $('div.lockable').each(function() {
+      var current_lockable_div = this;
+      $(this).find('p.form-note').hide();
+      $(this).find('input').each(function() {
+        this.disabled = true;
+        $(this).width(($(this).width() - 14) + 'px');
+        var imgE = document.createElement('img');
+        imgE.src = 'images/locker.png';
+        imgE.style.position = 'absolute';
+        imgE.style.top = '1.8em';
+        imgE.style.left = ($(this).width() + 14) + 'px';
+        imgE.alt = dotclear.msg.click_to_unlock;
+        $(imgE).css('cursor', 'pointer');
+        $(imgE).click(function() {
+          $(this).hide();
+          $(this).prev('input').each(function() {
+            this.disabled = false;
+            $(this).width(($(this).width() + 14) + 'px');
+          });
+          $(current_lockable_div).find('p.form-note').show();
+        });
+        $(this).parent().css('position', 'relative');
+        $(this).after(imgE);
+      });
+    });
+  },
+  checkboxesHelpers: function(e, target, c, s) {
+    $(e).append(document.createTextNode(dotclear.msg.to_select));
+    $(e).append(document.createTextNode(' '));
+    $('<button type="button" class="checkbox-helper select-all">' + dotclear.msg.select_all + '</button>').click(function() {
+      if (target !== undefined) {
+        target.check();
+      } else {
+        $(e).parents('form').find('input[type="checkbox"]').check();
+      }
+      if (c !== undefined && s !== undefined) {
+        dotclear.condSubmit(c, s);
+      }
+      return false;
+    }).appendTo($(e));
+    $(e).append(document.createTextNode(' '));
+    $('<button type="button" class="checkbox-helper select-none">' + dotclear.msg.no_selection + '</button>').click(function() {
+      if (target !== undefined) {
+        target.unCheck();
+      } else {
+        $(e).parents('form').find('input[type="checkbox"]').unCheck();
+      }
+      if (c !== undefined && s !== undefined) {
+        dotclear.condSubmit(c, s);
+      }
+      return false;
+    }).appendTo($(e));
+    $(e).append(document.createTextNode(' '));
+    $('<button type="button" class="checkbox-helper select-reverse">' + dotclear.msg.invert_sel + '</button>').click(function() {
+      if (target !== undefined) {
+        target.toggleCheck();
+      } else {
+        $(e).parents('form').find('input[type="checkbox"]').toggleCheck();
+      }
+      if (c !== undefined && s !== undefined) {
+        dotclear.condSubmit(c, s);
+      }
+      return false;
+    }).appendTo($(e));
+  },
+  postsActionsHelper: function() {
+    $('#form-entries').submit(function() {
+      var action = $(this).find('select[name="action"]').val();
+      if (action === undefined) {
+        return;
+      }
+      var checked = false;
+      $(this).find('input[name="entries[]"]').each(function() {
+        if (this.checked) {
+          checked = true;
+        }
+      });
+      if (!checked) {
+        return false;
+      }
+      if (action == 'delete') {
+        return window.confirm(dotclear.msg.confirm_delete_posts.replace('%s', $('input[name="entries[]"]:checked').size()));
+      }
+      return true;
+    });
+  },
+  commentsActionsHelper: function() {
+    $('#form-comments').submit(function() {
+      var action = $(this).find('select[name="action"]').val();
+      var checked = false;
+      $(this).find('input[name="comments[]"]').each(function() {
+        if (this.checked) {
+          checked = true;
+        }
+      });
+      if (!checked) {
+        return false;
+      }
+      if (action == 'delete') {
+        return window.confirm(dotclear.msg.confirm_delete_comments.replace('%s', $('input[name="comments[]"]:checked').size()));
+      }
+      return true;
+    });
+  }
+};
 /* On document ready
 -------------------------------------------------------- */
 $(function() {
-	dotclear.initFadeColor();
-	// remove class no-js from html tag; cf style/default.css for examples
-	$('body').removeClass('no-js').addClass('with-js');
+  // remove class no-js from html tag; cf style/default.css for examples
+  $('body').removeClass('no-js').addClass('with-js');
+  $('body').contents().each(function() {
+    if (this.nodeType == 8) {
+      var data = this.data;
+      data = data.replace(/ /g, '&nbsp;').replace(/\n/g, '<br/>');
+      $('<span class="tooltip">' + $('#footer a').prop('title') + data + '</span>').appendTo('#footer a');
+    }
+  });
+  // manage outgoing links
+  $('a').filter(function() {
+    return ((this.hostname && this.hostname != location.hostname && !$(this).hasClass('modal') && !$(this).hasClass('modal-image')) || $(this).hasClass('outgoing'));
+  }).each(function() {
+    $(this).prop('title', $(this).prop('title') + ' (' + dotclear.msg.new_window + ')');
+    if (!$(this).hasClass('outgoing')) {
+      $(this).append('&nbsp;<img src="images/outgoing-blue.png" alt=""/>');
+    }
+  }).click(function(e) {
+    e.preventDefault();
+    window.open($(this).attr('href'));
+  });
+  // Blog switcher
+  $('#switchblog').change(function() {
+    this.form.submit();
+  });
+  var menu_settings = {
+    img_on_src: dotclear.img_menu_off,
+    img_off_src: dotclear.img_menu_on,
+    legend_click: true,
+    speed: 100
+  }
+  $('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'), $.extend({
+    user_pref: 'dc_blog_menu'
+  }, menu_settings));
+  $('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'), $.extend({
+    user_pref: 'dc_system_menu'
+  }, menu_settings));
+  $('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'), $.extend({
+    user_pref: 'dc_plugins_menu'
+  }, menu_settings));
+  $('#favorites-menu h3:first').toggleWithLegend($('#favorites-menu ul:first'), $.extend({
+    user_pref: 'dc_favorites_menu',
+    hide: false,
+    reverse_user_pref: true
+  }, menu_settings));
+  $('#help').helpViewer();
+  // Notices
+  $('p.success,p.warning,p.error,div.error').each(function() {
+    $(this).addClass('close-notice-parent');
+    $(this).append('<button class="close-notice" type="button"><img src="images/close.png" alt="' + dotclear.msg.close_notice + '" /></button>');
+  });
+  $('button.close-notice').click(function(e) {
+    e.preventDefault();
+    $(this).parent().hide();
+  });
+  // Password
+  $('form:has(input[type=password][name=your_pwd])').submit(function() {
+    var e = this.elements['your_pwd'];
+    if (e.value == '') {
+      $(e).addClass('missing').focusout(function() {
+        $(this).removeClass('missing')
+      });
+      e.focus();
+      return false;
+    }
+    return true;
+  });
+  // Cope with ellipsis'ed cells
+  $('table .maximal').each(function() {
+    if (this.offsetWidth < this.scrollWidth) {
+      if (this.title == '') {
+        this.title = this.innerText;
+        $(this).addClass('ellipsis');
+      }
+    }
+  });
+  $('table .maximal.ellipsis a').each(function() {
+    if (this.title == '') {
+      this.title = this.innerText;
+    }
+  })
+  // Advanced users
+  if (dotclear.hideMoreInfo) {
+    $('.more-info,.form-note:not(.warn,.warning,.info)').addClass('no-more-info');
+  }
+  // Ajax loader activity indicator
+  if (dotclear.showAjaxLoader) {
+    $(document).ajaxStart(function() {
+      $('body').addClass('ajax-loader');
+      $('div.ajax-loader').show();
+    });
+    $(document).ajaxStop(function() {
+      $('body').removeClass('ajax-loader');
+      $('div.ajax-loader').hide();
+    });
+  }
+  // Main menu collapser
+  var objMain = $('#wrapper');
 
-	$('body').contents().each(function() {
-		if (this.nodeType==8) {
-			var data = this.data;
-			data = data.replace(/ /g,'&nbsp;').replace(/\n/g,'<br/>');
-			$('<span class="tooltip">'+$('#footer a').prop('title')+data+'</span>').appendTo('#footer a');
-		}
-	});
+  function showSidebar() {
+    // Show sidebar
+    objMain.removeClass('hide-mm');
+    $.cookie('sidebar-pref', null, {
+      expires: 30
+    });
+  }
 
-	// manage outgoing links
-	$('a').filter(function() {
-		return ((this.hostname && this.hostname!=location.hostname
-				&& !$(this).hasClass('modal') && !$(this).hasClass('modal-image'))
-			|| $(this).hasClass('outgoing'));
-	}).each(function() {
-		$(this).prop('title',$(this).prop('title')+' ('+dotclear.msg.new_window+')');
-		if (!$(this).hasClass('outgoing')) {
-			$(this).append('&nbsp;<img src="images/outgoing-blue.png" alt=""/>');
-		}
-	}).click(function(e) {
-		e.preventDefault();
-		window.open($(this).attr('href'));
-	});
-
-	// Blog switcher
-	$('#switchblog').change(function() {
-		this.form.submit();
-	});
-
-	var menu_settings = {
-		img_on_src: dotclear.img_menu_off,
-		img_off_src: dotclear.img_menu_on,
-		legend_click: true,
-		speed: 100
-	}
-	$('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'),
-		$.extend({user_pref:'dc_blog_menu'},menu_settings)
-	);
-	$('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'),
-		$.extend({user_pref:'dc_system_menu'},menu_settings)
-	);
-	$('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'),
-		$.extend({user_pref:'dc_plugins_menu'},menu_settings)
-	);
-	$('#favorites-menu h3:first').toggleWithLegend($('#favorites-menu ul:first'),
-		$.extend({user_pref:'dc_favorites_menu',hide:false,reverse_user_pref:true},menu_settings)
-	);
-
-	$('#help').helpViewer();
-
-	// Notices
-	$('.message').backgroundFade({sColor: dotclear.fadeColor.beginMessage, eColor: dotclear.fadeColor.endMessage, steps:20});
-	$('.error').backgroundFade({sColor: dotclear.fadeColor.beginError, eColor: dotclear.fadeColor.endError, steps:20});
-	$('.success').backgroundFade({sColor: dotclear.fadeColor.beginSuccess, eColor: dotclear.fadeColor.endSuccess, steps:20});
-
-	$('p.success,p.warning,p.error,div.error').each(function () {
-		$(this).addClass('close-notice-parent');
-		$(this).append('<button class="close-notice" type="button"><img src="images/close.png" alt="'+dotclear.msg.close_notice+'" /></button>');
-	});
-	$('button.close-notice').click(function(e) {
-		e.preventDefault();
-		$(this).parent().hide();
-	});
-
-	// Password
-	$('form:has(input[type=password][name=your_pwd])').submit(function() {
-		var e = this.elements['your_pwd'];
-		if (e.value == '') {
-			e.focus();
-			$(e).backgroundFade({sColor: dotclear.fadeColor.beginPassword,eColor: dotclear.fadeColor.endPassword,steps:50},function() {
-				$(this).backgroundFade({sColor: dotclear.fadeColor.endPassword,eColor: dotclear.fadeColor.beginPassword});
-			});
-			return false;
-		}
-		return true;
-	});
-
-	// Cope with ellipsis'ed cells
-	$('table .maximal').each(function() {
-		if (this.offsetWidth < this.scrollWidth) {
-			if (this.title == '') {
-				this.title = this.innerText;
-				$(this).addClass('ellipsis');
-			}
-		}
-	});
-	$('table .maximal.ellipsis a').each(function() {
-		if (this.title == '') {
-			this.title = this.innerText;
-		}
-	})
-
-	// Advanced users
-	if (dotclear.hideMoreInfo) {
-		$('.more-info,.form-note:not(.warn,.warning,.info)').addClass('no-more-info');
-	}
-
-	// Ajax loader activity indicator
-	if (dotclear.showAjaxLoader) {
-		$(document).ajaxStart(function() {
-			$('body').addClass('ajax-loader');
-			$('div.ajax-loader').show();
-		});
-		$(document).ajaxStop(function() {
-			$('body').removeClass('ajax-loader');
-			$('div.ajax-loader').hide();
-		});
-	}
-
-	// Main menu collapser
-    var objMain = $('#wrapper');
-    function showSidebar(){
-	    // Show sidebar
-        objMain.removeClass('hide-mm');
-        $.cookie('sidebar-pref',null,{expires:30});
-    }
-    function hideSidebar(){
-	    // Hide sidebar
-        objMain.addClass('hide-mm');
-        $.cookie('sidebar-pref','hide-mm',{expires:30});
-    }
-    // Sidebar separator
-    var objSeparator = $('#collapser');
-    objSeparator.click(function(e){
-        e.preventDefault();
-        if ( objMain.hasClass('hide-mm') ){
-            showSidebar();
-	        $('#main-menu input#qx').focus();
-        }
-        else {
-            hideSidebar();
-            $('#content a.go_home').focus();
-        }
-    });
-	if ( $.cookie('sidebar-pref') == 'hide-mm' ){
-		objMain.addClass('hide-mm');
-	} else {
-		objMain.removeClass('hide-mm');
-	}
-    // totop scroll
-    $(window).scroll(function() {
-            if($(this).scrollTop() != 0) {
-                $('#gototop').fadeIn();
-            } else {
-                $('#gototop').fadeOut();
-            }
-        });
-
-        $('#gototop').click(function(e) {
-            $('body,html').animate({scrollTop:0},800);
-            e.preventDefault();
-        });
+  function hideSidebar() {
+    // Hide sidebar
+    objMain.addClass('hide-mm');
+    $.cookie('sidebar-pref', 'hide-mm', {
+      expires: 30
+    });
+  }
+  // Sidebar separator
+  var objSeparator = $('#collapser');
+  objSeparator.click(function(e) {
+    e.preventDefault();
+    if (objMain.hasClass('hide-mm')) {
+      showSidebar();
+      $('#main-menu input#qx').focus();
+    } else {
+      hideSidebar();
+      $('#content a.go_home').focus();
+    }
+  });
+  if ($.cookie('sidebar-pref') == 'hide-mm') {
+    objMain.addClass('hide-mm');
+  } else {
+    objMain.removeClass('hide-mm');
+  }
+  // totop scroll
+  $(window).scroll(function() {
+    if ($(this).scrollTop() != 0) {
+      $('#gototop').fadeIn();
+    } else {
+      $('#gototop').fadeOut();
+    }
+  });
+  $('#gototop').click(function(e) {
+    $('body,html').animate({
+      scrollTop: 0
+    }, 800);
+    e.preventDefault();
+  });
 });
Index: admin/js/jquery/jquery-migrate.js
===================================================================
--- admin/js/jquery/jquery-migrate.js	(revision 3178)
+++ admin/js/jquery/jquery-migrate.js	(revision 3684)
@@ -1,4 +1,4 @@
 /*!
- * jQuery Migrate - v1.3.0 - 2016-01-13
+ * jQuery Migrate - v1.4.1 - 2016-05-19
  * Copyright jQuery Foundation and other contributors
  */
@@ -8,5 +8,5 @@
 
 
-jQuery.migrateVersion = "1.3.0";
+jQuery.migrateVersion = "1.4.1";
 
 
@@ -20,6 +20,8 @@
 
 // Show a message on the console so devs know we're active
-if ( !jQuery.migrateMute && window.console && window.console.log ) {
-	window.console.log("JQMIGRATE: Logging is active");
+if ( window.console && window.console.log ) {
+	window.console.log( "JQMIGRATE: Migrate is installed" +
+		( jQuery.migrateMute ? "" : " with logging active" ) +
+		", version " + jQuery.migrateVersion );
 }
 
@@ -192,6 +194,9 @@
 var matched, browser,
 	oldInit = jQuery.fn.init,
+	oldFind = jQuery.find,
 	oldParseJSON = jQuery.parseJSON,
 	rspaceAngle = /^\s*</,
+	rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
+	rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,
 	// Note: XSS check is done below after string is trimmed
 	rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
@@ -201,36 +206,35 @@
 	var match, ret;
 
-	if ( selector && typeof selector === "string" && !jQuery.isPlainObject( context ) &&
-			(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
-		// This is an HTML string according to the "old" rules; is it still?
-		if ( !rspaceAngle.test( selector ) ) {
-			migrateWarn("$(html) HTML strings must start with '<' character");
-		}
-		if ( match[ 3 ] ) {
-			migrateWarn("$(html) HTML text after last tag is ignored");
-		}
-
-		// Consistently reject any HTML-like string starting with a hash (#9521)
-		// Note that this may break jQuery 1.6.x code that otherwise would work.
-		if ( match[ 0 ].charAt( 0 ) === "#" ) {
-			migrateWarn("HTML string cannot start with a '#' character");
-			jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
-		}
-		// Now process using loose rules; let pre-1.8 play too
-		if ( context && context.context ) {
-			// jQuery object as context; parseHTML expects a DOM object
-			context = context.context;
-		}
-		if ( jQuery.parseHTML ) {
-			return oldInit.call( this,
-					jQuery.parseHTML( match[ 2 ], context && context.ownerDocument ||
-						context || document, true ), context, rootjQuery );
-		}
-	}
-
-	// jQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
-	if ( selector === "#" ) {
-		migrateWarn( "jQuery( '#' ) is not a valid selector" );
-		selector = [];
+	if ( selector && typeof selector === "string" ) {
+		if ( !jQuery.isPlainObject( context ) &&
+				(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
+
+			// This is an HTML string according to the "old" rules; is it still?
+			if ( !rspaceAngle.test( selector ) ) {
+				migrateWarn("$(html) HTML strings must start with '<' character");
+			}
+			if ( match[ 3 ] ) {
+				migrateWarn("$(html) HTML text after last tag is ignored");
+			}
+
+			// Consistently reject any HTML-like string starting with a hash (gh-9521)
+			// Note that this may break jQuery 1.6.x code that otherwise would work.
+			if ( match[ 0 ].charAt( 0 ) === "#" ) {
+				migrateWarn("HTML string cannot start with a '#' character");
+				jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
+			}
+
+			// Now process using loose rules; let pre-1.8 play too
+			// Is this a jQuery context? parseHTML expects a DOM element (#178)
+			if ( context && context.context && context.context.nodeType ) {
+				context = context.context;
+			}
+
+			if ( jQuery.parseHTML ) {
+				return oldInit.call( this,
+						jQuery.parseHTML( match[ 2 ], context && context.ownerDocument ||
+							context || document, true ), context, rootjQuery );
+			}
+		}
 	}
 
@@ -253,4 +257,45 @@
 };
 jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.find = function( selector ) {
+	var args = Array.prototype.slice.call( arguments );
+
+	// Support: PhantomJS 1.x
+	// String#match fails to match when used with a //g RegExp, only on some strings
+	if ( typeof selector === "string" && rattrHashTest.test( selector ) ) {
+
+		// The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
+		// First see if qS thinks it's a valid selector, if so avoid a false positive
+		try {
+			document.querySelector( selector );
+		} catch ( err1 ) {
+
+			// Didn't *look* valid to qSA, warn and try quoting what we think is the value
+			selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) {
+				return "[" + attr + op + "\"" + value + "\"]";
+			} );
+
+			// If the regexp *may* have created an invalid selector, don't update it
+			// Note that there may be false alarms if selector uses jQuery extensions
+			try {
+				document.querySelector( selector );
+				migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] );
+				args[ 0 ] = selector;
+			} catch ( err2 ) {
+				migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] );
+			}
+		}
+	}
+
+	return oldFind.apply( this, args );
+};
+
+// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML)
+var findProp;
+for ( findProp in oldFind ) {
+	if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) {
+		jQuery.find[ findProp ] = oldFind[ findProp ];
+	}
+}
 
 // Let $.parseJSON(falsy_value) return null
@@ -504,5 +549,4 @@
 	jQuery.fn[ name ] = function() {
 		var args = Array.prototype.slice.call( arguments, 0 );
-		migrateWarn( "jQuery.fn." + name + "() is deprecated" );
 
 		// If this is an ajax load() the first arg should be the string URL;
@@ -510,7 +554,9 @@
 		// which just goes to show why this dumb signature has been deprecated!
 		// jQuery custom builds that exclude the Ajax module justifiably die here.
-		if ( name === "load" && typeof arguments[ 0 ] === "string" ) {
-			return oldLoad.apply( this, arguments );
-		}
+		if ( name === "load" && typeof args[ 0 ] === "string" ) {
+			return oldLoad.apply( this, args );
+		}
+
+		migrateWarn( "jQuery.fn." + name + "() is deprecated" );
 
 		args.splice( 0, 0, name );
@@ -613,9 +659,13 @@
 
 jQuery.event.special.ready = {
-	setup: function() { migrateWarn( "'ready' event is deprecated" ); }
+	setup: function() {
+		if ( this === document ) {
+			migrateWarn( "'ready' event is deprecated" );
+		}
+	}
 };
 
 var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack,
-	oldFind = jQuery.fn.find;
+	oldFnFind = jQuery.fn.find;
 
 jQuery.fn.andSelf = function() {
@@ -625,5 +675,5 @@
 
 jQuery.fn.find = function( selector ) {
-	var ret = oldFind.apply( this, arguments );
+	var ret = oldFnFind.apply( this, arguments );
 	ret.context = this.context;
 	ret.selector = this.selector ? this.selector + " " + selector : selector;
Index: admin/js/jquery/jquery-ui.custom.js
===================================================================
--- admin/js/jquery/jquery-ui.custom.js	(revision 3178)
+++ admin/js/jquery/jquery-ui.custom.js	(revision 3684)
@@ -1,5 +1,5 @@
-/*! jQuery UI - v1.11.4 - 2016-02-20
+/*! jQuery UI - v1.12.1 - 2018-01-27
 * http://jqueryui.com
-* Includes: core.js, widget.js, mouse.js, draggable.js, sortable.js, accordion.js
+* Includes: widget.js, data.js, keycode.js, scroll-parent.js, unique-id.js, widgets/draggable.js, widgets/sortable.js, widgets/accordion.js, widgets/mouse.js
 * Copyright jQuery Foundation and other contributors; Licensed MIT */
 
@@ -15,6 +15,12 @@
 	}
 }(function( $ ) {
+
+$.ui = $.ui || {};
+
+var version = $.ui.version = "1.12.1";
+
+
 /*!
- * jQuery UI Core 1.11.4
+ * jQuery UI Widget 1.12.1
  * http://jqueryui.com
  *
@@ -22,310 +28,21 @@
  * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://api.jqueryui.com/category/ui-core/
  */
 
-
-// $.ui might exist from components with no dependencies, e.g., $.ui.position
-$.ui = $.ui || {};
-
-$.extend( $.ui, {
-	version: "1.11.4",
-
-	keyCode: {
-		BACKSPACE: 8,
-		COMMA: 188,
-		DELETE: 46,
-		DOWN: 40,
-		END: 35,
-		ENTER: 13,
-		ESCAPE: 27,
-		HOME: 36,
-		LEFT: 37,
-		PAGE_DOWN: 34,
-		PAGE_UP: 33,
-		PERIOD: 190,
-		RIGHT: 39,
-		SPACE: 32,
-		TAB: 9,
-		UP: 38
-	}
-});
-
-// plugins
-$.fn.extend({
-	scrollParent: function( includeHidden ) {
-		var position = this.css( "position" ),
-			excludeStaticParent = position === "absolute",
-			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
-			scrollParent = this.parents().filter( function() {
-				var parent = $( this );
-				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
-					return false;
-				}
-				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
-			}).eq( 0 );
-
-		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
-	},
-
-	uniqueId: (function() {
-		var uuid = 0;
-
-		return function() {
-			return this.each(function() {
-				if ( !this.id ) {
-					this.id = "ui-id-" + ( ++uuid );
-				}
-			});
-		};
-	})(),
-
-	removeUniqueId: function() {
-		return this.each(function() {
-			if ( /^ui-id-\d+$/.test( this.id ) ) {
-				$( this ).removeAttr( "id" );
-			}
-		});
-	}
-});
-
-// selectors
-function focusable( element, isTabIndexNotNaN ) {
-	var map, mapName, img,
-		nodeName = element.nodeName.toLowerCase();
-	if ( "area" === nodeName ) {
-		map = element.parentNode;
-		mapName = map.name;
-		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
-			return false;
-		}
-		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
-		return !!img && visible( img );
-	}
-	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
-		!element.disabled :
-		"a" === nodeName ?
-			element.href || isTabIndexNotNaN :
-			isTabIndexNotNaN) &&
-		// the element and all of its ancestors must be visible
-		visible( element );
-}
-
-function visible( element ) {
-	return $.expr.filters.visible( element ) &&
-		!$( element ).parents().addBack().filter(function() {
-			return $.css( this, "visibility" ) === "hidden";
-		}).length;
-}
-
-$.extend( $.expr[ ":" ], {
-	data: $.expr.createPseudo ?
-		$.expr.createPseudo(function( dataName ) {
-			return function( elem ) {
-				return !!$.data( elem, dataName );
-			};
-		}) :
-		// support: jQuery <1.8
-		function( elem, i, match ) {
-			return !!$.data( elem, match[ 3 ] );
-		},
-
-	focusable: function( element ) {
-		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
-	},
-
-	tabbable: function( element ) {
-		var tabIndex = $.attr( element, "tabindex" ),
-			isTabIndexNaN = isNaN( tabIndex );
-		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
-	}
-});
-
-// support: jQuery <1.8
-if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
-	$.each( [ "Width", "Height" ], function( i, name ) {
-		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
-			type = name.toLowerCase(),
-			orig = {
-				innerWidth: $.fn.innerWidth,
-				innerHeight: $.fn.innerHeight,
-				outerWidth: $.fn.outerWidth,
-				outerHeight: $.fn.outerHeight
-			};
-
-		function reduce( elem, size, border, margin ) {
-			$.each( side, function() {
-				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
-				if ( border ) {
-					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
-				}
-				if ( margin ) {
-					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
-				}
-			});
-			return size;
-		}
-
-		$.fn[ "inner" + name ] = function( size ) {
-			if ( size === undefined ) {
-				return orig[ "inner" + name ].call( this );
-			}
-
-			return this.each(function() {
-				$( this ).css( type, reduce( this, size ) + "px" );
-			});
-		};
-
-		$.fn[ "outer" + name] = function( size, margin ) {
-			if ( typeof size !== "number" ) {
-				return orig[ "outer" + name ].call( this, size );
-			}
-
-			return this.each(function() {
-				$( this).css( type, reduce( this, size, true, margin ) + "px" );
-			});
-		};
-	});
-}
-
-// support: jQuery <1.8
-if ( !$.fn.addBack ) {
-	$.fn.addBack = function( selector ) {
-		return this.add( selector == null ?
-			this.prevObject : this.prevObject.filter( selector )
-		);
-	};
-}
-
-// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
-if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
-	$.fn.removeData = (function( removeData ) {
-		return function( key ) {
-			if ( arguments.length ) {
-				return removeData.call( this, $.camelCase( key ) );
-			} else {
-				return removeData.call( this );
-			}
-		};
-	})( $.fn.removeData );
-}
-
-// deprecated
-$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
-
-$.fn.extend({
-	focus: (function( orig ) {
-		return function( delay, fn ) {
-			return typeof delay === "number" ?
-				this.each(function() {
-					var elem = this;
-					setTimeout(function() {
-						$( elem ).focus();
-						if ( fn ) {
-							fn.call( elem );
-						}
-					}, delay );
-				}) :
-				orig.apply( this, arguments );
-		};
-	})( $.fn.focus ),
-
-	disableSelection: (function() {
-		var eventType = "onselectstart" in document.createElement( "div" ) ?
-			"selectstart" :
-			"mousedown";
-
-		return function() {
-			return this.bind( eventType + ".ui-disableSelection", function( event ) {
-				event.preventDefault();
-			});
-		};
-	})(),
-
-	enableSelection: function() {
-		return this.unbind( ".ui-disableSelection" );
-	},
-
-	zIndex: function( zIndex ) {
-		if ( zIndex !== undefined ) {
-			return this.css( "zIndex", zIndex );
-		}
-
-		if ( this.length ) {
-			var elem = $( this[ 0 ] ), position, value;
-			while ( elem.length && elem[ 0 ] !== document ) {
-				// Ignore z-index if position is set to a value where z-index is ignored by the browser
-				// This makes behavior of this function consistent across browsers
-				// WebKit always returns auto if the element is positioned
-				position = elem.css( "position" );
-				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
-					// IE returns 0 when zIndex is not specified
-					// other browsers return a string
-					// we ignore the case of nested elements with an explicit value of 0
-					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
-					value = parseInt( elem.css( "zIndex" ), 10 );
-					if ( !isNaN( value ) && value !== 0 ) {
-						return value;
-					}
-				}
-				elem = elem.parent();
-			}
-		}
-
-		return 0;
-	}
-});
-
-// $.ui.plugin is deprecated. Use $.widget() extensions instead.
-$.ui.plugin = {
-	add: function( module, option, set ) {
-		var i,
-			proto = $.ui[ module ].prototype;
-		for ( i in set ) {
-			proto.plugins[ i ] = proto.plugins[ i ] || [];
-			proto.plugins[ i ].push( [ option, set[ i ] ] );
-		}
-	},
-	call: function( instance, name, args, allowDisconnected ) {
-		var i,
-			set = instance.plugins[ name ];
-
-		if ( !set ) {
-			return;
-		}
-
-		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
-			return;
-		}
-
-		for ( i = 0; i < set.length; i++ ) {
-			if ( instance.options[ set[ i ][ 0 ] ] ) {
-				set[ i ][ 1 ].apply( instance.element, args );
-			}
-		}
-	}
-};
-
-
-/*!
- * jQuery UI Widget 1.11.4
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/jQuery.widget/
- */
-
-
-var widget_uuid = 0,
-	widget_slice = Array.prototype.slice;
-
-$.cleanData = (function( orig ) {
+//>>label: Widget
+//>>group: Core
+//>>description: Provides a factory for creating stateful widgets with a common API.
+//>>docs: http://api.jqueryui.com/jQuery.widget/
+//>>demos: http://jqueryui.com/widget/
+
+
+
+var widgetUuid = 0;
+var widgetSlice = Array.prototype.slice;
+
+$.cleanData = ( function( orig ) {
 	return function( elems ) {
 		var events, elem, i;
-		for ( i = 0; (elem = elems[i]) != null; i++ ) {
+		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
 			try {
 
@@ -336,20 +53,21 @@
 				}
 
-			// http://bugs.jquery.com/ticket/8235
+			// Http://bugs.jquery.com/ticket/8235
 			} catch ( e ) {}
 		}
 		orig( elems );
 	};
-})( $.cleanData );
+} )( $.cleanData );
 
 $.widget = function( name, base, prototype ) {
-	var fullName, existingConstructor, constructor, basePrototype,
-		// proxiedPrototype allows the provided prototype to remain unmodified
-		// so that it can be used as a mixin for multiple widgets (#8876)
-		proxiedPrototype = {},
-		namespace = name.split( "." )[ 0 ];
-
+	var existingConstructor, constructor, basePrototype;
+
+	// ProxiedPrototype allows the provided prototype to remain unmodified
+	// so that it can be used as a mixin for multiple widgets (#8876)
+	var proxiedPrototype = {};
+
+	var namespace = name.split( "." )[ 0 ];
 	name = name.split( "." )[ 1 ];
-	fullName = namespace + "-" + name;
+	var fullName = namespace + "-" + name;
 
 	if ( !prototype ) {
@@ -358,5 +76,9 @@
 	}
 
-	// create selector for plugin
+	if ( $.isArray( prototype ) ) {
+		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
+	}
+
+	// Create selector for plugin
 	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
 		return !!$.data( elem, fullName );
@@ -366,10 +88,11 @@
 	existingConstructor = $[ namespace ][ name ];
 	constructor = $[ namespace ][ name ] = function( options, element ) {
-		// allow instantiation without "new" keyword
+
+		// Allow instantiation without "new" keyword
 		if ( !this._createWidget ) {
 			return new constructor( options, element );
 		}
 
-		// allow instantiation without initializing for simple inheritance
+		// Allow instantiation without initializing for simple inheritance
 		// must use "new" keyword (the code above always passes args)
 		if ( arguments.length ) {
@@ -377,17 +100,21 @@
 		}
 	};
-	// extend with the existing constructor to carry over any static properties
+
+	// Extend with the existing constructor to carry over any static properties
 	$.extend( constructor, existingConstructor, {
 		version: prototype.version,
-		// copy the object used to create the prototype in case we need to
+
+		// Copy the object used to create the prototype in case we need to
 		// redefine the widget later
 		_proto: $.extend( {}, prototype ),
-		// track widgets that inherit from this widget in case this widget is
+
+		// Track widgets that inherit from this widget in case this widget is
 		// redefined after a widget inherits from it
 		_childConstructors: []
-	});
+	} );
 
 	basePrototype = new base();
-	// we need to make the options hash a property directly on the new instance
+
+	// We need to make the options hash a property directly on the new instance
 	// otherwise we'll modify the options hash on the prototype that we're
 	// inheriting from
@@ -398,15 +125,17 @@
 			return;
 		}
-		proxiedPrototype[ prop ] = (function() {
-			var _super = function() {
-					return base.prototype[ prop ].apply( this, arguments );
-				},
-				_superApply = function( args ) {
-					return base.prototype[ prop ].apply( this, args );
-				};
+		proxiedPrototype[ prop ] = ( function() {
+			function _super() {
+				return base.prototype[ prop ].apply( this, arguments );
+			}
+
+			function _superApply( args ) {
+				return base.prototype[ prop ].apply( this, args );
+			}
+
 			return function() {
-				var __super = this._super,
-					__superApply = this._superApply,
-					returnValue;
+				var __super = this._super;
+				var __superApply = this._superApply;
+				var returnValue;
 
 				this._super = _super;
@@ -420,11 +149,12 @@
 				return returnValue;
 			};
-		})();
-	});
+		} )();
+	} );
 	constructor.prototype = $.widget.extend( basePrototype, {
+
 		// TODO: remove support for widgetEventPrefix
 		// always use the name + a colon as the prefix, e.g., draggable:start
 		// don't prefix for widgets that aren't DOM-based
-		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
+		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
 	}, proxiedPrototype, {
 		constructor: constructor,
@@ -432,5 +162,5 @@
 		widgetName: name,
 		widgetFullName: fullName
-	});
+	} );
 
 	// If this widget is being redefined then we need to find all widgets that
@@ -442,9 +172,11 @@
 			var childPrototype = child.prototype;
 
-			// redefine the child widget using the same prototype that was
+			// Redefine the child widget using the same prototype that was
 			// originally used, but inherit from the new version of the base
-			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
-		});
-		// remove the list of existing child constructors from the old constructor
+			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
+				child._proto );
+		} );
+
+		// Remove the list of existing child constructors from the old constructor
 		// so the old child constructors can be garbage collected
 		delete existingConstructor._childConstructors;
@@ -459,19 +191,23 @@
 
 $.widget.extend = function( target ) {
-	var input = widget_slice.call( arguments, 1 ),
-		inputIndex = 0,
-		inputLength = input.length,
-		key,
-		value;
+	var input = widgetSlice.call( arguments, 1 );
+	var inputIndex = 0;
+	var inputLength = input.length;
+	var key;
+	var value;
+
 	for ( ; inputIndex < inputLength; inputIndex++ ) {
 		for ( key in input[ inputIndex ] ) {
 			value = input[ inputIndex ][ key ];
 			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+
 				// Clone objects
 				if ( $.isPlainObject( value ) ) {
 					target[ key ] = $.isPlainObject( target[ key ] ) ?
 						$.widget.extend( {}, target[ key ], value ) :
+
 						// Don't extend strings, arrays, etc. with objects
 						$.widget.extend( {}, value );
+
 				// Copy everything else by reference
 				} else {
@@ -487,39 +223,53 @@
 	var fullName = object.prototype.widgetFullName || name;
 	$.fn[ name ] = function( options ) {
-		var isMethodCall = typeof options === "string",
-			args = widget_slice.call( arguments, 1 ),
-			returnValue = this;
+		var isMethodCall = typeof options === "string";
+		var args = widgetSlice.call( arguments, 1 );
+		var returnValue = this;
 
 		if ( isMethodCall ) {
-			this.each(function() {
-				var methodValue,
-					instance = $.data( this, fullName );
-				if ( options === "instance" ) {
-					returnValue = instance;
-					return false;
-				}
-				if ( !instance ) {
-					return $.error( "cannot call methods on " + name + " prior to initialization; " +
-						"attempted to call method '" + options + "'" );
-				}
-				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
-					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
-				}
-				methodValue = instance[ options ].apply( instance, args );
-				if ( methodValue !== instance && methodValue !== undefined ) {
-					returnValue = methodValue && methodValue.jquery ?
-						returnValue.pushStack( methodValue.get() ) :
-						methodValue;
-					return false;
-				}
-			});
+
+			// If this is an empty collection, we need to have the instance method
+			// return undefined instead of the jQuery instance
+			if ( !this.length && options === "instance" ) {
+				returnValue = undefined;
+			} else {
+				this.each( function() {
+					var methodValue;
+					var instance = $.data( this, fullName );
+
+					if ( options === "instance" ) {
+						returnValue = instance;
+						return false;
+					}
+
+					if ( !instance ) {
+						return $.error( "cannot call methods on " + name +
+							" prior to initialization; " +
+							"attempted to call method '" + options + "'" );
+					}
+
+					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
+						return $.error( "no such method '" + options + "' for " + name +
+							" widget instance" );
+					}
+
+					methodValue = instance[ options ].apply( instance, args );
+
+					if ( methodValue !== instance && methodValue !== undefined ) {
+						returnValue = methodValue && methodValue.jquery ?
+							returnValue.pushStack( methodValue.get() ) :
+							methodValue;
+						return false;
+					}
+				} );
+			}
 		} else {
 
 			// Allow multiple hashes to be passed on init
 			if ( args.length ) {
-				options = $.widget.extend.apply( null, [ options ].concat(args) );
-			}
-
-			this.each(function() {
+				options = $.widget.extend.apply( null, [ options ].concat( args ) );
+			}
+
+			this.each( function() {
 				var instance = $.data( this, fullName );
 				if ( instance ) {
@@ -531,5 +281,5 @@
 					$.data( this, fullName, new object( options, this ) );
 				}
-			});
+			} );
 		}
 
@@ -545,14 +295,17 @@
 	widgetEventPrefix: "",
 	defaultElement: "<div>",
+
 	options: {
+		classes: {},
 		disabled: false,
 
-		// callbacks
+		// Callbacks
 		create: null
 	},
+
 	_createWidget: function( options, element ) {
 		element = $( element || this.defaultElement || this )[ 0 ];
 		this.element = $( element );
-		this.uuid = widget_uuid++;
+		this.uuid = widgetUuid++;
 		this.eventNamespace = "." + this.widgetName + this.uuid;
 
@@ -560,4 +313,5 @@
 		this.hoverable = $();
 		this.focusable = $();
+		this.classesElementLookup = {};
 
 		if ( element !== this ) {
@@ -569,11 +323,13 @@
 					}
 				}
-			});
+			} );
 			this.document = $( element.style ?
-				// element within the document
+
+				// Element within the document
 				element.ownerDocument :
-				// element is window or document
+
+				// Element is window or document
 				element.document || element );
-			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
 		}
 
@@ -584,34 +340,44 @@
 
 		this._create();
+
+		if ( this.options.disabled ) {
+			this._setOptionDisabled( this.options.disabled );
+		}
+
 		this._trigger( "create", null, this._getCreateEventData() );
 		this._init();
 	},
-	_getCreateOptions: $.noop,
+
+	_getCreateOptions: function() {
+		return {};
+	},
+
 	_getCreateEventData: $.noop,
+
 	_create: $.noop,
+
 	_init: $.noop,
 
 	destroy: function() {
+		var that = this;
+
 		this._destroy();
-		// we can probably remove the unbind calls in 2.0
+		$.each( this.classesElementLookup, function( key, value ) {
+			that._removeClass( value, key );
+		} );
+
+		// We can probably remove the unbind calls in 2.0
 		// all event bindings should go through this._on()
 		this.element
-			.unbind( this.eventNamespace )
-			.removeData( this.widgetFullName )
-			// support: jquery <1.6.3
-			// http://bugs.jquery.com/ticket/9413
-			.removeData( $.camelCase( this.widgetFullName ) );
+			.off( this.eventNamespace )
+			.removeData( this.widgetFullName );
 		this.widget()
-			.unbind( this.eventNamespace )
-			.removeAttr( "aria-disabled" )
-			.removeClass(
-				this.widgetFullName + "-disabled " +
-				"ui-state-disabled" );
-
-		// clean up events and states
-		this.bindings.unbind( this.eventNamespace );
-		this.hoverable.removeClass( "ui-state-hover" );
-		this.focusable.removeClass( "ui-state-focus" );
-	},
+			.off( this.eventNamespace )
+			.removeAttr( "aria-disabled" );
+
+		// Clean up events and states
+		this.bindings.off( this.eventNamespace );
+	},
+
 	_destroy: $.noop,
 
@@ -621,16 +387,18 @@
 
 	option: function( key, value ) {
-		var options = key,
-			parts,
-			curOption,
-			i;
+		var options = key;
+		var parts;
+		var curOption;
+		var i;
 
 		if ( arguments.length === 0 ) {
-			// don't return a reference to the internal hash
+
+			// Don't return a reference to the internal hash
 			return $.widget.extend( {}, this.options );
 		}
 
 		if ( typeof key === "string" ) {
-			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+
+			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
 			options = {};
 			parts = key.split( "." );
@@ -659,4 +427,5 @@
 		return this;
 	},
+
 	_setOptions: function( options ) {
 		var key;
@@ -668,16 +437,14 @@
 		return this;
 	},
+
 	_setOption: function( key, value ) {
+		if ( key === "classes" ) {
+			this._setOptionClasses( value );
+		}
+
 		this.options[ key ] = value;
 
 		if ( key === "disabled" ) {
-			this.widget()
-				.toggleClass( this.widgetFullName + "-disabled", !!value );
-
-			// If the widget is becoming disabled, then nothing is interactive
-			if ( value ) {
-				this.hoverable.removeClass( "ui-state-hover" );
-				this.focusable.removeClass( "ui-state-focus" );
-			}
+			this._setOptionDisabled( value );
 		}
 
@@ -685,16 +452,128 @@
 	},
 
+	_setOptionClasses: function( value ) {
+		var classKey, elements, currentElements;
+
+		for ( classKey in value ) {
+			currentElements = this.classesElementLookup[ classKey ];
+			if ( value[ classKey ] === this.options.classes[ classKey ] ||
+					!currentElements ||
+					!currentElements.length ) {
+				continue;
+			}
+
+			// We are doing this to create a new jQuery object because the _removeClass() call
+			// on the next line is going to destroy the reference to the current elements being
+			// tracked. We need to save a copy of this collection so that we can add the new classes
+			// below.
+			elements = $( currentElements.get() );
+			this._removeClass( currentElements, classKey );
+
+			// We don't use _addClass() here, because that uses this.options.classes
+			// for generating the string of classes. We want to use the value passed in from
+			// _setOption(), this is the new value of the classes option which was passed to
+			// _setOption(). We pass this value directly to _classes().
+			elements.addClass( this._classes( {
+				element: elements,
+				keys: classKey,
+				classes: value,
+				add: true
+			} ) );
+		}
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
+
+		// If the widget is becoming disabled, then nothing is interactive
+		if ( value ) {
+			this._removeClass( this.hoverable, null, "ui-state-hover" );
+			this._removeClass( this.focusable, null, "ui-state-focus" );
+		}
+	},
+
 	enable: function() {
-		return this._setOptions({ disabled: false });
-	},
+		return this._setOptions( { disabled: false } );
+	},
+
 	disable: function() {
-		return this._setOptions({ disabled: true });
+		return this._setOptions( { disabled: true } );
+	},
+
+	_classes: function( options ) {
+		var full = [];
+		var that = this;
+
+		options = $.extend( {
+			element: this.element,
+			classes: this.options.classes || {}
+		}, options );
+
+		function processClassString( classes, checkOption ) {
+			var current, i;
+			for ( i = 0; i < classes.length; i++ ) {
+				current = that.classesElementLookup[ classes[ i ] ] || $();
+				if ( options.add ) {
+					current = $( $.unique( current.get().concat( options.element.get() ) ) );
+				} else {
+					current = $( current.not( options.element ).get() );
+				}
+				that.classesElementLookup[ classes[ i ] ] = current;
+				full.push( classes[ i ] );
+				if ( checkOption && options.classes[ classes[ i ] ] ) {
+					full.push( options.classes[ classes[ i ] ] );
+				}
+			}
+		}
+
+		this._on( options.element, {
+			"remove": "_untrackClassesElement"
+		} );
+
+		if ( options.keys ) {
+			processClassString( options.keys.match( /\S+/g ) || [], true );
+		}
+		if ( options.extra ) {
+			processClassString( options.extra.match( /\S+/g ) || [] );
+		}
+
+		return full.join( " " );
+	},
+
+	_untrackClassesElement: function( event ) {
+		var that = this;
+		$.each( that.classesElementLookup, function( key, value ) {
+			if ( $.inArray( event.target, value ) !== -1 ) {
+				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
+			}
+		} );
+	},
+
+	_removeClass: function( element, keys, extra ) {
+		return this._toggleClass( element, keys, extra, false );
+	},
+
+	_addClass: function( element, keys, extra ) {
+		return this._toggleClass( element, keys, extra, true );
+	},
+
+	_toggleClass: function( element, keys, extra, add ) {
+		add = ( typeof add === "boolean" ) ? add : extra;
+		var shift = ( typeof element === "string" || element === null ),
+			options = {
+				extra: shift ? keys : extra,
+				keys: shift ? element : keys,
+				element: shift ? this.element : element,
+				add: add
+			};
+		options.element.toggleClass( this._classes( options ), add );
+		return this;
 	},
 
 	_on: function( suppressDisabledCheck, element, handlers ) {
-		var delegateElement,
-			instance = this;
-
-		// no suppressDisabledCheck flag, shuffle arguments
+		var delegateElement;
+		var instance = this;
+
+		// No suppressDisabledCheck flag, shuffle arguments
 		if ( typeof suppressDisabledCheck !== "boolean" ) {
 			handlers = element;
@@ -703,5 +582,5 @@
 		}
 
-		// no element argument, shuffle and use this.element
+		// No element argument, shuffle and use this.element
 		if ( !handlers ) {
 			handlers = element;
@@ -715,10 +594,11 @@
 		$.each( handlers, function( event, handler ) {
 			function handlerProxy() {
-				// allow widgets to customize the disabled handling
+
+				// Allow widgets to customize the disabled handling
 				// - disabled as an array instead of boolean
 				// - disabled class as method for disabling individual parts
 				if ( !suppressDisabledCheck &&
 						( instance.options.disabled === true ||
-							$( this ).hasClass( "ui-state-disabled" ) ) ) {
+						$( this ).hasClass( "ui-state-disabled" ) ) ) {
 					return;
 				}
@@ -727,5 +607,5 @@
 			}
 
-			// copy the guid so direct unbinding works
+			// Copy the guid so direct unbinding works
 			if ( typeof handler !== "string" ) {
 				handlerProxy.guid = handler.guid =
@@ -733,19 +613,20 @@
 			}
 
-			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
-				eventName = match[1] + instance.eventNamespace,
-				selector = match[2];
+			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
+			var eventName = match[ 1 ] + instance.eventNamespace;
+			var selector = match[ 2 ];
+
 			if ( selector ) {
-				delegateElement.delegate( selector, eventName, handlerProxy );
+				delegateElement.on( eventName, selector, handlerProxy );
 			} else {
-				element.bind( eventName, handlerProxy );
-			}
-		});
+				element.on( eventName, handlerProxy );
+			}
+		} );
 	},
 
 	_off: function( element, eventName ) {
-		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
+		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
 			this.eventNamespace;
-		element.unbind( eventName ).undelegate( eventName );
+		element.off( eventName ).off( eventName );
 
 		// Clear the stack to avoid memory leaks (#10056)
@@ -768,10 +649,10 @@
 		this._on( element, {
 			mouseenter: function( event ) {
-				$( event.currentTarget ).addClass( "ui-state-hover" );
+				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
 			},
 			mouseleave: function( event ) {
-				$( event.currentTarget ).removeClass( "ui-state-hover" );
-			}
-		});
+				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
+			}
+		} );
 	},
 
@@ -780,15 +661,15 @@
 		this._on( element, {
 			focusin: function( event ) {
-				$( event.currentTarget ).addClass( "ui-state-focus" );
+				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
 			},
 			focusout: function( event ) {
-				$( event.currentTarget ).removeClass( "ui-state-focus" );
-			}
-		});
+				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
+			}
+		} );
 	},
 
 	_trigger: function( type, event, data ) {
-		var prop, orig,
-			callback = this.options[ type ];
+		var prop, orig;
+		var callback = this.options[ type ];
 
 		data = data || {};
@@ -797,9 +678,10 @@
 			type :
 			this.widgetEventPrefix + type ).toLowerCase();
-		// the original event may come from any element
+
+		// The original event may come from any element
 		// so we need to reset the target on the new event
 		event.target = this.element[ 0 ];
 
-		// copy original event properties over to the new event
+		// Copy original event properties over to the new event
 		orig = event.originalEvent;
 		if ( orig ) {
@@ -813,5 +695,5 @@
 		this.element.trigger( event, data );
 		return !( $.isFunction( callback ) &&
-			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
 			event.isDefaultPrevented() );
 	}
@@ -823,19 +705,24 @@
 			options = { effect: options };
 		}
-		var hasOptions,
-			effectName = !options ?
-				method :
-				options === true || typeof options === "number" ?
-					defaultEffect :
-					options.effect || defaultEffect;
+
+		var hasOptions;
+		var effectName = !options ?
+			method :
+			options === true || typeof options === "number" ?
+				defaultEffect :
+				options.effect || defaultEffect;
+
 		options = options || {};
 		if ( typeof options === "number" ) {
 			options = { duration: options };
 		}
+
 		hasOptions = !$.isEmptyObject( options );
 		options.complete = callback;
+
 		if ( options.delay ) {
 			element.delay( options.delay );
 		}
+
 		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
 			element[ method ]( options );
@@ -843,5 +730,5 @@
 			element[ effectName ]( options.duration, options.easing, callback );
 		} else {
-			element.queue(function( next ) {
+			element.queue( function( next ) {
 				$( this )[ method ]();
 				if ( callback ) {
@@ -849,8 +736,8 @@
 				}
 				next();
-			});
+			} );
 		}
 	};
-});
+} );
 
 var widget = $.widget;
@@ -858,5 +745,5 @@
 
 /*!
- * jQuery UI Mouse 1.11.4
+ * jQuery UI :data 1.12.1
  * http://jqueryui.com
  *
@@ -864,18 +751,165 @@
  * Released under the MIT license.
  * http://jquery.org/license
+ */
+
+//>>label: :data Selector
+//>>group: Core
+//>>description: Selects elements which have data stored under the specified key.
+//>>docs: http://api.jqueryui.com/data-selector/
+
+
+var data = $.extend( $.expr[ ":" ], {
+	data: $.expr.createPseudo ?
+		$.expr.createPseudo( function( dataName ) {
+			return function( elem ) {
+				return !!$.data( elem, dataName );
+			};
+		} ) :
+
+		// Support: jQuery <1.8
+		function( elem, i, match ) {
+			return !!$.data( elem, match[ 3 ] );
+		}
+} );
+
+/*!
+ * jQuery UI Keycode 1.12.1
+ * http://jqueryui.com
  *
- * http://api.jqueryui.com/mouse/
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
  */
 
+//>>label: Keycode
+//>>group: Core
+//>>description: Provide keycodes as keynames
+//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
+
+
+var keycode = $.ui.keyCode = {
+	BACKSPACE: 8,
+	COMMA: 188,
+	DELETE: 46,
+	DOWN: 40,
+	END: 35,
+	ENTER: 13,
+	ESCAPE: 27,
+	HOME: 36,
+	LEFT: 37,
+	PAGE_DOWN: 34,
+	PAGE_UP: 33,
+	PERIOD: 190,
+	RIGHT: 39,
+	SPACE: 32,
+	TAB: 9,
+	UP: 38
+};
+
+
+/*!
+ * jQuery UI Scroll Parent 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: scrollParent
+//>>group: Core
+//>>description: Get the closest ancestor element that is scrollable.
+//>>docs: http://api.jqueryui.com/scrollParent/
+
+
+
+var scrollParent = $.fn.scrollParent = function( includeHidden ) {
+	var position = this.css( "position" ),
+		excludeStaticParent = position === "absolute",
+		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
+		scrollParent = this.parents().filter( function() {
+			var parent = $( this );
+			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
+				return false;
+			}
+			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
+				parent.css( "overflow-x" ) );
+		} ).eq( 0 );
+
+	return position === "fixed" || !scrollParent.length ?
+		$( this[ 0 ].ownerDocument || document ) :
+		scrollParent;
+};
+
+
+/*!
+ * jQuery UI Unique ID 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: uniqueId
+//>>group: Core
+//>>description: Functions to generate and remove uniqueId's
+//>>docs: http://api.jqueryui.com/uniqueId/
+
+
+
+var uniqueId = $.fn.extend( {
+	uniqueId: ( function() {
+		var uuid = 0;
+
+		return function() {
+			return this.each( function() {
+				if ( !this.id ) {
+					this.id = "ui-id-" + ( ++uuid );
+				}
+			} );
+		};
+	} )(),
+
+	removeUniqueId: function() {
+		return this.each( function() {
+			if ( /^ui-id-\d+$/.test( this.id ) ) {
+				$( this ).removeAttr( "id" );
+			}
+		} );
+	}
+} );
+
+
+
+
+// This file is deprecated
+var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+/*!
+ * jQuery UI Mouse 1.12.1
+ * http://jqueryui.com
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ */
+
+//>>label: Mouse
+//>>group: Widgets
+//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
+//>>docs: http://api.jqueryui.com/mouse/
+
+
 
 var mouseHandled = false;
-$( document ).mouseup( function() {
+$( document ).on( "mouseup", function() {
 	mouseHandled = false;
-});
-
-var mouse = $.widget("ui.mouse", {
-	version: "1.11.4",
+} );
+
+var widgetsMouse = $.widget( "ui.mouse", {
+	version: "1.12.1",
 	options: {
-		cancel: "input,textarea,button,select,option",
+		cancel: "input, textarea, button, select, option",
 		distance: 1,
 		delay: 0
@@ -885,14 +919,14 @@
 
 		this.element
-			.bind("mousedown." + this.widgetName, function(event) {
-				return that._mouseDown(event);
-			})
-			.bind("click." + this.widgetName, function(event) {
-				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
-					$.removeData(event.target, that.widgetName + ".preventClickEvent");
+			.on( "mousedown." + this.widgetName, function( event ) {
+				return that._mouseDown( event );
+			} )
+			.on( "click." + this.widgetName, function( event ) {
+				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
+					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
 					event.stopImmediatePropagation();
 					return false;
 				}
-			});
+			} );
 
 		this.started = false;
@@ -902,13 +936,14 @@
 	// other instances of mouse
 	_mouseDestroy: function() {
-		this.element.unbind("." + this.widgetName);
+		this.element.off( "." + this.widgetName );
 		if ( this._mouseMoveDelegate ) {
 			this.document
-				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
-				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
-		}
-	},
-
-	_mouseDown: function(event) {
+				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
+		}
+	},
+
+	_mouseDown: function( event ) {
+
 		// don't let more than one widget handle mouseStart
 		if ( mouseHandled ) {
@@ -918,28 +953,30 @@
 		this._mouseMoved = false;
 
-		// we may have missed mouseup (out of window)
-		(this._mouseStarted && this._mouseUp(event));
+		// We may have missed mouseup (out of window)
+		( this._mouseStarted && this._mouseUp( event ) );
 
 		this._mouseDownEvent = event;
 
 		var that = this,
-			btnIsLeft = (event.which === 1),
+			btnIsLeft = ( event.which === 1 ),
+
 			// event.target.nodeName works around a bug in IE 8 with
 			// disabled inputs (#7620)
-			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
-		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
+				$( event.target ).closest( this.options.cancel ).length : false );
+		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
 			return true;
 		}
 
 		this.mouseDelayMet = !this.options.delay;
-		if (!this.mouseDelayMet) {
-			this._mouseDelayTimer = setTimeout(function() {
+		if ( !this.mouseDelayMet ) {
+			this._mouseDelayTimer = setTimeout( function() {
 				that.mouseDelayMet = true;
-			}, this.options.delay);
-		}
-
-		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
-			this._mouseStarted = (this._mouseStart(event) !== false);
-			if (!this._mouseStarted) {
+			}, this.options.delay );
+		}
+
+		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
+			this._mouseStarted = ( this._mouseStart( event ) !== false );
+			if ( !this._mouseStarted ) {
 				event.preventDefault();
 				return true;
@@ -948,19 +985,19 @@
 
 		// Click event may never have fired (Gecko & Opera)
-		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
-			$.removeData(event.target, this.widgetName + ".preventClickEvent");
-		}
-
-		// these delegates are required to keep context
-		this._mouseMoveDelegate = function(event) {
-			return that._mouseMove(event);
+		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
+			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
+		}
+
+		// These delegates are required to keep context
+		this._mouseMoveDelegate = function( event ) {
+			return that._mouseMove( event );
 		};
-		this._mouseUpDelegate = function(event) {
-			return that._mouseUp(event);
+		this._mouseUpDelegate = function( event ) {
+			return that._mouseUp( event );
 		};
 
 		this.document
-			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
-			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
+			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
 
 		event.preventDefault();
@@ -970,5 +1007,6 @@
 	},
 
-	_mouseMove: function(event) {
+	_mouseMove: function( event ) {
+
 		// Only check for mouseups outside the document if you've moved inside the document
 		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
@@ -976,11 +1014,22 @@
 		// Support: IE <9
 		if ( this._mouseMoved ) {
+
 			// IE mouseup check - mouseup happened when mouse was out of window
-			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
-				return this._mouseUp(event);
+			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
+					!event.button ) {
+				return this._mouseUp( event );
 
 			// Iframe mouseup check - mouseup occurred in another document
 			} else if ( !event.which ) {
-				return this._mouseUp( event );
+
+				// Support: Safari <=8 - 9
+				// Safari sets which to 0 if you press any of the following keys
+				// during a drag (#14461)
+				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
+						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
+					this.ignoreMissingWhich = true;
+				} else if ( !this.ignoreMissingWhich ) {
+					return this._mouseUp( event );
+				}
 			}
 		}
@@ -990,13 +1039,13 @@
 		}
 
-		if (this._mouseStarted) {
-			this._mouseDrag(event);
+		if ( this._mouseStarted ) {
+			this._mouseDrag( event );
 			return event.preventDefault();
 		}
 
-		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
 			this._mouseStarted =
-				(this._mouseStart(this._mouseDownEvent, event) !== false);
-			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+				( this._mouseStart( this._mouseDownEvent, event ) !== false );
+			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
 		}
 
@@ -1004,45 +1053,126 @@
 	},
 
-	_mouseUp: function(event) {
+	_mouseUp: function( event ) {
 		this.document
-			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
-			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
-
-		if (this._mouseStarted) {
+			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
+			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
+
+		if ( this._mouseStarted ) {
 			this._mouseStarted = false;
 
-			if (event.target === this._mouseDownEvent.target) {
-				$.data(event.target, this.widgetName + ".preventClickEvent", true);
-			}
-
-			this._mouseStop(event);
-		}
-
+			if ( event.target === this._mouseDownEvent.target ) {
+				$.data( event.target, this.widgetName + ".preventClickEvent", true );
+			}
+
+			this._mouseStop( event );
+		}
+
+		if ( this._mouseDelayTimer ) {
+			clearTimeout( this._mouseDelayTimer );
+			delete this._mouseDelayTimer;
+		}
+
+		this.ignoreMissingWhich = false;
 		mouseHandled = false;
-		return false;
-	},
-
-	_mouseDistanceMet: function(event) {
-		return (Math.max(
-				Math.abs(this._mouseDownEvent.pageX - event.pageX),
-				Math.abs(this._mouseDownEvent.pageY - event.pageY)
+		event.preventDefault();
+	},
+
+	_mouseDistanceMet: function( event ) {
+		return ( Math.max(
+				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
+				Math.abs( this._mouseDownEvent.pageY - event.pageY )
 			) >= this.options.distance
 		);
 	},
 
-	_mouseDelayMet: function(/* event */) {
+	_mouseDelayMet: function( /* event */ ) {
 		return this.mouseDelayMet;
 	},
 
 	// These are placeholder methods, to be overriden by extending plugin
-	_mouseStart: function(/* event */) {},
-	_mouseDrag: function(/* event */) {},
-	_mouseStop: function(/* event */) {},
-	_mouseCapture: function(/* event */) { return true; }
-});
+	_mouseStart: function( /* event */ ) {},
+	_mouseDrag: function( /* event */ ) {},
+	_mouseStop: function( /* event */ ) {},
+	_mouseCapture: function( /* event */ ) { return true; }
+} );
+
+
+
+
+// $.ui.plugin is deprecated. Use $.widget() extensions instead.
+var plugin = $.ui.plugin = {
+	add: function( module, option, set ) {
+		var i,
+			proto = $.ui[ module ].prototype;
+		for ( i in set ) {
+			proto.plugins[ i ] = proto.plugins[ i ] || [];
+			proto.plugins[ i ].push( [ option, set[ i ] ] );
+		}
+	},
+	call: function( instance, name, args, allowDisconnected ) {
+		var i,
+			set = instance.plugins[ name ];
+
+		if ( !set ) {
+			return;
+		}
+
+		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
+				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
+			return;
+		}
+
+		for ( i = 0; i < set.length; i++ ) {
+			if ( instance.options[ set[ i ][ 0 ] ] ) {
+				set[ i ][ 1 ].apply( instance.element, args );
+			}
+		}
+	}
+};
+
+
+
+var safeActiveElement = $.ui.safeActiveElement = function( document ) {
+	var activeElement;
+
+	// Support: IE 9 only
+	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
+	try {
+		activeElement = document.activeElement;
+	} catch ( error ) {
+		activeElement = document.body;
+	}
+
+	// Support: IE 9 - 11 only
+	// IE may return null instead of an element
+	// Interestingly, this only seems to occur when NOT in an iframe
+	if ( !activeElement ) {
+		activeElement = document.body;
+	}
+
+	// Support: IE 11 only
+	// IE11 returns a seemingly empty object in some cases when accessing
+	// document.activeElement from an <iframe>
+	if ( !activeElement.nodeName ) {
+		activeElement = document.body;
+	}
+
+	return activeElement;
+};
+
+
+
+var safeBlur = $.ui.safeBlur = function( element ) {
+
+	// Support: IE9 - 10 only
+	// If the <body> is blurred, IE will switch windows, see #9420
+	if ( element && element.nodeName.toLowerCase() !== "body" ) {
+		$( element ).trigger( "blur" );
+	}
+};
 
 
 /*!
- * jQuery UI Draggable 1.11.4
+ * jQuery UI Draggable 1.12.1
  * http://jqueryui.com
  *
@@ -1050,11 +1180,17 @@
  * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://api.jqueryui.com/draggable/
  */
 
-
-$.widget("ui.draggable", $.ui.mouse, {
-	version: "1.11.4",
+//>>label: Draggable
+//>>group: Interactions
+//>>description: Enables dragging functionality for any element.
+//>>docs: http://api.jqueryui.com/draggable/
+//>>demos: http://jqueryui.com/draggable/
+//>>css.structure: ../../themes/base/draggable.css
+
+
+
+$.widget( "ui.draggable", $.ui.mouse, {
+	version: "1.12.1",
 	widgetEventPrefix: "drag",
 	options: {
@@ -1084,5 +1220,5 @@
 		zIndex: false,
 
-		// callbacks
+		// Callbacks
 		drag: null,
 		start: null,
@@ -1094,9 +1230,6 @@
 			this._setPositionRelative();
 		}
-		if (this.options.addClasses){
-			this.element.addClass("ui-draggable");
-		}
-		if (this.options.disabled){
-			this.element.addClass("ui-draggable-disabled");
+		if ( this.options.addClasses ) {
+			this._addClass( "ui-draggable" );
 		}
 		this._setHandleClassName();
@@ -1118,25 +1251,25 @@
 			return;
 		}
-		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
 		this._removeHandleClassName();
 		this._mouseDestroy();
 	},
 
-	_mouseCapture: function(event) {
+	_mouseCapture: function( event ) {
 		var o = this.options;
 
+		// Among others, prevent a drag on a resizable-handle
+		if ( this.helper || o.disabled ||
+				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
+			return false;
+		}
+
+		//Quit if we're not on a valid handle
+		this.handle = this._getHandle( event );
+		if ( !this.handle ) {
+			return false;
+		}
+
 		this._blurActiveElement( event );
 
-		// among others, prevent a drag on a resizable-handle
-		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
-			return false;
-		}
-
-		//Quit if we're not on a valid handle
-		this.handle = this._getHandle(event);
-		if (!this.handle) {
-			return false;
-		}
-
 		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
 
@@ -1146,5 +1279,5 @@
 
 	_blockFrames: function( selector ) {
-		this.iframeBlocks = this.document.find( selector ).map(function() {
+		this.iframeBlocks = this.document.find( selector ).map( function() {
 			var iframe = $( this );
 
@@ -1155,5 +1288,5 @@
 				.outerHeight( iframe.outerHeight() )
 				.offset( iframe.offset() )[ 0 ];
-		});
+		} );
 	},
 
@@ -1166,33 +1299,26 @@
 
 	_blurActiveElement: function( event ) {
-		var document = this.document[ 0 ];
-
-		// Only need to blur if the event occurred on the draggable itself, see #10527
-		if ( !this.handleElement.is( event.target ) ) {
+		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
+			target = $( event.target );
+
+		// Don't blur if the event occurred on an element that is within
+		// the currently focused element
+		// See #10527, #12472
+		if ( target.closest( activeElement ).length ) {
 			return;
 		}
 
-		// support: IE9
-		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
-		try {
-
-			// Support: IE9, IE10
-			// If the <body> is blurred, IE will switch windows, see #9520
-			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
-
-				// Blur any element that currently has focus, see #4261
-				$( document.activeElement ).blur();
-			}
-		} catch ( error ) {}
-	},
-
-	_mouseStart: function(event) {
+		// Blur any element that currently has focus, see #4261
+		$.ui.safeBlur( activeElement );
+	},
+
+	_mouseStart: function( event ) {
 
 		var o = this.options;
 
 		//Create and append the visible helper
-		this.helper = this._createHelper(event);
-
-		this.helper.addClass("ui-draggable-dragging");
+		this.helper = this._createHelper( event );
+
+		this._addClass( this.helper, "ui-draggable-dragging" );
 
 		//Cache the helper size
@@ -1200,5 +1326,5 @@
 
 		//If ddmanager is used for droppables, set the global draggable
-		if ($.ui.ddmanager) {
+		if ( $.ui.ddmanager ) {
 			$.ui.ddmanager.current = this;
 		}
@@ -1216,7 +1342,7 @@
 		this.scrollParent = this.helper.scrollParent( true );
 		this.offsetParent = this.helper.offsetParent();
-		this.hasFixedAncestor = this.helper.parents().filter(function() {
+		this.hasFixedAncestor = this.helper.parents().filter( function() {
 				return $( this ).css( "position" ) === "fixed";
-			}).length > 0;
+			} ).length > 0;
 
 		//The element's absolute position on the page minus margins
@@ -1230,5 +1356,5 @@
 
 		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
 
 		//Set a containment if given in the options
@@ -1236,5 +1362,5 @@
 
 		//Trigger event + callbacks
-		if (this._trigger("start", event) === false) {
+		if ( this._trigger( "start", event ) === false ) {
 			this._clear();
 			return false;
@@ -1245,17 +1371,16 @@
 
 		//Prepare the droppable offsets
-		if ($.ui.ddmanager && !o.dropBehaviour) {
-			$.ui.ddmanager.prepareOffsets(this, event);
-		}
-
-		// Reset helper's right/bottom css if they're set and set explicit width/height instead
-		// as this prevents resizing of elements with right/bottom set (see #7772)
-		this._normalizeRightBottom();
-
-		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
-
-		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+		if ( $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( this, event );
+		}
+
+		// Execute the drag once - this causes the helper not to be visible before getting its
+		// correct position
+		this._mouseDrag( event, true );
+
+		// If the ddmanager is used for droppables, inform the manager that dragging has started
+		// (see #5003)
 		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.dragStart(this, event);
+			$.ui.ddmanager.dragStart( this, event );
 		}
 
@@ -1278,5 +1403,6 @@
 	},
 
-	_mouseDrag: function(event, noPropagation) {
+	_mouseDrag: function( event, noPropagation ) {
+
 		// reset any necessary cached properties (see #5009)
 		if ( this.hasFixedAncestor ) {
@@ -1286,11 +1412,11 @@
 		//Compute the helpers position
 		this.position = this._generatePosition( event, true );
-		this.positionAbs = this._convertPositionTo("absolute");
+		this.positionAbs = this._convertPositionTo( "absolute" );
 
 		//Call plugins and callbacks and use the resulting position if something is returned
-		if (!noPropagation) {
+		if ( !noPropagation ) {
 			var ui = this._uiHash();
-			if (this._trigger("drag", event, ui) === false) {
-				this._mouseUp({});
+			if ( this._trigger( "drag", event, ui ) === false ) {
+				this._mouseUp( new $.Event( "mouseup", event ) );
 				return false;
 			}
@@ -1301,6 +1427,6 @@
 		this.helper[ 0 ].style.top = this.position.top + "px";
 
-		if ($.ui.ddmanager) {
-			$.ui.ddmanager.drag(this, event);
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.drag( this, event );
 		}
 
@@ -1308,27 +1434,35 @@
 	},
 
-	_mouseStop: function(event) {
+	_mouseStop: function( event ) {
 
 		//If we are using droppables, inform the manager about the drop
 		var that = this,
 			dropped = false;
-		if ($.ui.ddmanager && !this.options.dropBehaviour) {
-			dropped = $.ui.ddmanager.drop(this, event);
+		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
+			dropped = $.ui.ddmanager.drop( this, event );
 		}
 
 		//if a drop comes from outside (a sortable)
-		if (this.dropped) {
+		if ( this.dropped ) {
 			dropped = this.dropped;
 			this.dropped = false;
 		}
 
-		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))) {
-			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
-				if (that._trigger("stop", event) !== false) {
-					that._clear();
-				}
-			});
+		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 ) )
+		) {
+			$( this.helper ).animate(
+				this.originalPosition,
+				parseInt( this.options.revertDuration, 10 ),
+				function() {
+					if ( that._trigger( "stop", event ) !== false ) {
+						that._clear();
+					}
+				}
+			);
 		} else {
-			if (this._trigger("stop", event) !== false) {
+			if ( this._trigger( "stop", event ) !== false ) {
 				this._clear();
 			}
@@ -1341,22 +1475,25 @@
 		this._unblockFrames();
 
-		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
+		// (see #5003)
 		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.dragStop(this, event);
+			$.ui.ddmanager.dragStop( this, event );
 		}
 
 		// Only need to focus if the event occurred on the draggable itself, see #10527
 		if ( this.handleElement.is( event.target ) ) {
-			// The interaction is over; whether or not the click resulted in a drag, focus the element
-			this.element.focus();
-		}
-
-		return $.ui.mouse.prototype._mouseUp.call(this, event);
+
+			// The interaction is over; whether or not the click resulted in a drag,
+			// focus the element
+			this.element.trigger( "focus" );
+		}
+
+		return $.ui.mouse.prototype._mouseUp.call( this, event );
 	},
 
 	cancel: function() {
 
-		if (this.helper.is(".ui-draggable-dragging")) {
-			this._mouseUp({});
+		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
+			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
 		} else {
 			this._clear();
@@ -1367,5 +1504,5 @@
 	},
 
-	_getHandle: function(event) {
+	_getHandle: function( event ) {
 		return this.options.handle ?
 			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
@@ -1376,12 +1513,12 @@
 		this.handleElement = this.options.handle ?
 			this.element.find( this.options.handle ) : this.element;
-		this.handleElement.addClass( "ui-draggable-handle" );
+		this._addClass( this.handleElement, "ui-draggable-handle" );
 	},
 
 	_removeHandleClassName: function() {
-		this.handleElement.removeClass( "ui-draggable-handle" );
-	},
-
-	_createHelper: function(event) {
+		this._removeClass( this.handleElement, "ui-draggable-handle" );
+	},
+
+	_createHelper: function( event ) {
 
 		var o = this.options,
@@ -1393,9 +1530,11 @@
 					this.element );
 
-		if (!helper.parents("body").length) {
-			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
-		}
-
-		// http://bugs.jqueryui.com/ticket/9446
+		if ( !helper.parents( "body" ).length ) {
+			helper.appendTo( ( o.appendTo === "parent" ?
+				this.element[ 0 ].parentNode :
+				o.appendTo ) );
+		}
+
+		// Http://bugs.jqueryui.com/ticket/9446
 		// a helper function can return the original element
 		// which wouldn't have been set to relative in _create
@@ -1404,6 +1543,7 @@
 		}
 
-		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
-			helper.css("position", "absolute");
+		if ( helper[ 0 ] !== this.element[ 0 ] &&
+				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
+			helper.css( "position", "absolute" );
 		}
 
@@ -1418,21 +1558,21 @@
 	},
 
-	_adjustOffsetFromHelper: function(obj) {
-		if (typeof obj === "string") {
-			obj = obj.split(" ");
-		}
-		if ($.isArray(obj)) {
-			obj = { left: +obj[0], top: +obj[1] || 0 };
-		}
-		if ("left" in obj) {
+	_adjustOffsetFromHelper: function( obj ) {
+		if ( typeof obj === "string" ) {
+			obj = obj.split( " " );
+		}
+		if ( $.isArray( obj ) ) {
+			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
+		}
+		if ( "left" in obj ) {
 			this.offset.click.left = obj.left + this.margins.left;
 		}
-		if ("right" in obj) {
+		if ( "right" in obj ) {
 			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 		}
-		if ("top" in obj) {
+		if ( "top" in obj ) {
 			this.offset.click.top = obj.top + this.margins.top;
 		}
-		if ("bottom" in obj) {
+		if ( "bottom" in obj ) {
 			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 		}
@@ -1449,9 +1589,13 @@
 			document = this.document[ 0 ];
 
-		// This is a special case where we need to modify a offset calculated on start, since the following happened:
-		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
-		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
-		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
-		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+		// This is a special case where we need to modify a offset calculated on start, since the
+		// following happened:
+		// 1. The position of the helper is absolute, so it's position is calculated based on the
+		// next positioned parent
+		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
+		// the document, which means that the scroll is included in the initial calculation of the
+		// offset of the parent, and never recalculated upon drag
+		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
 			po.left += this.scrollParent.scrollLeft();
 			po.top += this.scrollParent.scrollTop();
@@ -1463,6 +1607,6 @@
 
 		return {
-			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
-			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
+			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
+			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
 		};
 
@@ -1478,6 +1622,8 @@
 
 		return {
-			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
-			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
+			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
+				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
+			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
+				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
 		};
 
@@ -1486,8 +1632,8 @@
 	_cacheMargins: function() {
 		this.margins = {
-			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
-			top: (parseInt(this.element.css("marginTop"), 10) || 0),
-			right: (parseInt(this.element.css("marginRight"), 10) || 0),
-			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
+			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
+			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
+			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
+			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
 		};
 	},
@@ -1517,16 +1663,20 @@
 				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
 				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
-				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
-				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+				$( window ).scrollLeft() + $( window ).width() -
+					this.helperProportions.width - this.margins.left,
+				$( window ).scrollTop() +
+					( $( window ).height() || document.body.parentNode.scrollHeight ) -
+					this.helperProportions.height - this.margins.top
 			];
 			return;
 		}
 
-		if ( o.containment === "document") {
+		if ( o.containment === "document" ) {
 			this.containment = [
 				0,
 				0,
 				$( document ).width() - this.helperProportions.width - this.margins.left,
-				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
+				( $( document ).height() || document.body.parentNode.scrollHeight ) -
+					this.helperProportions.height - this.margins.top
 			];
 			return;
@@ -1552,6 +1702,8 @@
 
 		this.containment = [
-			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
-			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
+			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
+				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
+			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
+				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
 			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
 				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
@@ -1570,7 +1722,7 @@
 	},
 
-	_convertPositionTo: function(d, pos) {
-
-		if (!pos) {
+	_convertPositionTo: function( d, pos ) {
+
+		if ( !pos ) {
 			pos = this.position;
 		}
@@ -1581,14 +1733,30 @@
 		return {
 			top: (
-				pos.top	+																// The absolute mouse position
-				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
+
+				// The absolute mouse position
+				pos.top	+
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top * mod -
+				( ( this.cssPosition === "fixed" ?
+					-this.offset.scroll.top :
+					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
 			),
 			left: (
-				pos.left +																// The absolute mouse position
-				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
+
+				// The absolute mouse position
+				pos.left +
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left * mod	-
+				( ( this.cssPosition === "fixed" ?
+					-this.offset.scroll.left :
+					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
 			)
 		};
@@ -1620,5 +1788,5 @@
 		if ( constrainPosition ) {
 			if ( this.containment ) {
-				if ( this.relativeContainer ){
+				if ( this.relativeContainer ) {
 					co = this.relativeContainer.offset();
 					containment = [
@@ -1632,25 +1800,38 @@
 				}
 
-				if (event.pageX - this.offset.click.left < containment[0]) {
-					pageX = containment[0] + this.offset.click.left;
-				}
-				if (event.pageY - this.offset.click.top < containment[1]) {
-					pageY = containment[1] + this.offset.click.top;
-				}
-				if (event.pageX - this.offset.click.left > containment[2]) {
-					pageX = containment[2] + this.offset.click.left;
-				}
-				if (event.pageY - this.offset.click.top > containment[3]) {
-					pageY = containment[3] + this.offset.click.top;
-				}
-			}
-
-			if (o.grid) {
-				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
-				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
-				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;
-
-				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
-				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;
+				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
+					pageX = containment[ 0 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
+					pageY = containment[ 1 ] + this.offset.click.top;
+				}
+				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
+					pageX = containment[ 2 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
+					pageY = containment[ 3 ] + this.offset.click.top;
+				}
+			}
+
+			if ( o.grid ) {
+
+				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
+				// argument errors in IE (see ticket #6950)
+				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
+					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
+				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;
+
+				left = o.grid[ 0 ] ? this.originalPageX +
+					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
+					this.originalPageX;
+				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;
 			}
 
@@ -1666,16 +1847,36 @@
 		return {
 			top: (
-				pageY -																	// The absolute mouse position
-				this.offset.click.top	-												// Click offset (relative to the element)
-				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
-				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
+
+				// The absolute mouse position
+				pageY -
+
+				// Click offset (relative to the element)
+				this.offset.click.top -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top +
+				( this.cssPosition === "fixed" ?
+					-this.offset.scroll.top :
+					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
 			),
 			left: (
-				pageX -																	// The absolute mouse position
-				this.offset.click.left -												// Click offset (relative to the element)
-				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
-				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
+
+				// The absolute mouse position
+				pageX -
+
+				// Click offset (relative to the element)
+				this.offset.click.left -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left +
+				( this.cssPosition === "fixed" ?
+					-this.offset.scroll.left :
+					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
 			)
 		};
@@ -1684,6 +1885,6 @@
 
 	_clear: function() {
-		this.helper.removeClass("ui-draggable-dragging");
-		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
+		this._removeClass( this.helper, "ui-draggable-dragging" );
+		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
 			this.helper.remove();
 		}
@@ -1692,15 +1893,4 @@
 		if ( this.destroyOnClear ) {
 			this.destroy();
-		}
-	},
-
-	_normalizeRightBottom: function() {
-		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
-			this.helper.width( this.helper.width() );
-			this.helper.css( "right", "auto" );
-		}
-		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
-			this.helper.height( this.helper.height() );
-			this.helper.css( "bottom", "auto" );
 		}
 	},
@@ -1731,5 +1921,5 @@
 	}
 
-});
+} );
 
 $.ui.plugin.add( "draggable", "connectToSortable", {
@@ -1737,8 +1927,8 @@
 		var uiSortable = $.extend( {}, ui, {
 			item: draggable.element
-		});
+		} );
 
 		draggable.sortables = [];
-		$( draggable.options.connectToSortable ).each(function() {
+		$( draggable.options.connectToSortable ).each( function() {
 			var sortable = $( this ).sortable( "instance" );
 
@@ -1746,16 +1936,16 @@
 				draggable.sortables.push( sortable );
 
-				// refreshPositions is called at drag start to refresh the containerCache
+				// RefreshPositions is called at drag start to refresh the containerCache
 				// which is used in drag. This ensures it's initialized and synchronized
 				// with any changes that might have happened on the page since initialization.
 				sortable.refreshPositions();
-				sortable._trigger("activate", event, uiSortable);
-			}
-		});
+				sortable._trigger( "activate", event, uiSortable );
+			}
+		} );
 	},
 	stop: function( event, ui, draggable ) {
 		var uiSortable = $.extend( {}, ui, {
 			item: draggable.element
-		});
+		} );
 
 		draggable.cancelHelperRemoval = false;
@@ -1780,5 +1970,5 @@
 				};
 
-				sortable._mouseStop(event);
+				sortable._mouseStop( event );
 
 				// Once drag has ended, the sortable should return to using
@@ -1786,4 +1976,5 @@
 				sortable.options.helper = sortable.options._helper;
 			} else {
+
 				// Prevent this Sortable from removing the helper.
 				// However, don't set the draggable to remove the helper
@@ -1793,5 +1984,5 @@
 				sortable._trigger( "deactivate", event, uiSortable );
 			}
-		});
+		} );
 	},
 	drag: function( event, ui, draggable ) {
@@ -1809,4 +2000,5 @@
 
 				$.each( draggable.sortables, function() {
+
 					// Copy over variables that sortable's _intersectsWith uses
 					this.positionAbs = draggable.positionAbs;
@@ -1821,8 +2013,9 @@
 
 					return innermostIntersecting;
-				});
+				} );
 			}
 
 			if ( innermostIntersecting ) {
+
 				// If it intersects, we use a little isOver variable and set it once,
 				// so that the move-in stuff gets fired only once.
@@ -1869,7 +2062,7 @@
 					$.each( draggable.sortables, function() {
 						this.refreshPositions();
-					});
-
-					// hack so receive/update callbacks work (mostly)
+					} );
+
+					// Hack so receive/update callbacks work (mostly)
 					draggable.currentItem = draggable.element;
 					sortable.fromOutside = draggable;
@@ -1878,4 +2071,5 @@
 				if ( sortable.currentItem ) {
 					sortable._mouseDrag( event );
+
 					// Copy the sortable's position because the draggable's can potentially reflect
 					// a relative position, while sortable is always absolute, which the dragged
@@ -1884,4 +2078,5 @@
 				}
 			} else {
+
 				// If it doesn't intersect with the sortable, and it intersected before,
 				// we fake the drag stop of the sortable, but make sure it doesn't remove
@@ -1900,5 +2095,5 @@
 					sortable._mouseStop( event, true );
 
-					// restore sortable behaviors that were modfied
+					// Restore sortable behaviors that were modfied
 					// when the draggable entered the sortable area (#9481)
 					sortable.options.revert = sortable.options._revert;
@@ -1924,47 +2119,47 @@
 					$.each( draggable.sortables, function() {
 						this.refreshPositions();
-					});
-				}
-			}
-		});
+					} );
+				}
+			}
+		} );
 	}
-});
-
-$.ui.plugin.add("draggable", "cursor", {
+} );
+
+$.ui.plugin.add( "draggable", "cursor", {
 	start: function( event, ui, instance ) {
 		var t = $( "body" ),
 			o = instance.options;
 
-		if (t.css("cursor")) {
-			o._cursor = t.css("cursor");
-		}
-		t.css("cursor", o.cursor);
+		if ( t.css( "cursor" ) ) {
+			o._cursor = t.css( "cursor" );
+		}
+		t.css( "cursor", o.cursor );
 	},
 	stop: function( event, ui, instance ) {
 		var o = instance.options;
-		if (o._cursor) {
-			$("body").css("cursor", o._cursor);
+		if ( o._cursor ) {
+			$( "body" ).css( "cursor", o._cursor );
 		}
 	}
-});
-
-$.ui.plugin.add("draggable", "opacity", {
+} );
+
+$.ui.plugin.add( "draggable", "opacity", {
 	start: function( event, ui, instance ) {
 		var t = $( ui.helper ),
 			o = instance.options;
-		if (t.css("opacity")) {
-			o._opacity = t.css("opacity");
-		}
-		t.css("opacity", o.opacity);
+		if ( t.css( "opacity" ) ) {
+			o._opacity = t.css( "opacity" );
+		}
+		t.css( "opacity", o.opacity );
 	},
 	stop: function( event, ui, instance ) {
 		var o = instance.options;
-		if (o._opacity) {
-			$(ui.helper).css("opacity", o._opacity);
+		if ( o._opacity ) {
+			$( ui.helper ).css( "opacity", o._opacity );
 		}
 	}
-});
-
-$.ui.plugin.add("draggable", "scroll", {
+} );
+
+$.ui.plugin.add( "draggable", "scroll", {
 	start: function( event, ui, i ) {
 		if ( !i.scrollParentNotHidden ) {
@@ -1972,5 +2167,6 @@
 		}
 
-		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
+		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
+				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
 			i.overflowOffset = i.scrollParentNotHidden.offset();
 		}
@@ -1985,5 +2181,6 @@
 		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
 			if ( !o.axis || o.axis !== "x" ) {
-				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
+				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
+						o.scrollSensitivity ) {
 					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
 				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
@@ -1993,5 +2190,6 @@
 
 			if ( !o.axis || o.axis !== "y" ) {
-				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
+				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
+						o.scrollSensitivity ) {
 					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
 				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
@@ -2002,30 +2200,36 @@
 		} else {
 
-			if (!o.axis || o.axis !== "x") {
-				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
-					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
-				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
-					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
-				}
-			}
-
-			if (!o.axis || o.axis !== "y") {
-				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
-					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
-				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
-					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
-				}
-			}
-
-		}
-
-		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
-			$.ui.ddmanager.prepareOffsets(i, event);
+			if ( !o.axis || o.axis !== "x" ) {
+				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
+					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
+				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
+						o.scrollSensitivity ) {
+					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
+				}
+			}
+
+			if ( !o.axis || o.axis !== "y" ) {
+				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
+					scrolled = $( document ).scrollLeft(
+						$( document ).scrollLeft() - o.scrollSpeed
+					);
+				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
+						o.scrollSensitivity ) {
+					scrolled = $( document ).scrollLeft(
+						$( document ).scrollLeft() + o.scrollSpeed
+					);
+				}
+			}
+
+		}
+
+		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( i, event );
 		}
 
 	}
-});
-
-$.ui.plugin.add("draggable", "snap", {
+} );
+
+$.ui.plugin.add( "draggable", "snap", {
 	start: function( event, ui, i ) {
 
@@ -2034,15 +2238,16 @@
 		i.snapElements = [];
 
-		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
-			var $t = $(this),
-				$o = $t.offset();
-			if (this !== i.element[0]) {
-				i.snapElements.push({
-					item: this,
-					width: $t.outerWidth(), height: $t.outerHeight(),
-					top: $o.top, left: $o.left
-				});
-			}
-		});
+		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
+			.each( function() {
+				var $t = $( this ),
+					$o = $t.offset();
+				if ( this !== i.element[ 0 ] ) {
+					i.snapElements.push( {
+						item: this,
+						width: $t.outerWidth(), height: $t.outerHeight(),
+						top: $o.top, left: $o.left
+					} );
+				}
+			} );
 
 	},
@@ -2055,111 +2260,149 @@
 			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
 
-		for (i = inst.snapElements.length - 1; i >= 0; i--){
-
-			l = inst.snapElements[i].left - inst.margins.left;
-			r = l + inst.snapElements[i].width;
-			t = inst.snapElements[i].top - inst.margins.top;
-			b = t + inst.snapElements[i].height;
-
-			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
-				if (inst.snapElements[i].snapping) {
-					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
-				}
-				inst.snapElements[i].snapping = false;
+		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
+
+			l = inst.snapElements[ i ].left - inst.margins.left;
+			r = l + inst.snapElements[ i ].width;
+			t = inst.snapElements[ i ].top - inst.margins.top;
+			b = t + inst.snapElements[ i ].height;
+
+			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
+					!$.contains( inst.snapElements[ i ].item.ownerDocument,
+					inst.snapElements[ i ].item ) ) {
+				if ( inst.snapElements[ i ].snapping ) {
+					( inst.options.snap.release &&
+						inst.options.snap.release.call(
+							inst.element,
+							event,
+							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
+						) );
+				}
+				inst.snapElements[ i ].snapping = false;
 				continue;
 			}
 
-			if (o.snapMode !== "inner") {
-				ts = Math.abs(t - y2) <= d;
-				bs = Math.abs(b - y1) <= d;
-				ls = Math.abs(l - x2) <= d;
-				rs = Math.abs(r - x1) <= d;
-				if (ts) {
-					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
-				}
-				if (bs) {
-					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
-				}
-				if (ls) {
-					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
-				}
-				if (rs) {
-					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
-				}
-			}
-
-			first = (ts || bs || ls || rs);
-
-			if (o.snapMode !== "outer") {
-				ts = Math.abs(t - y1) <= d;
-				bs = Math.abs(b - y2) <= d;
-				ls = Math.abs(l - x1) <= d;
-				rs = Math.abs(r - x2) <= d;
-				if (ts) {
-					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
-				}
-				if (bs) {
-					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
-				}
-				if (ls) {
-					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
-				}
-				if (rs) {
-					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
-				}
-			}
-
-			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
-				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
-			}
-			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+			if ( o.snapMode !== "inner" ) {
+				ts = Math.abs( t - y2 ) <= d;
+				bs = Math.abs( b - y1 ) <= d;
+				ls = Math.abs( l - x2 ) <= d;
+				rs = Math.abs( r - x1 ) <= d;
+				if ( ts ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: t - inst.helperProportions.height,
+						left: 0
+					} ).top;
+				}
+				if ( bs ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: b,
+						left: 0
+					} ).top;
+				}
+				if ( ls ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: l - inst.helperProportions.width
+					} ).left;
+				}
+				if ( rs ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: r
+					} ).left;
+				}
+			}
+
+			first = ( ts || bs || ls || rs );
+
+			if ( o.snapMode !== "outer" ) {
+				ts = Math.abs( t - y1 ) <= d;
+				bs = Math.abs( b - y2 ) <= d;
+				ls = Math.abs( l - x1 ) <= d;
+				rs = Math.abs( r - x2 ) <= d;
+				if ( ts ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: t,
+						left: 0
+					} ).top;
+				}
+				if ( bs ) {
+					ui.position.top = inst._convertPositionTo( "relative", {
+						top: b - inst.helperProportions.height,
+						left: 0
+					} ).top;
+				}
+				if ( ls ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: l
+					} ).left;
+				}
+				if ( rs ) {
+					ui.position.left = inst._convertPositionTo( "relative", {
+						top: 0,
+						left: r - inst.helperProportions.width
+					} ).left;
+				}
+			}
+
+			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
+				( inst.options.snap.snap &&
+					inst.options.snap.snap.call(
+						inst.element,
+						event,
+						$.extend( inst._uiHash(), {
+							snapItem: inst.snapElements[ i ].item
+						} ) ) );
+			}
+			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
 
 		}
 
 	}
-});
-
-$.ui.plugin.add("draggable", "stack", {
+} );
+
+$.ui.plugin.add( "draggable", "stack", {
 	start: function( event, ui, instance ) {
 		var min,
 			o = instance.options,
-			group = $.makeArray($(o.stack)).sort(function(a, b) {
-				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
-			});
-
-		if (!group.length) { return; }
-
-		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
-		$(group).each(function(i) {
-			$(this).css("zIndex", min + i);
-		});
-		this.css("zIndex", (min + group.length));
+			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
+				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
+					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
+			} );
+
+		if ( !group.length ) { return; }
+
+		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
+		$( group ).each( function( i ) {
+			$( this ).css( "zIndex", min + i );
+		} );
+		this.css( "zIndex", ( min + group.length ) );
 	}
-});
-
-$.ui.plugin.add("draggable", "zIndex", {
+} );
+
+$.ui.plugin.add( "draggable", "zIndex", {
 	start: function( event, ui, instance ) {
 		var t = $( ui.helper ),
 			o = instance.options;
 
-		if (t.css("zIndex")) {
-			o._zIndex = t.css("zIndex");
-		}
-		t.css("zIndex", o.zIndex);
+		if ( t.css( "zIndex" ) ) {
+			o._zIndex = t.css( "zIndex" );
+		}
+		t.css( "zIndex", o.zIndex );
 	},
 	stop: function( event, ui, instance ) {
 		var o = instance.options;
 
-		if (o._zIndex) {
-			$(ui.helper).css("zIndex", o._zIndex);
+		if ( o._zIndex ) {
+			$( ui.helper ).css( "zIndex", o._zIndex );
 		}
 	}
-});
-
-var draggable = $.ui.draggable;
+} );
+
+var widgetsDraggable = $.ui.draggable;
 
 
 /*!
- * jQuery UI Sortable 1.11.4
+ * jQuery UI Sortable 1.12.1
  * http://jqueryui.com
  *
@@ -2167,11 +2410,17 @@
  * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://api.jqueryui.com/sortable/
  */
 
-
-var sortable = $.widget("ui.sortable", $.ui.mouse, {
-	version: "1.11.4",
+//>>label: Sortable
+//>>group: Interactions
+//>>description: Enables items in a list to be sorted using the mouse.
+//>>docs: http://api.jqueryui.com/sortable/
+//>>demos: http://jqueryui.com/sortable/
+//>>css.structure: ../../themes/base/sortable.css
+
+
+
+var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
+	version: "1.12.1",
 	widgetEventPrefix: "sort",
 	ready: false,
@@ -2200,5 +2449,5 @@
 		zIndex: 1000,
 
-		// callbacks
+		// Callbacks
 		activate: null,
 		beforeStop: null,
@@ -2220,10 +2469,11 @@
 
 	_isFloating: function( item ) {
-		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
+		return ( /left|right/ ).test( item.css( "float" ) ) ||
+			( /inline|table-cell/ ).test( item.css( "display" ) );
 	},
 
 	_create: function() {
 		this.containerCache = {};
-		this.element.addClass("ui-sortable");
+		this._addClass( "ui-sortable" );
 
 		//Get the items
@@ -2252,21 +2502,21 @@
 
 	_setHandleClassName: function() {
-		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
+		var that = this;
+		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
 		$.each( this.items, function() {
-			( this.instance.options.handle ?
-				this.item.find( this.instance.options.handle ) : this.item )
-				.addClass( "ui-sortable-handle" );
-		});
+			that._addClass(
+				this.instance.options.handle ?
+					this.item.find( this.instance.options.handle ) :
+					this.item,
+				"ui-sortable-handle"
+			);
+		} );
 	},
 
 	_destroy: function() {
-		this.element
-			.removeClass( "ui-sortable ui-sortable-disabled" )
-			.find( ".ui-sortable-handle" )
-				.removeClass( "ui-sortable-handle" );
 		this._mouseDestroy();
 
 		for ( var i = this.items.length - 1; i >= 0; i-- ) {
-			this.items[i].item.removeData(this.widgetName + "-item");
+			this.items[ i ].item.removeData( this.widgetName + "-item" );
 		}
 
@@ -2274,41 +2524,41 @@
 	},
 
-	_mouseCapture: function(event, overrideHandle) {
+	_mouseCapture: function( event, overrideHandle ) {
 		var currentItem = null,
 			validHandle = false,
 			that = this;
 
-		if (this.reverting) {
+		if ( this.reverting ) {
 			return false;
 		}
 
-		if(this.options.disabled || this.options.type === "static") {
+		if ( this.options.disabled || this.options.type === "static" ) {
 			return false;
 		}
 
 		//We have to refresh the items data once first
-		this._refreshItems(event);
+		this._refreshItems( event );
 
 		//Find out if the clicked node (or one of its parents) is a actual item in this.items
-		$(event.target).parents().each(function() {
-			if($.data(this, that.widgetName + "-item") === that) {
-				currentItem = $(this);
+		$( event.target ).parents().each( function() {
+			if ( $.data( this, that.widgetName + "-item" ) === that ) {
+				currentItem = $( this );
 				return false;
 			}
-		});
-		if($.data(event.target, that.widgetName + "-item") === that) {
-			currentItem = $(event.target);
-		}
-
-		if(!currentItem) {
+		} );
+		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
+			currentItem = $( event.target );
+		}
+
+		if ( !currentItem ) {
 			return false;
 		}
-		if(this.options.handle && !overrideHandle) {
-			$(this.options.handle, currentItem).find("*").addBack().each(function() {
-				if(this === event.target) {
+		if ( this.options.handle && !overrideHandle ) {
+			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
+				if ( this === event.target ) {
 					validHandle = true;
 				}
-			});
-			if(!validHandle) {
+			} );
+			if ( !validHandle ) {
 				return false;
 			}
@@ -2321,5 +2571,5 @@
 	},
 
-	_mouseStart: function(event, overrideHandle, noActivation) {
+	_mouseStart: function( event, overrideHandle, noActivation ) {
 
 		var i, body,
@@ -2328,9 +2578,10 @@
 		this.currentContainer = this;
 
-		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+		//We only need to call refreshPositions, because the refreshItems call has been moved to
+		// mouseCapture
 		this.refreshPositions();
 
 		//Create and append the visible helper
-		this.helper = this._createHelper(event);
+		this.helper = this._createHelper( event );
 
 		//Cache the helper size
@@ -2355,5 +2606,5 @@
 		};
 
-		$.extend(this.offset, {
+		$.extend( this.offset, {
 			click: { //Where the click happened, relative to the element
 				left: event.pageX - this.offset.left,
@@ -2361,25 +2612,32 @@
 			},
 			parent: this._getParentOffset(),
-			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
-		});
+
+			// This is a relative to absolute position minus the actual position calculation -
+			// only used for relative positioned helper
+			relative: this._getRelativeOffset()
+		} );
 
 		// Only after we got the offset, we can change the helper's position to absolute
 		// TODO: Still need to figure out a way to make relative sorting possible
-		this.helper.css("position", "absolute");
-		this.cssPosition = this.helper.css("position");
+		this.helper.css( "position", "absolute" );
+		this.cssPosition = this.helper.css( "position" );
 
 		//Generate the original position
-		this.originalPosition = this._generatePosition(event);
+		this.originalPosition = this._generatePosition( event );
 		this.originalPageX = event.pageX;
 		this.originalPageY = event.pageY;
 
 		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
 
 		//Cache the former DOM position
-		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
-
-		//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
-		if(this.helper[0] !== this.currentItem[0]) {
+		this.domPosition = {
+			prev: this.currentItem.prev()[ 0 ],
+			parent: this.currentItem.parent()[ 0 ]
+		};
+
+		// 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
+		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
 			this.currentItem.hide();
 		}
@@ -2389,48 +2647,49 @@
 
 		//Set a containment if given in the options
-		if(o.containment) {
+		if ( o.containment ) {
 			this._setContainment();
 		}
 
-		if( o.cursor && o.cursor !== "auto" ) { // cursor option
+		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
 			body = this.document.find( "body" );
 
-			// support: IE
+			// Support: IE
 			this.storedCursor = body.css( "cursor" );
 			body.css( "cursor", o.cursor );
 
-			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
-		}
-
-		if(o.opacity) { // opacity option
-			if (this.helper.css("opacity")) {
-				this._storedOpacity = this.helper.css("opacity");
-			}
-			this.helper.css("opacity", o.opacity);
-		}
-
-		if(o.zIndex) { // zIndex option
-			if (this.helper.css("zIndex")) {
-				this._storedZIndex = this.helper.css("zIndex");
-			}
-			this.helper.css("zIndex", o.zIndex);
+			this.storedStylesheet =
+				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
+		}
+
+		if ( o.opacity ) { // opacity option
+			if ( this.helper.css( "opacity" ) ) {
+				this._storedOpacity = this.helper.css( "opacity" );
+			}
+			this.helper.css( "opacity", o.opacity );
+		}
+
+		if ( o.zIndex ) { // zIndex option
+			if ( this.helper.css( "zIndex" ) ) {
+				this._storedZIndex = this.helper.css( "zIndex" );
+			}
+			this.helper.css( "zIndex", o.zIndex );
 		}
 
 		//Prepare scrolling
-		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
+		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				this.scrollParent[ 0 ].tagName !== "HTML" ) {
 			this.overflowOffset = this.scrollParent.offset();
 		}
 
 		//Call callbacks
-		this._trigger("start", event, this._uiHash());
+		this._trigger( "start", event, this._uiHash() );
 
 		//Recache the helper size
-		if(!this._preserveHelperProportions) {
+		if ( !this._preserveHelperProportions ) {
 			this._cacheHelperProportions();
 		}
 
-
 		//Post "activate" events to possible containers
-		if( !noActivation ) {
+		if ( !noActivation ) {
 			for ( i = this.containers.length - 1; i >= 0; i-- ) {
 				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
@@ -2439,21 +2698,24 @@
 
 		//Prepare possible droppables
-		if($.ui.ddmanager) {
+		if ( $.ui.ddmanager ) {
 			$.ui.ddmanager.current = this;
 		}
 
-		if ($.ui.ddmanager && !o.dropBehaviour) {
-			$.ui.ddmanager.prepareOffsets(this, event);
+		if ( $.ui.ddmanager && !o.dropBehaviour ) {
+			$.ui.ddmanager.prepareOffsets( this, event );
 		}
 
 		this.dragging = true;
 
-		this.helper.addClass("ui-sortable-helper");
-		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+		this._addClass( this.helper, "ui-sortable-helper" );
+
+		// Execute the drag once - this causes the helper not to be visiblebefore getting its
+		// correct position
+		this._mouseDrag( event );
 		return true;
 
 	},
 
-	_mouseDrag: function(event) {
+	_mouseDrag: function( event ) {
 		var i, item, itemElement, intersection,
 			o = this.options,
@@ -2461,67 +2723,80 @@
 
 		//Compute the helpers position
-		this.position = this._generatePosition(event);
-		this.positionAbs = this._convertPositionTo("absolute");
-
-		if (!this.lastPositionAbs) {
+		this.position = this._generatePosition( event );
+		this.positionAbs = this._convertPositionTo( "absolute" );
+
+		if ( !this.lastPositionAbs ) {
 			this.lastPositionAbs = this.positionAbs;
 		}
 
 		//Do scrolling
-		if(this.options.scroll) {
-			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
-
-				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
-					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
-				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
-					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
-				}
-
-				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
-					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
-				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
-					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+		if ( this.options.scroll ) {
+			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+					this.scrollParent[ 0 ].tagName !== "HTML" ) {
+
+				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
+						event.pageY < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollTop =
+						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
+				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollTop =
+						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
+				}
+
+				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
+						event.pageX < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollLeft = scrolled =
+						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
+				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
+					this.scrollParent[ 0 ].scrollLeft = scrolled =
+						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
 				}
 
 			} else {
 
-				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
-					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
-				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
-					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
-				}
-
-				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
-					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
-				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
-					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
-				}
-
-			}
-
-			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
-				$.ui.ddmanager.prepareOffsets(this, event);
+				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
+					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
+				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
+						o.scrollSensitivity ) {
+					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
+				}
+
+				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
+					scrolled = this.document.scrollLeft(
+						this.document.scrollLeft() - o.scrollSpeed
+					);
+				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
+						o.scrollSensitivity ) {
+					scrolled = this.document.scrollLeft(
+						this.document.scrollLeft() + o.scrollSpeed
+					);
+				}
+
+			}
+
+			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
+				$.ui.ddmanager.prepareOffsets( this, event );
 			}
 		}
 
 		//Regenerate the absolute position used for position checks
-		this.positionAbs = this._convertPositionTo("absolute");
+		this.positionAbs = this._convertPositionTo( "absolute" );
 
 		//Set the helper position
-		if(!this.options.axis || this.options.axis !== "y") {
-			this.helper[0].style.left = this.position.left+"px";
-		}
-		if(!this.options.axis || this.options.axis !== "x") {
-			this.helper[0].style.top = this.position.top+"px";
+		if ( !this.options.axis || this.options.axis !== "y" ) {
+			this.helper[ 0 ].style.left = this.position.left + "px";
+		}
+		if ( !this.options.axis || this.options.axis !== "x" ) {
+			this.helper[ 0 ].style.top = this.position.top + "px";
 		}
 
 		//Rearrange
-		for (i = this.items.length - 1; i >= 0; i--) {
+		for ( i = this.items.length - 1; i >= 0; i-- ) {
 
 			//Cache variables and intersection, continue if no intersection
-			item = this.items[i];
-			itemElement = item.item[0];
-			intersection = this._intersectsWithPointer(item);
-			if (!intersection) {
+			item = this.items[ i ];
+			itemElement = item.item[ 0 ];
+			intersection = this._intersectsWithPointer( item );
+			if ( !intersection ) {
 				continue;
 			}
@@ -2534,26 +2809,29 @@
 			// Without this, moving items in "sub-sortables" can cause
 			// the placeholder to jitter between the outer and inner container.
-			if (item.instance !== this.currentContainer) {
+			if ( item.instance !== this.currentContainer ) {
 				continue;
 			}
 
-			// cannot intersect with itself
+			// Cannot intersect with itself
 			// no useless actions that have been done before
 			// no action if the item moved is the parent of the item checked
-			if (itemElement !== this.currentItem[0] &&
-				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
-				!$.contains(this.placeholder[0], itemElement) &&
-				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
+			if ( itemElement !== this.currentItem[ 0 ] &&
+				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
+				!$.contains( this.placeholder[ 0 ], itemElement ) &&
+				( this.options.type === "semi-dynamic" ?
+					!$.contains( this.element[ 0 ], itemElement ) :
+					true
+				)
 			) {
 
 				this.direction = intersection === 1 ? "down" : "up";
 
-				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
-					this._rearrange(event, item);
+				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
+					this._rearrange( event, item );
 				} else {
 					break;
 				}
 
-				this._trigger("change", event, this._uiHash());
+				this._trigger( "change", event, this._uiHash() );
 				break;
 			}
@@ -2561,13 +2839,13 @@
 
 		//Post events to containers
-		this._contactContainers(event);
+		this._contactContainers( event );
 
 		//Interconnect with droppables
-		if($.ui.ddmanager) {
-			$.ui.ddmanager.drag(this, event);
+		if ( $.ui.ddmanager ) {
+			$.ui.ddmanager.drag( this, event );
 		}
 
 		//Call callbacks
-		this._trigger("sort", event, this._uiHash());
+		this._trigger( "sort", event, this._uiHash() );
 
 		this.lastPositionAbs = this.positionAbs;
@@ -2576,16 +2854,16 @@
 	},
 
-	_mouseStop: function(event, noPropagation) {
-
-		if(!event) {
+	_mouseStop: function( event, noPropagation ) {
+
+		if ( !event ) {
 			return;
 		}
 
 		//If we are using droppables, inform the manager about the drop
-		if ($.ui.ddmanager && !this.options.dropBehaviour) {
-			$.ui.ddmanager.drop(this, event);
-		}
-
-		if(this.options.revert) {
+		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
+			$.ui.ddmanager.drop( this, event );
+		}
+
+		if ( this.options.revert ) {
 			var that = this,
 				cur = this.placeholder.offset(),
@@ -2594,15 +2872,27 @@
 
 			if ( !axis || axis === "x" ) {
-				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
+				animation.left = cur.left - this.offset.parent.left - this.margins.left +
+					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
+						0 :
+						this.offsetParent[ 0 ].scrollLeft
+					);
 			}
 			if ( !axis || axis === "y" ) {
-				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
+				animation.top = cur.top - this.offset.parent.top - this.margins.top +
+					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
+						0 :
+						this.offsetParent[ 0 ].scrollTop
+					);
 			}
 			this.reverting = true;
-			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
-				that._clear(event);
-			});
+			$( this.helper ).animate(
+				animation,
+				parseInt( this.options.revert, 10 ) || 500,
+				function() {
+					that._clear( event );
+				}
+			);
 		} else {
-			this._clear(event, noPropagation);
+			this._clear( event, noPropagation );
 		}
 
@@ -2613,10 +2903,11 @@
 	cancel: function() {
 
-		if(this.dragging) {
-
-			this._mouseUp({ target: null });
-
-			if(this.options.helper === "original") {
-				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+		if ( this.dragging ) {
+
+			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
+
+			if ( this.options.helper === "original" ) {
+				this.currentItem.css( this._storedCSS );
+				this._removeClass( this.currentItem, "ui-sortable-helper" );
 			} else {
 				this.currentItem.show();
@@ -2624,34 +2915,37 @@
 
 			//Post deactivating events to containers
-			for (var i = this.containers.length - 1; i >= 0; i--){
-				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
-				if(this.containers[i].containerCache.over) {
-					this.containers[i]._trigger("out", null, this._uiHash(this));
-					this.containers[i].containerCache.over = 0;
-				}
-			}
-
-		}
-
-		if (this.placeholder) {
-			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
-			if(this.placeholder[0].parentNode) {
-				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
-			}
-			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
+			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
+				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
+				if ( this.containers[ i ].containerCache.over ) {
+					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
+					this.containers[ i ].containerCache.over = 0;
+				}
+			}
+
+		}
+
+		if ( this.placeholder ) {
+
+			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
+			// it unbinds ALL events from the original node!
+			if ( this.placeholder[ 0 ].parentNode ) {
+				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
+			}
+			if ( this.options.helper !== "original" && this.helper &&
+					this.helper[ 0 ].parentNode ) {
 				this.helper.remove();
 			}
 
-			$.extend(this, {
+			$.extend( this, {
 				helper: null,
 				dragging: false,
 				reverting: false,
 				_noFinalSort: null
-			});
-
-			if(this.domPosition.prev) {
-				$(this.domPosition.prev).after(this.currentItem);
+			} );
+
+			if ( this.domPosition.prev ) {
+				$( this.domPosition.prev ).after( this.currentItem );
 			} else {
-				$(this.domPosition.parent).prepend(this.currentItem);
+				$( this.domPosition.parent ).prepend( this.currentItem );
 			}
 		}
@@ -2661,33 +2955,38 @@
 	},
 
-	serialize: function(o) {
-
-		var items = this._getItemsAsjQuery(o && o.connected),
+	serialize: function( o ) {
+
+		var items = this._getItemsAsjQuery( o && o.connected ),
 			str = [];
 		o = o || {};
 
-		$(items).each(function() {
-			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
-			if (res) {
-				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
-			}
-		});
-
-		if(!str.length && o.key) {
-			str.push(o.key + "=");
-		}
-
-		return str.join("&");
-
-	},
-
-	toArray: function(o) {
-
-		var items = this._getItemsAsjQuery(o && o.connected),
+		$( items ).each( function() {
+			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
+				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
+			if ( res ) {
+				str.push(
+					( o.key || res[ 1 ] + "[]" ) +
+					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
+			}
+		} );
+
+		if ( !str.length && o.key ) {
+			str.push( o.key + "=" );
+		}
+
+		return str.join( "&" );
+
+	},
+
+	toArray: function( o ) {
+
+		var items = this._getItemsAsjQuery( o && o.connected ),
 			ret = [];
 
 		o = o || {};
 
-		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
+		items.each( function() {
+			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
+		} );
 		return ret;
 
@@ -2695,5 +2994,5 @@
 
 	/* Be careful with the following core functions */
-	_intersectsWith: function(item) {
+	_intersectsWith: function( item ) {
 
 		var x1 = this.positionAbs.left,
@@ -2707,52 +3006,65 @@
 			dyClick = this.offset.click.top,
 			dxClick = this.offset.click.left,
-			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
-			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
+			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
+				( y1 + dyClick ) < b ),
+			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
+				( x1 + dxClick ) < r ),
 			isOverElement = isOverElementHeight && isOverElementWidth;
 
 		if ( this.options.tolerance === "pointer" ||
 			this.options.forcePointerForContainers ||
-			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
+			( this.options.tolerance !== "pointer" &&
+				this.helperProportions[ this.floating ? "width" : "height" ] >
+				item[ this.floating ? "width" : "height" ] )
 		) {
 			return isOverElement;
 		} else {
 
-			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
-				x2 - (this.helperProportions.width / 2) < r && // Left Half
-				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
-				y2 - (this.helperProportions.height / 2) < b ); // Top Half
-
-		}
-	},
-
-	_intersectsWithPointer: function(item) {
-
-		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
-			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
-			isOverElement = isOverElementHeight && isOverElementWidth,
+			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
+				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
+				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
+				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
+
+		}
+	},
+
+	_intersectsWithPointer: function( item ) {
+		var verticalDirection, horizontalDirection,
+			isOverElementHeight = ( this.options.axis === "x" ) ||
+				this._isOverAxis(
+					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
+			isOverElementWidth = ( this.options.axis === "y" ) ||
+				this._isOverAxis(
+					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
+			isOverElement = isOverElementHeight && isOverElementWidth;
+
+		if ( !isOverElement ) {
+			return false;
+		}
+
+		verticalDirection = this._getDragVerticalDirection();
+		horizontalDirection = this._getDragHorizontalDirection();
+
+		return this.floating ?
+			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
+			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
+
+	},
+
+	_intersectsWithSides: function( item ) {
+
+		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
+				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
+			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
+				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
 			verticalDirection = this._getDragVerticalDirection(),
 			horizontalDirection = this._getDragHorizontalDirection();
 
-		if (!isOverElement) {
-			return false;
-		}
-
-		return this.floating ?
-			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
-			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
-
-	},
-
-	_intersectsWithSides: function(item) {
-
-		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
-			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
-			verticalDirection = this._getDragVerticalDirection(),
-			horizontalDirection = this._getDragHorizontalDirection();
-
-		if (this.floating && horizontalDirection) {
-			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
+		if ( this.floating && horizontalDirection ) {
+			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
+				( horizontalDirection === "left" && !isOverRightHalf ) );
 		} else {
-			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
+			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
+				( verticalDirection === "up" && !isOverBottomHalf ) );
 		}
 
@@ -2761,14 +3073,14 @@
 	_getDragVerticalDirection: function() {
 		var delta = this.positionAbs.top - this.lastPositionAbs.top;
-		return delta !== 0 && (delta > 0 ? "down" : "up");
+		return delta !== 0 && ( delta > 0 ? "down" : "up" );
 	},
 
 	_getDragHorizontalDirection: function() {
 		var delta = this.positionAbs.left - this.lastPositionAbs.left;
-		return delta !== 0 && (delta > 0 ? "right" : "left");
-	},
-
-	refresh: function(event) {
-		this._refreshItems(event);
+		return delta !== 0 && ( delta > 0 ? "right" : "left" );
+	},
+
+	refresh: function( event ) {
+		this._refreshItems( event );
 		this._setHandleClassName();
 		this.refreshPositions();
@@ -2778,8 +3090,10 @@
 	_connectWith: function() {
 		var options = this.options;
-		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
-	},
-
-	_getItemsAsjQuery: function(connected) {
+		return options.connectWith.constructor === String ?
+			[ options.connectWith ] :
+			options.connectWith;
+	},
+
+	_getItemsAsjQuery: function( connected ) {
 
 		var i, j, cur, inst,
@@ -2788,11 +3102,15 @@
 			connectWith = this._connectWith();
 
-		if(connectWith && connected) {
-			for (i = connectWith.length - 1; i >= 0; i--){
-				cur = $(connectWith[i], this.document[0]);
-				for ( j = cur.length - 1; j >= 0; j--){
-					inst = $.data(cur[j], this.widgetFullName);
-					if(inst && inst !== this && !inst.options.disabled) {
-						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]);
+		if ( connectWith && connected ) {
+			for ( i = connectWith.length - 1; i >= 0; i-- ) {
+				cur = $( connectWith[ i ], this.document[ 0 ] );
+				for ( j = cur.length - 1; j >= 0; j-- ) {
+					inst = $.data( cur[ j ], this.widgetFullName );
+					if ( inst && inst !== this && !inst.options.disabled ) {
+						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 ] );
 					}
 				}
@@ -2800,14 +3118,19 @@
 		}
 
-		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]);
+		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 ] );
 
 		function addItems() {
 			items.push( this );
 		}
-		for (i = queries.length - 1; i >= 0; i--){
-			queries[i][0].each( addItems );
-		}
-
-		return $(items);
+		for ( i = queries.length - 1; i >= 0; i-- ) {
+			queries[ i ][ 0 ].each( addItems );
+		}
+
+		return $( items );
 
 	},
@@ -2815,35 +3138,41 @@
 	_removeCurrentsFromItems: function() {
 
-		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
-
-		this.items = $.grep(this.items, function (item) {
-			for (var j=0; j < list.length; j++) {
-				if(list[j] === item.item[0]) {
+		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
+
+		this.items = $.grep( this.items, function( item ) {
+			for ( var j = 0; j < list.length; j++ ) {
+				if ( list[ j ] === item.item[ 0 ] ) {
 					return false;
 				}
 			}
 			return true;
-		});
-
-	},
-
-	_refreshItems: function(event) {
+		} );
+
+	},
+
+	_refreshItems: function( event ) {
 
 		this.items = [];
-		this.containers = [this];
+		this.containers = [ this ];
 
 		var i, j, cur, inst, targetData, _queries, item, queriesLength,
 			items = this.items,
-			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
+			queries = [ [ $.isFunction( this.options.items ) ?
+				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
+				$( this.options.items, this.element ), this ] ],
 			connectWith = this._connectWith();
 
-		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
-			for (i = connectWith.length - 1; i >= 0; i--){
-				cur = $(connectWith[i], this.document[0]);
-				for (j = cur.length - 1; j >= 0; j--){
-					inst = $.data(cur[j], this.widgetFullName);
-					if(inst && inst !== this && !inst.options.disabled) {
-						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
-						this.containers.push(inst);
+		//Shouldn't be run the first time through due to massive slow-down
+		if ( connectWith && this.ready ) {
+			for ( i = connectWith.length - 1; i >= 0; i-- ) {
+				cur = $( connectWith[ i ], this.document[ 0 ] );
+				for ( j = cur.length - 1; j >= 0; j-- ) {
+					inst = $.data( cur[ j ], this.widgetFullName );
+					if ( inst && inst !== this && !inst.options.disabled ) {
+						queries.push( [ $.isFunction( inst.options.items ) ?
+							inst.options.items
+								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
+							$( inst.options.items, inst.element ), inst ] );
+						this.containers.push( inst );
 					}
 				}
@@ -2851,25 +3180,26 @@
 		}
 
-		for (i = queries.length - 1; i >= 0; i--) {
-			targetData = queries[i][1];
-			_queries = queries[i][0];
-
-			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
-				item = $(_queries[j]);
-
-				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
-
-				items.push({
+		for ( i = queries.length - 1; i >= 0; i-- ) {
+			targetData = queries[ i ][ 1 ];
+			_queries = queries[ i ][ 0 ];
+
+			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
+				item = $( _queries[ j ] );
+
+				// Data for target checking (mouse manager)
+				item.data( this.widgetName + "-item", targetData );
+
+				items.push( {
 					item: item,
 					instance: targetData,
 					width: 0, height: 0,
 					left: 0, top: 0
-				});
-			}
-		}
-
-	},
-
-	refreshPositions: function(fast) {
+				} );
+			}
+		}
+
+	},
+
+	refreshPositions: function( fast ) {
 
 		// Determine whether items are being displayed horizontally
@@ -2878,6 +3208,7 @@
 			false;
 
-		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
-		if(this.offsetParent && this.helper) {
+		//This has to be redone because due to the item being moved out/into the offsetParent,
+		// the offsetParent's position will change
+		if ( this.offsetParent && this.helper ) {
 			this.offset.parent = this._getParentOffset();
 		}
@@ -2885,15 +3216,18 @@
 		var i, item, t, p;
 
-		for (i = this.items.length - 1; i >= 0; i--){
-			item = this.items[i];
+		for ( i = this.items.length - 1; i >= 0; i-- ) {
+			item = this.items[ i ];
 
 			//We ignore calculating positions of all connected containers when we're not over them
-			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
+			if ( item.instance !== this.currentContainer && this.currentContainer &&
+					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
 				continue;
 			}
 
-			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
-
-			if (!fast) {
+			t = this.options.toleranceElement ?
+				$( this.options.toleranceElement, item.item ) :
+				item.item;
+
+			if ( !fast ) {
 				item.width = t.outerWidth();
 				item.height = t.outerHeight();
@@ -2905,13 +3239,15 @@
 		}
 
-		if(this.options.custom && this.options.custom.refreshContainers) {
-			this.options.custom.refreshContainers.call(this);
+		if ( this.options.custom && this.options.custom.refreshContainers ) {
+			this.options.custom.refreshContainers.call( this );
 		} else {
-			for (i = this.containers.length - 1; i >= 0; i--){
-				p = this.containers[i].element.offset();
-				this.containers[i].containerCache.left = p.left;
-				this.containers[i].containerCache.top = p.top;
-				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
-				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+			for ( i = this.containers.length - 1; i >= 0; i-- ) {
+				p = this.containers[ i ].element.offset();
+				this.containers[ i ].containerCache.left = p.left;
+				this.containers[ i ].containerCache.top = p.top;
+				this.containers[ i ].containerCache.width =
+					this.containers[ i ].element.outerWidth();
+				this.containers[ i ].containerCache.height =
+					this.containers[ i ].element.outerHeight();
 			}
 		}
@@ -2920,18 +3256,20 @@
 	},
 
-	_createPlaceholder: function(that) {
+	_createPlaceholder: function( that ) {
 		that = that || this;
 		var className,
 			o = that.options;
 
-		if(!o.placeholder || o.placeholder.constructor === String) {
+		if ( !o.placeholder || o.placeholder.constructor === String ) {
 			className = o.placeholder;
 			o.placeholder = {
 				element: function() {
 
-					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
-						element = $( "<" + nodeName + ">", that.document[0] )
-							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
-							.removeClass("ui-sortable-helper");
+					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
+						element = $( "<" + nodeName + ">", that.document[ 0 ] );
+
+						that._addClass( element, "ui-sortable-placeholder",
+								className || that.currentItem[ 0 ].className )
+							._removeClass( element, "ui-sortable-helper" );
 
 					if ( nodeName === "tbody" ) {
@@ -2952,15 +3290,28 @@
 					return element;
 				},
-				update: function(container, p) {
-
-					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
-					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
-					if(className && !o.forcePlaceholderSize) {
+				update: function( container, p ) {
+
+					// 1. If a className is set as 'placeholder option, we don't force sizes -
+					// the class is responsible for that
+					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
+					// class name is specified
+					if ( className && !o.forcePlaceholderSize ) {
 						return;
 					}
 
-					//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
-					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
-					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
+					//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
+					if ( !p.height() ) {
+						p.height(
+							that.currentItem.innerHeight() -
+							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
+							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
+					}
+					if ( !p.width() ) {
+						p.width(
+							that.currentItem.innerWidth() -
+							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
+							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
+					}
 				}
 			};
@@ -2968,11 +3319,11 @@
 
 		//Create the placeholder
-		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
+		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
 
 		//Append it after the actual current item
-		that.currentItem.after(that.placeholder);
+		that.currentItem.after( that.placeholder );
 
 		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
-		o.placeholder.update(that, that.placeholder);
+		o.placeholder.update( that, that.placeholder );
 
 	},
@@ -2981,74 +3332,82 @@
 		var that = this;
 
-		sourceTr.children().each(function() {
+		sourceTr.children().each( function() {
 			$( "<td>&#160;</td>", that.document[ 0 ] )
 				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
 				.appendTo( targetTr );
-		});
-	},
-
-	_contactContainers: function(event) {
-		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
+		} );
+	},
+
+	_contactContainers: function( event ) {
+		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
+			floating, axis,
 			innermostContainer = null,
 			innermostIndex = null;
 
-		// get innermost container that intersects with item
-		for (i = this.containers.length - 1; i >= 0; i--) {
-
-			// never consider a container that's located within the item itself
-			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
+		// Get innermost container that intersects with item
+		for ( i = this.containers.length - 1; i >= 0; i-- ) {
+
+			// Never consider a container that's located within the item itself
+			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
 				continue;
 			}
 
-			if(this._intersectsWith(this.containers[i].containerCache)) {
-
-				// if we've already found a container and it's more "inner" than this, then continue
-				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
+			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
+
+				// If we've already found a container and it's more "inner" than this, then continue
+				if ( innermostContainer &&
+						$.contains(
+							this.containers[ i ].element[ 0 ],
+							innermostContainer.element[ 0 ] ) ) {
 					continue;
 				}
 
-				innermostContainer = this.containers[i];
+				innermostContainer = this.containers[ i ];
 				innermostIndex = i;
 
 			} else {
+
 				// container doesn't intersect. trigger "out" event if necessary
-				if(this.containers[i].containerCache.over) {
-					this.containers[i]._trigger("out", event, this._uiHash(this));
-					this.containers[i].containerCache.over = 0;
-				}
-			}
-
-		}
-
-		// if no intersecting containers found, return
-		if(!innermostContainer) {
+				if ( this.containers[ i ].containerCache.over ) {
+					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
+					this.containers[ i ].containerCache.over = 0;
+				}
+			}
+
+		}
+
+		// If no intersecting containers found, return
+		if ( !innermostContainer ) {
 			return;
 		}
 
-		// move the item into the container if it's not there already
-		if(this.containers.length === 1) {
-			if (!this.containers[innermostIndex].containerCache.over) {
-				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
-				this.containers[innermostIndex].containerCache.over = 1;
+		// Move the item into the container if it's not there already
+		if ( this.containers.length === 1 ) {
+			if ( !this.containers[ innermostIndex ].containerCache.over ) {
+				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
+				this.containers[ innermostIndex ].containerCache.over = 1;
 			}
 		} else {
 
-			//When entering a new container, we will find the item with the least distance and append our item near it
+			// When entering a new container, we will find the item with the least distance and
+			// append our item near it
 			dist = 10000;
 			itemWithLeastDistance = null;
-			floating = innermostContainer.floating || this._isFloating(this.currentItem);
+			floating = innermostContainer.floating || this._isFloating( this.currentItem );
 			posProperty = floating ? "left" : "top";
 			sizeProperty = floating ? "width" : "height";
-			axis = floating ? "clientX" : "clientY";
-
-			for (j = this.items.length - 1; j >= 0; j--) {
-				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
+			axis = floating ? "pageX" : "pageY";
+
+			for ( j = this.items.length - 1; j >= 0; j-- ) {
+				if ( !$.contains(
+						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
+				) {
 					continue;
 				}
-				if(this.items[j].item[0] === this.currentItem[0]) {
+				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
 					continue;
 				}
 
-				cur = this.items[j].item.offset()[posProperty];
+				cur = this.items[ j ].item.offset()[ posProperty ];
 				nearBottom = false;
 				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
@@ -3059,14 +3418,14 @@
 					dist = Math.abs( event[ axis ] - cur );
 					itemWithLeastDistance = this.items[ j ];
-					this.direction = nearBottom ? "up": "down";
+					this.direction = nearBottom ? "up" : "down";
 				}
 			}
 
 			//Check if dropOnEmpty is enabled
-			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
+			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
 				return;
 			}
 
-			if(this.currentContainer === this.containers[innermostIndex]) {
+			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
 				if ( !this.currentContainer.containerCache.over ) {
 					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
@@ -3076,38 +3435,49 @@
 			}
 
-			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
-			this._trigger("change", event, this._uiHash());
-			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
-			this.currentContainer = this.containers[innermostIndex];
+			itemWithLeastDistance ?
+				this._rearrange( event, itemWithLeastDistance, null, true ) :
+				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
+			this._trigger( "change", event, this._uiHash() );
+			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
+			this.currentContainer = this.containers[ innermostIndex ];
 
 			//Update the placeholder
-			this.options.placeholder.update(this.currentContainer, this.placeholder);
-
-			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
-			this.containers[innermostIndex].containerCache.over = 1;
-		}
-
-
-	},
-
-	_createHelper: function(event) {
+			this.options.placeholder.update( this.currentContainer, this.placeholder );
+
+			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
+			this.containers[ innermostIndex ].containerCache.over = 1;
+		}
+
+	},
+
+	_createHelper: function( event ) {
 
 		var o = this.options,
-			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
+			helper = $.isFunction( o.helper ) ?
+				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
+				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
 
 		//Add the helper to the DOM if that didn't happen already
-		if(!helper.parents("body").length) {
-			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
-		}
-
-		if(helper[0] === this.currentItem[0]) {
-			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") };
-		}
-
-		if(!helper[0].style.width || o.forceHelperSize) {
-			helper.width(this.currentItem.width());
-		}
-		if(!helper[0].style.height || o.forceHelperSize) {
-			helper.height(this.currentItem.height());
+		if ( !helper.parents( "body" ).length ) {
+			$( o.appendTo !== "parent" ?
+				o.appendTo :
+				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
+		}
+
+		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
+			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" )
+			};
+		}
+
+		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
+			helper.width( this.currentItem.width() );
+		}
+		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
+			helper.height( this.currentItem.height() );
 		}
 
@@ -3116,21 +3486,21 @@
 	},
 
-	_adjustOffsetFromHelper: function(obj) {
-		if (typeof obj === "string") {
-			obj = obj.split(" ");
-		}
-		if ($.isArray(obj)) {
-			obj = {left: +obj[0], top: +obj[1] || 0};
-		}
-		if ("left" in obj) {
+	_adjustOffsetFromHelper: function( obj ) {
+		if ( typeof obj === "string" ) {
+			obj = obj.split( " " );
+		}
+		if ( $.isArray( obj ) ) {
+			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
+		}
+		if ( "left" in obj ) {
 			this.offset.click.left = obj.left + this.margins.left;
 		}
-		if ("right" in obj) {
+		if ( "right" in obj ) {
 			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
 		}
-		if ("top" in obj) {
+		if ( "top" in obj ) {
 			this.offset.click.top = obj.top + this.margins.top;
 		}
-		if ("bottom" in obj) {
+		if ( "bottom" in obj ) {
 			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
 		}
@@ -3138,5 +3508,4 @@
 
 	_getParentOffset: function() {
-
 
 		//Get the offsetParent and cache its position
@@ -3144,22 +3513,28 @@
 		var po = this.offsetParent.offset();
 
-		// This is a special case where we need to modify a offset calculated on start, since the following happened:
-		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
-		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
-		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
-		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+		// This is a special case where we need to modify a offset calculated on start, since the
+		// following happened:
+		// 1. The position of the helper is absolute, so it's position is calculated based on the
+		// next positioned parent
+		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
+		// the document, which means that the scroll is included in the initial calculation of the
+		// offset of the parent, and never recalculated upon drag
+		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
 			po.left += this.scrollParent.scrollLeft();
 			po.top += this.scrollParent.scrollTop();
 		}
 
-		// This needs to be actually done for all browsers, since pageX/pageY includes this information
-		// with an ugly IE fix
-		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+		// This needs to be actually done for all browsers, since pageX/pageY includes this
+		// information with an ugly IE fix
+		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
+				( this.offsetParent[ 0 ].tagName &&
+				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
 			po = { top: 0, left: 0 };
 		}
 
 		return {
-			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
-			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
+			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
 		};
 
@@ -3168,9 +3543,11 @@
 	_getRelativeOffset: function() {
 
-		if(this.cssPosition === "relative") {
+		if ( this.cssPosition === "relative" ) {
 			var p = this.currentItem.position();
 			return {
-				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
-				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
+					this.scrollParent.scrollTop(),
+				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
+					this.scrollParent.scrollLeft()
 			};
 		} else {
@@ -3182,6 +3559,6 @@
 	_cacheMargins: function() {
 		this.margins = {
-			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
-			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
+			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
 		};
 	},
@@ -3198,26 +3575,39 @@
 		var ce, co, over,
 			o = this.options;
-		if(o.containment === "parent") {
-			o.containment = this.helper[0].parentNode;
-		}
-		if(o.containment === "document" || o.containment === "window") {
+		if ( o.containment === "parent" ) {
+			o.containment = this.helper[ 0 ].parentNode;
+		}
+		if ( o.containment === "document" || o.containment === "window" ) {
 			this.containment = [
 				0 - this.offset.relative.left - this.offset.parent.left,
 				0 - this.offset.relative.top - this.offset.parent.top,
-				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
-				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+				o.containment === "document" ?
+					this.document.width() :
+					this.window.width() - this.helperProportions.width - this.margins.left,
+				( o.containment === "document" ?
+					( this.document.height() || document.body.parentNode.scrollHeight ) :
+					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
+				) - this.helperProportions.height - this.margins.top
 			];
 		}
 
-		if(!(/^(document|window|parent)$/).test(o.containment)) {
-			ce = $(o.containment)[0];
-			co = $(o.containment).offset();
-			over = ($(ce).css("overflow") !== "hidden");
+		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
+			ce = $( o.containment )[ 0 ];
+			co = $( o.containment ).offset();
+			over = ( $( ce ).css( "overflow" ) !== "hidden" );
 
 			this.containment = [
-				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
-				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
-				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,
-				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
+				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
+					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
+				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
+					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
+				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,
+				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
 			];
 		}
@@ -3225,25 +3615,45 @@
 	},
 
-	_convertPositionTo: function(d, pos) {
-
-		if(!pos) {
+	_convertPositionTo: function( d, pos ) {
+
+		if ( !pos ) {
 			pos = this.position;
 		}
 		var mod = d === "absolute" ? 1 : -1,
-			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
-			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+			scroll = this.cssPosition === "absolute" &&
+				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
+					this.offsetParent :
+					this.scrollParent,
+			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
 
 		return {
 			top: (
-				pos.top	+																// The absolute mouse position
-				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+
+				// The absolute mouse position
+				pos.top	+
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top * mod -
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollTop() :
+					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
 			),
 			left: (
-				pos.left +																// The absolute mouse position
-				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+
+				// The absolute mouse position
+				pos.left +
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left * mod +
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left * mod	-
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
+					scroll.scrollLeft() ) * mod )
 			)
 		};
@@ -3251,5 +3661,5 @@
 	},
 
-	_generatePosition: function(event) {
+	_generatePosition: function( event ) {
 
 		var top, left,
@@ -3257,5 +3667,10 @@
 			pageX = event.pageX,
 			pageY = event.pageY,
-			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+			scroll = this.cssPosition === "absolute" &&
+				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
+					this.offsetParent :
+					this.scrollParent,
+				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
 
 		// This is another very weird special case that only happens for relative elements:
@@ -3263,5 +3678,6 @@
 		// 2. and the scroll parent is the document or similar to the offset parent
 		// we have to refresh the relative offset during the scroll so there are no jumps
-		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
+		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
+				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
 			this.offset.relative = this._getRelativeOffset();
 		}
@@ -3272,27 +3688,41 @@
 		 */
 
-		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
-
-			if(this.containment) {
-				if(event.pageX - this.offset.click.left < this.containment[0]) {
-					pageX = this.containment[0] + this.offset.click.left;
-				}
-				if(event.pageY - this.offset.click.top < this.containment[1]) {
-					pageY = this.containment[1] + this.offset.click.top;
-				}
-				if(event.pageX - this.offset.click.left > this.containment[2]) {
-					pageX = this.containment[2] + this.offset.click.left;
-				}
-				if(event.pageY - this.offset.click.top > this.containment[3]) {
-					pageY = this.containment[3] + this.offset.click.top;
-				}
-			}
-
-			if(o.grid) {
-				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
-				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;
-
-				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
-				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;
+		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
+
+			if ( this.containment ) {
+				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
+					pageX = this.containment[ 0 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
+					pageY = this.containment[ 1 ] + this.offset.click.top;
+				}
+				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
+					pageX = this.containment[ 2 ] + this.offset.click.left;
+				}
+				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
+					pageY = this.containment[ 3 ] + this.offset.click.top;
+				}
+			}
+
+			if ( o.grid ) {
+				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
+					o.grid[ 1 ] ) * o.grid[ 1 ];
+				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;
+
+				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
+					o.grid[ 0 ] ) * o.grid[ 0 ];
+				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;
 			}
 
@@ -3301,16 +3731,36 @@
 		return {
 			top: (
-				pageY -																// The absolute mouse position
-				this.offset.click.top -													// Click offset (relative to the element)
-				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+
+				// The absolute mouse position
+				pageY -
+
+				// Click offset (relative to the element)
+				this.offset.click.top -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.top -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.top +
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollTop() :
+					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
 			),
 			left: (
-				pageX -																// The absolute mouse position
-				this.offset.click.left -												// Click offset (relative to the element)
-				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
-				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+
+				// The absolute mouse position
+				pageX -
+
+				// Click offset (relative to the element)
+				this.offset.click.left -
+
+				// Only for relative positioned nodes: Relative offset from element to offset parent
+				this.offset.relative.left -
+
+				// The offsetParent's offset without borders (offset + border)
+				this.offset.parent.left +
+				( ( this.cssPosition === "fixed" ?
+					-this.scrollParent.scrollLeft() :
+					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
 			)
 		};
@@ -3318,67 +3768,93 @@
 	},
 
-	_rearrange: function(event, i, a, hardRefresh) {
-
-		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));
+	_rearrange: function( event, i, a, hardRefresh ) {
+
+		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 ) );
 
 		//Various things done here to improve the performance:
 		// 1. we create a setTimeout, that calls refreshPositions
 		// 2. on the instance, we have a counter variable, that get's higher after every append
-		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+		// 3. on the local scope, we copy the counter variable, and check in the timeout,
+		// if it's still the same
 		// 4. this lets only the last addition to the timeout stack through
 		this.counter = this.counter ? ++this.counter : 1;
 		var counter = this.counter;
 
-		this._delay(function() {
-			if(counter === this.counter) {
-				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
-			}
-		});
-
-	},
-
-	_clear: function(event, noPropagation) {
+		this._delay( function() {
+			if ( counter === this.counter ) {
+
+				//Precompute after each DOM insertion, NOT on mousemove
+				this.refreshPositions( !hardRefresh );
+			}
+		} );
+
+	},
+
+	_clear: function( event, noPropagation ) {
 
 		this.reverting = false;
-		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
-		// everything else normalized again
+
+		// We delay all events that have to be triggered to after the point where the placeholder
+		// has been removed and everything else normalized again
 		var i,
 			delayedTriggers = [];
 
 		// We first have to update the dom position of the actual currentItem
-		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
-		if(!this._noFinalSort && this.currentItem.parent().length) {
-			this.placeholder.before(this.currentItem);
+		// Note: don't do it if the current item is already removed (by a user), or it gets
+		// reappended (see #4088)
+		if ( !this._noFinalSort && this.currentItem.parent().length ) {
+			this.placeholder.before( this.currentItem );
 		}
 		this._noFinalSort = null;
 
-		if(this.helper[0] === this.currentItem[0]) {
-			for(i in this._storedCSS) {
-				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
-					this._storedCSS[i] = "";
-				}
-			}
-			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
+			for ( i in this._storedCSS ) {
+				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
+					this._storedCSS[ i ] = "";
+				}
+			}
+			this.currentItem.css( this._storedCSS );
+			this._removeClass( this.currentItem, "ui-sortable-helper" );
 		} else {
 			this.currentItem.show();
 		}
 
-		if(this.fromOutside && !noPropagation) {
-			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
-		}
-		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
-			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+		if ( this.fromOutside && !noPropagation ) {
+			delayedTriggers.push( function( event ) {
+				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
+			} );
+		}
+		if ( ( this.fromOutside ||
+				this.domPosition.prev !==
+				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
+				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
+
+			// Trigger update callback if the DOM position has changed
+			delayedTriggers.push( function( event ) {
+				this._trigger( "update", event, this._uiHash() );
+			} );
 		}
 
 		// Check if the items Container has Changed and trigger appropriate
 		// events.
-		if (this !== this.currentContainer) {
-			if(!noPropagation) {
-				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
-				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
-				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
-			}
-		}
-
+		if ( this !== this.currentContainer ) {
+			if ( !noPropagation ) {
+				delayedTriggers.push( function( event ) {
+					this._trigger( "remove", event, this._uiHash() );
+				} );
+				delayedTriggers.push( ( function( c ) {
+					return function( event ) {
+						c._trigger( "receive", event, this._uiHash( this ) );
+					};
+				} ).call( this, this.currentContainer ) );
+				delayedTriggers.push( ( function( c ) {
+					return function( event ) {
+						c._trigger( "update", event, this._uiHash( this ) );
+					};
+				} ).call( this, this.currentContainer ) );
+			}
+		}
 
 		//Post events to containers
@@ -3388,11 +3864,11 @@
 			};
 		}
-		for (i = this.containers.length - 1; i >= 0; i--){
-			if (!noPropagation) {
+		for ( i = this.containers.length - 1; i >= 0; i-- ) {
+			if ( !noPropagation ) {
 				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
 			}
-			if(this.containers[i].containerCache.over) {
+			if ( this.containers[ i ].containerCache.over ) {
 				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
-				this.containers[i].containerCache.over = 0;
+				this.containers[ i ].containerCache.over = 0;
 			}
 		}
@@ -3403,19 +3879,20 @@
 			this.storedStylesheet.remove();
 		}
-		if(this._storedOpacity) {
-			this.helper.css("opacity", this._storedOpacity);
-		}
-		if(this._storedZIndex) {
-			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
+		if ( this._storedOpacity ) {
+			this.helper.css( "opacity", this._storedOpacity );
+		}
+		if ( this._storedZIndex ) {
+			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
 		}
 
 		this.dragging = false;
 
-		if(!noPropagation) {
-			this._trigger("beforeStop", event, this._uiHash());
-		}
-
-		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
-		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+		if ( !noPropagation ) {
+			this._trigger( "beforeStop", event, this._uiHash() );
+		}
+
+		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
+		// it unbinds ALL events from the original node!
+		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
 
 		if ( !this.cancelHelperRemoval ) {
@@ -3426,9 +3903,11 @@
 		}
 
-		if(!noPropagation) {
-			for (i=0; i < delayedTriggers.length; i++) {
-				delayedTriggers[i].call(this, event);
-			} //Trigger all delayed events
-			this._trigger("stop", event, this._uiHash());
+		if ( !noPropagation ) {
+			for ( i = 0; i < delayedTriggers.length; i++ ) {
+
+				// Trigger all delayed events
+				delayedTriggers[ i ].call( this, event );
+			}
+			this._trigger( "stop", event, this._uiHash() );
 		}
 
@@ -3439,14 +3918,14 @@
 
 	_trigger: function() {
-		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
 			this.cancel();
 		}
 	},
 
-	_uiHash: function(_inst) {
+	_uiHash: function( _inst ) {
 		var inst = _inst || this;
 		return {
 			helper: inst.helper,
-			placeholder: inst.placeholder || $([]),
+			placeholder: inst.placeholder || $( [] ),
 			position: inst.position,
 			originalPosition: inst.originalPosition,
@@ -3457,9 +3936,9 @@
 	}
 
-});
+} );
 
 
 /*!
- * jQuery UI Accordion 1.11.4
+ * jQuery UI Accordion 1.12.1
  * http://jqueryui.com
  *
@@ -3467,17 +3946,32 @@
  * Released under the MIT license.
  * http://jquery.org/license
- *
- * http://api.jqueryui.com/accordion/
  */
 
-
-var accordion = $.widget( "ui.accordion", {
-	version: "1.11.4",
+//>>label: Accordion
+//>>group: Widgets
+// jscs:disable maximumLineLength
+//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
+// jscs:enable maximumLineLength
+//>>docs: http://api.jqueryui.com/accordion/
+//>>demos: http://jqueryui.com/accordion/
+//>>css.structure: ../../themes/base/core.css
+//>>css.structure: ../../themes/base/accordion.css
+//>>css.theme: ../../themes/base/theme.css
+
+
+
+var widgetsAccordion = $.widget( "ui.accordion", {
+	version: "1.12.1",
 	options: {
 		active: 0,
 		animate: {},
+		classes: {
+			"ui-accordion-header": "ui-corner-top",
+			"ui-accordion-header-collapsed": "ui-corner-all",
+			"ui-accordion-content": "ui-corner-bottom"
+		},
 		collapsible: false,
 		event: "click",
-		header: "> li > :first-child,> :not(li):even",
+		header: "> li > :first-child, > :not(li):even",
 		heightStyle: "auto",
 		icons: {
@@ -3486,5 +3980,5 @@
 		},
 
-		// callbacks
+		// Callbacks
 		activate: null,
 		beforeActivate: null
@@ -3509,15 +4003,16 @@
 	_create: function() {
 		var options = this.options;
+
 		this.prevShow = this.prevHide = $();
-		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
-			// ARIA
-			.attr( "role", "tablist" );
-
-		// don't allow collapsible: false and active: false / null
-		if ( !options.collapsible && (options.active === false || options.active == null) ) {
+		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
+		this.element.attr( "role", "tablist" );
+
+		// Don't allow collapsible: false and active: false / null
+		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
 			options.active = 0;
 		}
 
 		this._processPanels();
+
 		// handle negative values
 		if ( options.active < 0 ) {
@@ -3535,21 +4030,21 @@
 
 	_createIcons: function() {
-		var icons = this.options.icons;
+		var icon, children,
+			icons = this.options.icons;
+
 		if ( icons ) {
-			$( "<span>" )
-				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
-				.prependTo( this.headers );
-			this.active.children( ".ui-accordion-header-icon" )
-				.removeClass( icons.header )
-				.addClass( icons.activeHeader );
-			this.headers.addClass( "ui-accordion-icons" );
+			icon = $( "<span>" );
+			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
+			icon.prependTo( this.headers );
+			children = this.active.children( ".ui-accordion-header-icon" );
+			this._removeClass( children, icons.header )
+				._addClass( children, null, icons.activeHeader )
+				._addClass( this.headers, "ui-accordion-icons" );
 		}
 	},
 
 	_destroyIcons: function() {
-		this.headers
-			.removeClass( "ui-accordion-icons" )
-			.children( ".ui-accordion-header-icon" )
-				.remove();
+		this._removeClass( this.headers, "ui-accordion-icons" );
+		this.headers.children( ".ui-accordion-header-icon" ).remove();
 	},
 
@@ -3557,30 +4052,18 @@
 		var contents;
 
-		// clean up main element
-		this.element
-			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
-			.removeAttr( "role" );
-
-		// clean up headers
+		// Clean up main element
+		this.element.removeAttr( "role" );
+
+		// Clean up headers
 		this.headers
-			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
-				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
-			.removeAttr( "role" )
-			.removeAttr( "aria-expanded" )
-			.removeAttr( "aria-selected" )
-			.removeAttr( "aria-controls" )
-			.removeAttr( "tabIndex" )
+			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
 			.removeUniqueId();
 
 		this._destroyIcons();
 
-		// clean up content panels
+		// Clean up content panels
 		contents = this.headers.next()
-			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
-				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
 			.css( "display", "" )
-			.removeAttr( "role" )
-			.removeAttr( "aria-hidden" )
-			.removeAttr( "aria-labelledby" )
+			.removeAttr( "role aria-hidden aria-labelledby" )
 			.removeUniqueId();
 
@@ -3592,4 +4075,5 @@
 	_setOption: function( key, value ) {
 		if ( key === "active" ) {
+
 			// _activate() will handle invalid values and update this.options
 			this._activate( value );
@@ -3606,5 +4090,5 @@
 		this._super( key, value );
 
-		// setting collapsible: false while collapsed; open first panel
+		// Setting collapsible: false while collapsed; open first panel
 		if ( key === "collapsible" && !value && this.options.active === false ) {
 			this._activate( 0 );
@@ -3617,14 +4101,17 @@
 			}
 		}
-
-		// #5332 - opacity doesn't cascade to positioned elements in IE
+	},
+
+	_setOptionDisabled: function( value ) {
+		this._super( value );
+
+		this.element.attr( "aria-disabled", value );
+
+		// Support: IE8 Only
+		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
 		// so we need to add the disabled class to the headers and panels
-		if ( key === "disabled" ) {
-			this.element
-				.toggleClass( "ui-state-disabled", !!value )
-				.attr( "aria-disabled", value );
-			this.headers.add( this.headers.next() )
-				.toggleClass( "ui-state-disabled", !!value );
-		}
+		this._toggleClass( null, "ui-state-disabled", !!value );
+		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
+			!!value );
 	},
 
@@ -3640,22 +4127,22 @@
 
 		switch ( event.keyCode ) {
-			case keyCode.RIGHT:
-			case keyCode.DOWN:
-				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
-				break;
-			case keyCode.LEFT:
-			case keyCode.UP:
-				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
-				break;
-			case keyCode.SPACE:
-			case keyCode.ENTER:
-				this._eventHandler( event );
-				break;
-			case keyCode.HOME:
-				toFocus = this.headers[ 0 ];
-				break;
-			case keyCode.END:
-				toFocus = this.headers[ length - 1 ];
-				break;
+		case keyCode.RIGHT:
+		case keyCode.DOWN:
+			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+			break;
+		case keyCode.LEFT:
+		case keyCode.UP:
+			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+			break;
+		case keyCode.SPACE:
+		case keyCode.ENTER:
+			this._eventHandler( event );
+			break;
+		case keyCode.HOME:
+			toFocus = this.headers[ 0 ];
+			break;
+		case keyCode.END:
+			toFocus = this.headers[ length - 1 ];
+			break;
 		}
 
@@ -3663,5 +4150,5 @@
 			$( event.target ).attr( "tabIndex", -1 );
 			$( toFocus ).attr( "tabIndex", 0 );
-			toFocus.focus();
+			$( toFocus ).trigger( "focus" );
 			event.preventDefault();
 		}
@@ -3670,5 +4157,5 @@
 	_panelKeyDown: function( event ) {
 		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
-			$( event.currentTarget ).prev().focus();
+			$( event.currentTarget ).prev().trigger( "focus" );
 		}
 	},
@@ -3678,23 +4165,30 @@
 		this._processPanels();
 
-		// was collapsed or no panel
-		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
+		// Was collapsed or no panel
+		if ( ( options.active === false && options.collapsible === true ) ||
+				!this.headers.length ) {
 			options.active = false;
 			this.active = $();
+
 		// active false only when collapsible is true
 		} else if ( options.active === false ) {
 			this._activate( 0 );
+
 		// was active, but active panel is gone
 		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
+
 			// all remaining panel are disabled
-			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
+			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
 				options.active = false;
 				this.active = $();
+
 			// activate previous panel
 			} else {
 				this._activate( Math.max( 0, options.active - 1 ) );
 			}
+
 		// was active, active panel still exists
 		} else {
+
 			// make sure active index is correct
 			options.active = this.headers.index( this.active );
@@ -3710,11 +4204,10 @@
 			prevPanels = this.panels;
 
-		this.headers = this.element.find( this.options.header )
-			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );
-
-		this.panels = this.headers.next()
-			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
-			.filter( ":not(.ui-accordion-content-active)" )
-			.hide();
+		this.headers = this.element.find( this.options.header );
+		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
+			"ui-state-default" );
+
+		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
+		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
 
 		// Avoid memory leaks (#10056)
@@ -3731,14 +4224,13 @@
 			parent = this.element.parent();
 
-		this.active = this._findActive( options.active )
-			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
-			.removeClass( "ui-corner-all" );
-		this.active.next()
-			.addClass( "ui-accordion-content-active" )
-			.show();
+		this.active = this._findActive( options.active );
+		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
+			._removeClass( this.active, "ui-accordion-header-collapsed" );
+		this._addClass( this.active.next(), "ui-accordion-content-active" );
+		this.active.next().show();
 
 		this.headers
 			.attr( "role", "tab" )
-			.each(function() {
+			.each( function() {
 				var header = $( this ),
 					headerId = header.uniqueId().attr( "id" ),
@@ -3747,5 +4239,5 @@
 				header.attr( "aria-controls", panelId );
 				panel.attr( "aria-labelledby", headerId );
-			})
+			} )
 			.next()
 				.attr( "role", "tabpanel" );
@@ -3753,28 +4245,28 @@
 		this.headers
 			.not( this.active )
-			.attr({
-				"aria-selected": "false",
-				"aria-expanded": "false",
-				tabIndex: -1
-			})
-			.next()
-				.attr({
-					"aria-hidden": "true"
-				})
-				.hide();
-
-		// make sure at least one header is in the tab order
+				.attr( {
+					"aria-selected": "false",
+					"aria-expanded": "false",
+					tabIndex: -1
+				} )
+				.next()
+					.attr( {
+						"aria-hidden": "true"
+					} )
+					.hide();
+
+		// Make sure at least one header is in the tab order
 		if ( !this.active.length ) {
 			this.headers.eq( 0 ).attr( "tabIndex", 0 );
 		} else {
-			this.active.attr({
+			this.active.attr( {
 				"aria-selected": "true",
 				"aria-expanded": "true",
 				tabIndex: 0
-			})
-			.next()
-				.attr({
-					"aria-hidden": "false"
-				});
+			} )
+				.next()
+					.attr( {
+						"aria-hidden": "false"
+					} );
 		}
 
@@ -3785,5 +4277,5 @@
 		if ( heightStyle === "fill" ) {
 			maxHeight = parent.height();
-			this.element.siblings( ":visible" ).each(function() {
+			this.element.siblings( ":visible" ).each( function() {
 				var elem = $( this ),
 					position = elem.css( "position" );
@@ -3793,22 +4285,29 @@
 				}
 				maxHeight -= elem.outerHeight( true );
-			});
-
-			this.headers.each(function() {
+			} );
+
+			this.headers.each( function() {
 				maxHeight -= $( this ).outerHeight( true );
-			});
+			} );
 
 			this.headers.next()
-				.each(function() {
+				.each( function() {
 					$( this ).height( Math.max( 0, maxHeight -
 						$( this ).innerHeight() + $( this ).height() ) );
-				})
+				} )
 				.css( "overflow", "auto" );
 		} else if ( heightStyle === "auto" ) {
 			maxHeight = 0;
 			this.headers.next()
-				.each(function() {
+				.each( function() {
+					var isVisible = $( this ).is( ":visible" );
+					if ( !isVisible ) {
+						$( this ).show();
+					}
 					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
-				})
+					if ( !isVisible ) {
+						$( this ).hide();
+					}
+				} )
 				.height( maxHeight );
 		}
@@ -3818,17 +4317,17 @@
 		var active = this._findActive( index )[ 0 ];
 
-		// trying to activate the already active panel
+		// Trying to activate the already active panel
 		if ( active === this.active[ 0 ] ) {
 			return;
 		}
 
-		// trying to collapse, simulate a click on the currently active header
+		// Trying to collapse, simulate a click on the currently active header
 		active = active || this.active[ 0 ];
 
-		this._eventHandler({
+		this._eventHandler( {
 			target: active,
 			currentTarget: active,
 			preventDefault: $.noop
-		});
+		} );
 	},
 
@@ -3844,10 +4343,10 @@
 			$.each( event.split( " " ), function( index, eventName ) {
 				events[ eventName ] = "_eventHandler";
-			});
+			} );
 		}
 
 		this._off( this.headers.add( this.headers.next() ) );
 		this._on( this.headers, events );
-		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
+		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
 		this._hoverable( this.headers );
 		this._focusable( this.headers );
@@ -3855,5 +4354,6 @@
 
 	_eventHandler: function( event ) {
-		var options = this.options,
+		var activeChildren, clickedChildren,
+			options = this.options,
 			active = this.active,
 			clicked = $( event.currentTarget ),
@@ -3872,6 +4372,8 @@
 
 		if (
+
 				// click on active header, but not collapsible
 				( clickedIsActive && !options.collapsible ) ||
+
 				// allow canceling activation
 				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
@@ -3881,31 +4383,28 @@
 		options.active = collapsing ? false : this.headers.index( clicked );
 
-		// when the call to ._toggle() comes after the class changes
+		// When the call to ._toggle() comes after the class changes
 		// it causes a very odd bug in IE 8 (see #6720)
 		this.active = clickedIsActive ? $() : clicked;
 		this._toggle( eventData );
 
-		// switch classes
+		// Switch classes
 		// corner classes on the previously active header stay after the animation
-		active.removeClass( "ui-accordion-header-active ui-state-active" );
+		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
 		if ( options.icons ) {
-			active.children( ".ui-accordion-header-icon" )
-				.removeClass( options.icons.activeHeader )
-				.addClass( options.icons.header );
+			activeChildren = active.children( ".ui-accordion-header-icon" );
+			this._removeClass( activeChildren, null, options.icons.activeHeader )
+				._addClass( activeChildren, null, options.icons.header );
 		}
 
 		if ( !clickedIsActive ) {
-			clicked
-				.removeClass( "ui-corner-all" )
-				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
+			this._removeClass( clicked, "ui-accordion-header-collapsed" )
+				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
 			if ( options.icons ) {
-				clicked.children( ".ui-accordion-header-icon" )
-					.removeClass( options.icons.header )
-					.addClass( options.icons.activeHeader );
-			}
-
-			clicked
-				.next()
-				.addClass( "ui-accordion-content-active" );
+				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
+				this._removeClass( clickedChildren, null, options.icons.header )
+					._addClass( clickedChildren, null, options.icons.activeHeader );
+			}
+
+			this._addClass( clicked.next(), "ui-accordion-content-active" );
 		}
 	},
@@ -3915,5 +4414,5 @@
 			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
 
-		// handle activating a panel during the animation for another activation
+		// Handle activating a panel during the animation for another activation
 		this.prevShow.add( this.prevHide ).stop( true, true );
 		this.prevShow = toShow;
@@ -3928,24 +4427,25 @@
 		}
 
-		toHide.attr({
+		toHide.attr( {
 			"aria-hidden": "true"
-		});
-		toHide.prev().attr({
+		} );
+		toHide.prev().attr( {
 			"aria-selected": "false",
 			"aria-expanded": "false"
-		});
+		} );
+
 		// if we're switching panels, remove the old header from the tab order
 		// if we're opening from collapsed state, remove the previous header from the tab order
 		// if we're collapsing, then keep the collapsing header in the tab order
 		if ( toShow.length && toHide.length ) {
-			toHide.prev().attr({
+			toHide.prev().attr( {
 				"tabIndex": -1,
 				"aria-expanded": "false"
-			});
+			} );
 		} else if ( toShow.length ) {
-			this.headers.filter(function() {
+			this.headers.filter( function() {
 				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
-			})
-			.attr( "tabIndex", -1 );
+			} )
+				.attr( "tabIndex", -1 );
 		}
 
@@ -3953,9 +4453,9 @@
 			.attr( "aria-hidden", "false" )
 			.prev()
-				.attr({
+				.attr( {
 					"aria-selected": "true",
 					"aria-expanded": "true",
 					tabIndex: 0
-				});
+				} );
 	},
 
@@ -3979,4 +4479,5 @@
 			easing = options;
 		}
+
 		// fall back from options to animation in case of partial down settings
 		easing = easing || options.easing || animate.easing;
@@ -3997,5 +4498,5 @@
 				fx.now = Math.round( now );
 			}
-		});
+		} );
 		toShow
 			.hide()
@@ -4015,15 +4516,14 @@
 					}
 				}
-			});
+			} );
 	},
 
 	_toggleComplete: function( data ) {
-		var toHide = data.oldPanel;
-
-		toHide
-			.removeClass( "ui-accordion-content-active" )
-			.prev()
-				.removeClass( "ui-corner-top" )
-				.addClass( "ui-corner-all" );
+		var toHide = data.oldPanel,
+			prev = toHide.prev();
+
+		this._removeClass( toHide, "ui-accordion-content-active" );
+		this._removeClass( prev, "ui-accordion-header-active" )
+			._addClass( prev, "ui-accordion-header-collapsed" );
 
 		// Work around for rendering bug in IE (#5421)
@@ -4033,5 +4533,6 @@
 		this._trigger( "activate", null, data );
 	}
-});
+} );
+
 
 
Index: dmin/js/jquery/jquery.bgFade.js
===================================================================
--- admin/js/jquery/jquery.bgFade.js	(revision 0)
+++ 	(revision )
@@ -1,70 +1,0 @@
-jQuery.fn.backgroundFade = function(s,callback) {
-	var defaults = {
-		sColor: [255,0,0],
-		eColor: [255,255,255],
-		fColor: null,
-		steps: 200,
-		intervals: 5,
-		powr: 4
-	},
-	
-	params = jQuery.extend(defaults,s);
-	
-	return this.each(function() {
-		this.bgFade_sColor = jQuery.backgroundFade.parseHexColor(params.sColor);
-		this.bgFade_eColor = jQuery.backgroundFade.parseHexColor(params.eColor);
-		this.bgFade_fColor = params.fColor ? params.fColor : jQuery(this).css('backgroundColor');
-		this.bgFade_steps = params.steps;
-		this.bgFade_intervals = params.intervals;
-		this.bgFade_powr = params.powr;
-		this.bgFade_fn = callback;
-		
-		jQuery.backgroundFade.doFade(this);
-	});
-};
-
-jQuery.backgroundFade = {
-	parseHexColor: function(c) {
-		if (c.constructor == String && c.substr(0,1) == '#') {
-			return [parseInt(c.substr(1,2),16),parseInt(c.substr(3,2),16),parseInt(c.substr(5,2),16)];
-		}
-		return c;
-	},
-	
-	easeInOut: function(minValue,maxValue,totalSteps,actualStep,powr) {
-		var delta = maxValue - minValue;
-		var stepp = minValue+(Math.pow(((1 / totalSteps)*actualStep),powr)*delta);
-		return Math.ceil(stepp);
-	},
-	
-	doFade: function(e) {
-		if (e.bgFadeInt) window.clearInterval(e.bgFadeInt);
-		var act_step = 0;
-		
-		e.bgFadeInt = window.setInterval(function() {
-			e.style.backgroundColor =
-			"rgb("+
-			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[0],e.bgFade_eColor[0],
-				e.bgFade_steps,act_step,e.bgFade_powr)+","+
-			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[1],e.bgFade_eColor[1],
-				e.bgFade_steps,act_step,e.bgFade_powr)+","+
-			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[2],e.bgFade_eColor[2],
-				e.bgFade_steps,act_step,e.bgFade_powr)+")";
-			
-			act_step++;
-			if (act_step > e.bgFade_steps) {
-				window.clearInterval(e.bgFadeInt);
-				e.bgFade_sColor = undefined;
-				e.bgFade_eColor = undefined;
-				e.bgFade_fColor = undefined;
-				e.bgFade_steps = undefined;
-				e.bgFade_intervals = undefined;
-				e.bgFade_powr = undefined;
-				if (typeof(e.bgFade_fn) == 'function') {
-					e.bgFade_fn.call(e);
-				}
-				e.style.backgroundColor = e.bgFade_fColor;
-			}
-		},e.bgFade_intervals);
-	}
-};
Index: admin/style/default.css
===================================================================
--- admin/style/default.css	(revision 3678)
+++ admin/style/default.css	(revision 3685)
@@ -1189,4 +1189,16 @@
   text-transform: none; }
 
+.missing {
+  background-color: inherit;
+  animation-name: kf-missing;
+  animation-duration: 1s; }
+
+@keyframes kf-missing {
+  0% {
+    background-color: inherit; }
+  50% {
+    background-color: #ffbaba; }
+  100% {
+    background-color: inherit; } }
 .no-more-info {
   display: none; }
@@ -1487,7 +1499,14 @@
 
 .error {
-  background: #FFBABA url(msg-error.png) no-repeat 0.7em 0.7em;
-  color: #000; }
-
+  background: #ffbaba url(msg-error.png) no-repeat 0.7em 0.7em;
+  color: #000;
+  animation-name: kf-error;
+  animation-duration: .5s; }
+
+@keyframes kf-error {
+  0% {
+    background-color: #fefacd; }
+  100% {
+    background-color: #ffbaba; } }
 .message,
 .static-msg {
@@ -1495,4 +1514,13 @@
   color: #fff; }
 
+.message {
+  animation-name: kf-message;
+  animation-duration: .5s; }
+
+@keyframes kf-message {
+  0% {
+    background-color: #ccc; }
+  100% {
+    background-color: #676e78; } }
 .message a,
 .static-msg a,
@@ -1506,10 +1534,24 @@
 
 .success {
-  background: #9bca1c url(msg-success.png) no-repeat 0.7em 0.7em; }
-
+  background: #bee74b url(msg-success.png) no-repeat 0.7em 0.7em;
+  animation-name: kf-success;
+  animation-duration: .5s; }
+
+@keyframes kf-success {
+  0% {
+    background-color: #9bca1c; }
+  100% {
+    background-color: #bee74b; } }
 .warning-msg {
   background: #ffd478 url(msg-warning.png) no-repeat 0.7em 0.7em;
-  border: 1px solid #ffd478; }
-
+  border: 1px solid #ffd478;
+  animation-name: kf-warning;
+  animation-duration: .5s; }
+
+@keyframes kf-warning {
+  0% {
+    background-color: #fefacd; }
+  100% {
+    background-color: #ffd478; } }
 .success a,
 .warning-msg a,
@@ -3199,35 +3241,4 @@
   border: 1px solid #ccc; }
 
-/* fadings ('color' est utilisé comme variable, pas comme text color) */
-.colorBeginPassword,
-.colorBeginValidatorErr,
-.colorBeginUserMail {
-  color: #fff; }
-
-.colorEndPassword,
-.colorEndError,
-.colorEndValidatorErr,
-.colorEndUserMail {
-  color: #ffbaba; }
-
-.colorBeginMessage {
-  color: #ccc; }
-
-.colorEndMessage,
-.colorBeginValidatorMsg {
-  color: #676e78; }
-
-.colorBeginError {
-  color: #fefacd; }
-
-.colorBeginSuccess {
-  color: #9BCA1C; }
-
-.colorEndSuccess {
-  color: #bee74b; }
-
-.colorEndValidatorMsg {
-  color: #ffcc00; }
-
 /* ------------------------------------------------------------------------------------
 															UN POIL DE MEDIA QUERIES
Index: admin/style/scss/partials/_forms.scss
===================================================================
--- admin/style/scss/partials/_forms.scss	(revision 3639)
+++ admin/style/scss/partials/_forms.scss	(revision 3685)
@@ -245,4 +245,21 @@
 }
 
+.missing {
+  background-color: inherit;
+  animation-name: kf-missing;
+  animation-duration: 1s;
+}
+@keyframes kf-missing {
+  0% {
+    background-color: inherit;
+  }
+  50% {
+    background-color: #ffbaba;
+  }
+  100% {
+    background-color: inherit;
+  }
+}
+
 // .more-info Additional information on fieldset, field, … (may be hide from user-prefs)
 .more-info {}
Index: admin/style/scss/partials/_messages.scss
===================================================================
--- admin/style/scss/partials/_messages.scss	(revision 3638)
+++ admin/style/scss/partials/_messages.scss	(revision 3685)
@@ -60,6 +60,16 @@
 
 .error {
-	background: #FFBABA url(msg-error.png) no-repeat .7em .7em;
+	background: #ffbaba url(msg-error.png) no-repeat .7em .7em;
 	color: #000;
+  animation-name: kf-error;
+  animation-duration: .5s;
+}
+@keyframes kf-error {
+  0% {
+    background-color: #fefacd;
+  }
+  100% {
+    background-color: #ffbaba;
+  }
 }
 
@@ -68,4 +78,16 @@
 	background: #676e78 url(msg-std.png) no-repeat .7em .7em;
 	color: #fff;
+}
+.message {
+  animation-name: kf-message;
+  animation-duration: .5s;
+}
+@keyframes kf-message {
+  0% {
+    background-color: #ccc;
+  }
+  100% {
+    background-color: #676e78;
+  }
 }
 
@@ -83,5 +105,15 @@
 
 .success {
-	background: #9bca1c url(msg-success.png) no-repeat .7em .7em;
+	background: #bee74b url(msg-success.png) no-repeat .7em .7em;
+  animation-name: kf-success;
+  animation-duration: .5s;
+}
+@keyframes kf-success {
+  0% {
+    background-color: #9bca1c;
+  }
+  100% {
+    background-color: #bee74b;
+  }
 }
 
@@ -89,4 +121,14 @@
 	background: #ffd478 url(msg-warning.png) no-repeat .7em .7em;
 	border: 1px solid #ffd478;
+  animation-name: kf-warning;
+  animation-duration: .5s;
+}
+@keyframes kf-warning {
+  0% {
+    background-color: #fefacd;
+  }
+  100% {
+    background-color: #ffd478;
+  }
 }
 
Index: admin/style/scss/partials/_utils.scss
===================================================================
--- admin/style/scss/partials/_utils.scss	(revision 3439)
+++ admin/style/scss/partials/_utils.scss	(revision 3685)
@@ -14,43 +14,2 @@
 	border: 1px solid #ccc;
 }
-
-
-/* fadings ('color' est utilisé comme variable, pas comme text color) */
-
-.colorBeginPassword,
-.colorBeginValidatorErr,
-.colorBeginUserMail {
-	color: #fff;
-}
-
-.colorEndPassword,
-.colorEndError,
-.colorEndValidatorErr,
-.colorEndUserMail {
-	color: #ffbaba;
-}
-
-.colorBeginMessage {
-	color: #ccc;
-}
-
-.colorEndMessage,
-.colorBeginValidatorMsg {
-	color: #676e78;
-}
-
-.colorBeginError {
-	color: #fefacd;
-}
-
-.colorBeginSuccess {
-	color: #9BCA1C;
-}
-
-.colorEndSuccess {
-	color: #bee74b;
-}
-
-.colorEndValidatorMsg {
-	color: #ffcc00;
-}
Index: inc/admin/lib.dc.page.php
===================================================================
--- inc/admin/lib.dc.page.php	(revision 3672)
+++ inc/admin/lib.dc.page.php	(revision 3685)
@@ -746,5 +746,4 @@
 		self::jsLoad('js/jquery/jquery-migrate.js').
 		self::jsLoad('js/jquery/jquery.biscuit.js').
-		self::jsLoad('js/jquery/jquery.bgFade.js').
 		self::jsLoad('js/common.js').
 		self::jsLoad('js/prelude.js').
Index: inc/dbschema/upgrade.php
===================================================================
--- inc/dbschema/upgrade.php	(revision 3599)
+++ inc/dbschema/upgrade.php	(revision 3685)
@@ -712,4 +712,10 @@
 		}
 
+        if (version_compare($version,'2.14','<'))
+        {
+            // File not more needed
+            @unlink(DC_ROOT.'/'.'admin/js/jquery/jquery.bgFade.js');
+        }
+
 		$core->setVersion('core',DC_VERSION);
 		$core->blogDefaults();
