From 078664bc34403bf18e0ae6ea3e0ccba308cf8df6 Mon Sep 17 00:00:00 2001
From: Walter Purcaro <vuolter@gmail.com>
Date: Fri, 17 Oct 2014 02:19:08 +0200
Subject: [themes] Code cosmetics

---
 pyload/webui/themes/estate/css/MooDialog.css       |   94 +-
 pyload/webui/themes/estate/css/log.css             |   64 +-
 pyload/webui/themes/estate/css/pathchooser.css     |   56 +-
 pyload/webui/themes/estate/css/window.css          |   96 +-
 .../webui/themes/estate/js/render/filemanager.js   |  236 +-
 pyload/webui/themes/estate/js/static/MooDialog.js  |  236 +-
 .../webui/themes/estate/js/static/MooDropMenu.js   |   92 +-
 .../webui/themes/estate/js/static/mootools-core.js | 8142 ++++++++++----------
 .../webui/themes/estate/js/static/mootools-more.js | 4128 +++++-----
 pyload/webui/themes/estate/js/static/purr.js       |  566 +-
 pyload/webui/themes/estate/js/static/tinytab.js    |   48 +-
 pyload/webui/themes/estate/tml/home.html           |    2 +-
 12 files changed, 6880 insertions(+), 6880 deletions(-)

(limited to 'pyload/webui/themes/estate')

diff --git a/pyload/webui/themes/estate/css/MooDialog.css b/pyload/webui/themes/estate/css/MooDialog.css
index 8a555ac2c..7d6e38ece 100644
--- a/pyload/webui/themes/estate/css/MooDialog.css
+++ b/pyload/webui/themes/estate/css/MooDialog.css
@@ -1,85 +1,85 @@
 /* Created by Arian Stolwijk <http://www.aryweb.nl> */
 
 .MooDialog {
-/*	position: fixed;*/
-    margin: 0 auto 0 -350px;
-    width:600px;
-    padding:14px;
-    left:50%;
-    top: 100px;
+/*  position: fixed;*/
+  margin: 0 auto 0 -350px;
+  width:600px;
+  padding:14px;
+  left:50%;
+  top: 100px;
 
-	position: absolute;
-	left: 50%;
-	z-index: 50000;
+  position: absolute;
+  left: 50%;
+  z-index: 50000;
 
-	background-color: #E44424;
-	color: black;
+  background-color: #E44424;
+  color: black;
   opacity:0.9;
 }
 
 .MooDialogTitle {
-	padding-top: 30px;
+  padding-top: 30px;
 }
 
 .MooDialog .title {
-	position: absolute;
-	top: 0;
-	left: 0;
-	right: 0;
-	padding: 3px 20px;
-	background: #b7c4dc;
-	border-bottom: 1px solid #a1aec5;
-	font-weight: bold;
-	text-shadow: 1px 1px 0 #fff;
-	color: black;
-	border-radius: 7px;
-	-moz-border-radius: 7px;
-	-webkit-border-radius: 7px;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  padding: 3px 20px;
+  background: #b7c4dc;
+  border-bottom: 1px solid #a1aec5;
+  font-weight: bold;
+  text-shadow: 1px 1px 0 #fff;
+  color: black;
+  border-radius: 7px;
+  -moz-border-radius: 7px;
+  -webkit-border-radius: 7px;
 }
 
 .MooDialog .close {
-	background: url(../img/control_cancel.png) no-repeat;
-	width: 16px;
-	height: 16px;
-	display: block;
-	cursor: pointer;
-	top: -5px;
-	left: -5px;
-	position: absolute;
+  background: url(../img/control_cancel.png) no-repeat;
+  width: 16px;
+  height: 16px;
+  display: block;
+  cursor: pointer;
+  top: -5px;
+  left: -5px;
+  position: absolute;
 }
 
 .MooDialog .buttons {
-	text-align: right;
-	margin: 0;
-	padding: 0;
-	border: 0;
-	background: none;
+  text-align: right;
+  margin: 0;
+  padding: 0;
+  border: 0;
+  background: none;
 }
 
 .MooDialog .iframe {
-	width: 100%;
-	height: 100%;
+  width: 100%;
+  height: 100%;
 }
 
 .MooDialog .textInput {
-	width: 200px;
-	float: left;
+  width: 200px;
+  float: left;
 }
 
 .MooDialog .MooDialogAlert,
 .MooDialog .MooDialogConfirm,
 .MooDialog .MooDialogPrompt,
 .MooDialog .MooDialogError {
-	background: url(../img/MooDialog/dialog-warning.png) no-repeat;
-	padding-left: 40px;
-	min-height: 40px;
+  background: url(../img/MooDialog/dialog-warning.png) no-repeat;
+  padding-left: 40px;
+  min-height: 40px;
 }
 
 .MooDialog .MooDialogConfirm,
 .MooDialog .MooDialogPromt {
-	background: url(../img/MooDialog/dialog-question.png) no-repeat;
+  background: url(../img/MooDialog/dialog-question.png) no-repeat;
 }
 
 .MooDialog .MooDialogError {
-	background: url(../img/MooDialog/dialog-error.png) no-repeat;
+  background: url(../img/MooDialog/dialog-error.png) no-repeat;
 }
diff --git a/pyload/webui/themes/estate/css/log.css b/pyload/webui/themes/estate/css/log.css
index af2ea4fe8..c2f21b506 100644
--- a/pyload/webui/themes/estate/css/log.css
+++ b/pyload/webui/themes/estate/css/log.css
@@ -1,72 +1,72 @@
 
 html, body, #content
 {
-    height: 100%;
+  height: 100%;
 }
 #body-wrapper
 {
-    height: 70%;
+  height: 70%;
 }
 .logdiv
 {
-    height: 90%;
-    width: 100%;
-    overflow: auto;
-    border: 2px solid #CCC;
-    outline: 1px solid #666;
-    background-color: #FFE;
-    margin-right: auto;
-    margin-left: auto;
+  height: 90%;
+  width: 100%;
+  overflow: auto;
+  border: 2px solid #CCC;
+  outline: 1px solid #666;
+  background-color: #FFE;
+  margin-right: auto;
+  margin-left: auto;
 }
 .logform
 {
-    display: table;
-    margin: 0 auto 0 auto;
-    padding-top: 5px;
+  display: table;
+  margin: 0 auto 0 auto;
+  padding-top: 5px;
 }
 .logtable
 {
 
-    margin: 0px;
+  margin: 0px;
 }
 .logtable td
 {
-    border: none;
-    white-space: nowrap;
+  border: none;
+  white-space: nowrap;
 
 
-    font-family: monospace;
-    font-size: 16px;
-    margin: 0px;
-    padding: 0px 10px 0px 10px;
-    line-height: 110%;
+  font-family: monospace;
+  font-size: 16px;
+  margin: 0px;
+  padding: 0px 10px 0px 10px;
+  line-height: 110%;
 }
 td.logline
 {
-    background-color: #EEE;
-    text-align:right;
-    padding: 0px 5px 0px 5px;
+  background-color: #EEE;
+  text-align:right;
+  padding: 0px 5px 0px 5px;
 }
 td.loglevel
 {
-    text-align:right;
+  text-align:right;
 }
 .logperpage
 {
-    float: right;
-    padding-bottom: 8px;
+  float: right;
+  padding-bottom: 8px;
 }
 .logpaginator
 {
-    float: left;
-    padding-top: 5px;
+  float: left;
+  padding-top: 5px;
 }
 .logpaginator a
 {
-    padding: 0px 8px 0px 8px;
+  padding: 0px 8px 0px 8px;
 }
 .logwarn
 {
-    text-align: center;
-    color: red;
+  text-align: center;
+  color: red;
 }
\ No newline at end of file
diff --git a/pyload/webui/themes/estate/css/pathchooser.css b/pyload/webui/themes/estate/css/pathchooser.css
index 894cc335e..204812aa1 100644
--- a/pyload/webui/themes/estate/css/pathchooser.css
+++ b/pyload/webui/themes/estate/css/pathchooser.css
@@ -1,68 +1,68 @@
 table {
-    width: 90%;
-    border: 1px dotted #888888;
-    font-family: sans-serif;
-    font-size: 10pt;
+  width: 90%;
+  border: 1px dotted #888888;
+  font-family: sans-serif;
+  font-size: 10pt;
 }
 
 th {
-    background-color: #525252;
-    color: #E0E0E0;
+  background-color: #525252;
+  color: #E0E0E0;
 }
 
 table, tr, td {
-    background-color: #F0F0F0;
+  background-color: #F0F0F0;
 }
 
 a, a:visited {
-    text-decoration: none;
-    font-weight: bold;
+  text-decoration: none;
+  font-weight: bold;
 }
 
 #paths {
-    width: 90%;
-    text-align: left;
+  width: 90%;
+  text-align: left;
 }
 
 .file_directory {
-    color: #c0c0c0;
+  color: #c0c0c0;
 }
 .path_directory {
-    color: #3c3c3c;
+  color: #3c3c3c;
 }
 .file_file {
-    color: #3c3c3c;
+  color: #3c3c3c;
 }
 .path_file {
-    color: #c0c0c0;
+  color: #c0c0c0;
 }
 
 .parentdir {
-    color: #000000;
-    font-size: 10pt;
+  color: #000000;
+  font-size: 10pt;
 }
 .name {
-    text-align: left;
+  text-align: left;
 }
 .size {
-    text-align: right;
+  text-align: right;
 }
 .type {
-    text-align: left;
+  text-align: left;
 }
 .mtime {
-    text-align: center;
+  text-align: center;
 }
 
 .path_abs_rel {
-    color: #3c3c3c;
-    text-decoration: none;
-    font-weight: bold;
-    font-family: sans-serif;
-    font-size: 10pt;
+  color: #3c3c3c;
+  text-decoration: none;
+  font-weight: bold;
+  font-family: sans-serif;
+  font-size: 10pt;
 }
 
 .path_abs_rel a {
-    color: #3c3c3c;
-    font-style: italic;
+  color: #3c3c3c;
+  font-style: italic;
 }
diff --git a/pyload/webui/themes/estate/css/window.css b/pyload/webui/themes/estate/css/window.css
index 8b9a69b8c..40c1aadca 100644
--- a/pyload/webui/themes/estate/css/window.css
+++ b/pyload/webui/themes/estate/css/window.css
@@ -1,70 +1,70 @@
 /* ----------- stylized ----------- */
 .window_box h1{
-    margin-bottom:8px;
+  margin-bottom:8px;
 }
 .window_box p{
-    font-size:11px;
-    color:#FFFFFF;
-    margin-bottom:20px;
-    border-bottom:solid 1px #b7ddf2;
-    padding-bottom:10px;
+  font-size:11px;
+  color:#FFFFFF;
+  margin-bottom:20px;
+  border-bottom:solid 1px #b7ddf2;
+  padding-bottom:10px;
 }
 .window_box label{
-    display:block;
-    font-weight:bold;
-    text-align:right;
-    width:240px;
-    float:left;
+  display:block;
+  font-weight:bold;
+  text-align:right;
+  width:240px;
+  float:left;
 }
 .window_box .small{
-    color:#FFFFFF;
-    display:block;
-    font-size:11px;
-    font-weight:normal;
-    text-align:right;
-    width:240px;
+  color:#FFFFFF;
+  display:block;
+  font-size:11px;
+  font-weight:normal;
+  text-align:right;
+  width:240px;
 }
 .window_box select, .window_box input{
-    float:left;
-    font-size:12px;
-    padding:4px 2px;
-    width:300px;
-    margin:2px 0 20px 10px;
+  float:left;
+  font-size:12px;
+  padding:4px 2px;
+  width:300px;
+  margin:2px 0 20px 10px;
 }
 .window_box .cont{
-    float:left;
-    font-size:12px;
-    padding: 0px 10px 15px 0px;
-    width:300px;
-    margin:0px 0px 0px 10px;
-    color:#FFFFFF;
+  float:left;
+  font-size:12px;
+  padding: 0px 10px 15px 0px;
+  width:300px;
+  margin:0px 0px 0px 10px;
+  color:#FFFFFF;
 }
 .window_box .cont input{
-    float: none;
-    margin: 0px 15px 0px 1px;
+  float: none;
+  margin: 0px 15px 0px 1px;
 }
 .window_box textarea{
-    float:left;
-    font-size:12px;
-    padding:4px 2px;
-    width:300px;
-    margin:2px 0 20px 10px;
+  float:left;
+  font-size:12px;
+  padding:4px 2px;
+  width:300px;
+  margin:2px 0 20px 10px;
 }
 .window_box button, .styled_button{
-    clear:both;
-    margin-left:150px;
-    width:125px;
-    height:31px;
-    background:url(../img/button.png) no-repeat;
-    text-align:center;
-    line-height:31px;
-    color:#FFFFFF;
-    font-size:11px;
-    font-weight:bold;
-    border: 0px;
+  clear:both;
+  margin-left:150px;
+  width:125px;
+  height:31px;
+  background:url(../img/button.png) no-repeat;
+  text-align:center;
+  line-height:31px;
+  color:#FFFFFF;
+  font-size:11px;
+  font-weight:bold;
+  border: 0px;
 }
 
 .styled_button {
-    margin-left: 15px;
-    cursor: pointer;
+  margin-left: 15px;
+  cursor: pointer;
 }
diff --git a/pyload/webui/themes/estate/js/render/filemanager.js b/pyload/webui/themes/estate/js/render/filemanager.js
index f1ebed93f..b1046ccad 100644
--- a/pyload/webui/themes/estate/js/render/filemanager.js
+++ b/pyload/webui/themes/estate/js/render/filemanager.js
@@ -17,7 +17,7 @@ document.addEvent("domready", function() {
       var action_name = action.className;
       if(functions[action.className] != undefined)
       {
-	action.addEvent('click', functions[action.className]);
+    action.addEvent('click', functions[action.className]);
       }
     });*/
 });
@@ -76,7 +76,7 @@ var FilemanagerUI = new Class({
         this.url = url;
         this.type = type;
         this.directories = [];
-	this.files = [];
+    this.files = [];
         this.parseChildren();
     },
 
@@ -86,8 +86,8 @@ var FilemanagerUI = new Class({
             var name = ele.getElements("input.name")[0].get("value");
             this.directories.push(new Item(this, path, name, ele))
         }.bind(this));
-	
-	$("directories-list").getChildren("li.file").each(function(ele) {
+    
+    $("directories-list").getChildren("li.file").each(function(ele) {
             var path = ele.getElements("input.path")[0].get("value");
             var name = ele.getElements("input.name")[0].get("value");
             this.files.push(new Item(this, path, name, ele))
@@ -98,15 +98,15 @@ var FilemanagerUI = new Class({
 var Item = new Class({
     initialize: function(ui, path, name, ele) {
         this.ui = ui;
-	this.path = path;
-	this.name = name;
+    this.path = path;
+    this.name = name;
         this.ele = ele;
-	this.directories = [];
-	this.files = [];
-	this.actions = new Array();
-	this.actions["delete"] = this.del;
-	this.actions["rename"] = this.rename;
-	this.actions["mkdir"] = this.mkdir;
+    this.directories = [];
+    this.files = [];
+    this.actions = new Array();
+    this.actions["delete"] = this.del;
+    this.actions["rename"] = this.rename;
+    this.actions["mkdir"] = this.mkdir;
         this.parseElement();
 
         var pname = this.ele.getElements("span")[0];
@@ -125,27 +125,27 @@ var Item = new Class({
 
     parseElement: function() {
         this.ele.getChildren('span span.buttons img').each(function(img) {
-	  img.addEvent('click', this.actions[img.className].bind(this));
-	}, this);
-
-	//click on the directory name must open the directory itself
-	this.ele.getElements('b')[0].addEvent('click', this.toggle.bind(this));
-	
-	//iterate over child directories
-	var uls = this.ele.getElements('ul');
-	if(uls.length > 0)
-	{
-	  uls[0].getChildren("li.folder").each(function(fld) {
-	    var path = fld.getElements("input.path")[0].get("value");
-	    var name = fld.getElements("input.name")[0].get("value");
-	    this.directories.push(new Item(this, path, name, fld));
-	  }.bind(this));
-	  uls[0].getChildren("li.file").each(function(fld) {
-	    var path = fld.getElements("input.path")[0].get("value");
-	    var name = fld.getElements("input.name")[0].get("value");
-	    this.files.push(new Item(this, path, name, fld));
-	  }.bind(this));
-	}
+      img.addEvent('click', this.actions[img.className].bind(this));
+    }, this);
+
+    //click on the directory name must open the directory itself
+    this.ele.getElements('b')[0].addEvent('click', this.toggle.bind(this));
+    
+    //iterate over child directories
+    var uls = this.ele.getElements('ul');
+    if(uls.length > 0)
+    {
+      uls[0].getChildren("li.folder").each(function(fld) {
+        var path = fld.getElements("input.path")[0].get("value");
+        var name = fld.getElements("input.name")[0].get("value");
+        this.directories.push(new Item(this, path, name, fld));
+      }.bind(this));
+      uls[0].getChildren("li.file").each(function(fld) {
+        var path = fld.getElements("input.path")[0].get("value");
+        var name = fld.getElements("input.name")[0].get("value");
+        this.files.push(new Item(this, path, name, fld));
+      }.bind(this));
+    }
     },
 
     reorderElements: function() {
@@ -156,41 +156,41 @@ var Item = new Class({
         $("confirm_form").removeEvents("submit");
         $("confirm_form").addEvent("submit", this.deleteDirectory.bind(this));
 
-	$$("#confirm_form p").set('html', '{{_(("Are you sure you want to delete the selected item?"))}}');
-	
+    $$("#confirm_form p").set('html', '{{_(("Are you sure you want to delete the selected item?"))}}');
+    
         show_confirm_box();
         event.stop();
     },
 
     deleteDirectory: function(event) {
         hide_confirm_box();
-	new Request.JSON({
+    new Request.JSON({
             method: 'POST',
             url: "/json/filemanager/delete",
-	    data: {'path': this.path, 'name': this.name},
+        data: {'path': this.path, 'name': this.name},
             onSuccess: function(data) {
-		if(data.response == "success")
-		{
-		  new Fx.Tween(this.ele).start('opacity', 0);
-		  var ul = this.ele.parentNode;
-		  this.ele.dispose();
-		  //if this was the only child, add a "empty folder" div
-		  if(!ul.getChildren('li')[0])
-		  {
-		    var div = new Element("div", { 'html': '{{ _("Folder is empty") }}' });
-		    div.replaces(ul);
-		  }
-
-		  indicateSuccess();
-		} else
-		{
-		  //error from json code...
-		  indicateFail();
-		}
+        if(data.response == "success")
+        {
+          new Fx.Tween(this.ele).start('opacity', 0);
+          var ul = this.ele.parentNode;
+          this.ele.dispose();
+          //if this was the only child, add a "empty folder" div
+          if(!ul.getChildren('li')[0])
+          {
+            var div = new Element("div", { 'html': '{{ _("Folder is empty") }}' });
+            div.replaces(ul);
+          }
+
+          indicateSuccess();
+        } else
+        {
+          //error from json code...
+          indicateFail();
+        }
             }.bind(this),
             onFailure: indicateFail
         }).send();
-	
+    
         event.stop();
     },
 
@@ -198,7 +198,7 @@ var Item = new Class({
         $("rename_form").removeEvents("submit");
         $("rename_form").addEvent("submit", this.renameDirectory.bind(this));
 
-	$("path").set("value", this.path);
+    $("path").set("value", this.path);
         $("old_name").set("value", this.name);
         $("new_name").set("value", this.name);
 
@@ -208,67 +208,67 @@ var Item = new Class({
 
     renameDirectory: function(event) {
         hide_rename_box();
-	new Request.JSON({
+    new Request.JSON({
             method: 'POST',
             url: "/json/filemanager/rename",
             onSuccess: function(data) {
-		if(data.response == "success")
-		{
-		  this.name = $("new_name").get("value");
-		  this.ele.getElements("b")[0].set('html', $("new_name").get("value"));
-		  this.reorderElements();
-		  indicateSuccess();
-		} else
-		{
-		  //error from json code...
-		  indicateFail();
-		}
+        if(data.response == "success")
+        {
+          this.name = $("new_name").get("value");
+          this.ele.getElements("b")[0].set('html', $("new_name").get("value"));
+          this.reorderElements();
+          indicateSuccess();
+        } else
+        {
+          //error from json code...
+          indicateFail();
+        }
             }.bind(this),
             onFailure: indicateFail
         }).send($("rename_form").toQueryString());
-	
+    
         event.stop();
     },
 
     mkdir: function(event) {
       new Request.JSON({
-	  method: 'POST',
-	  url: "/json/filemanager/mkdir",
-	  data: {'path': this.path + "/" + this.name, 'name': '{{_("New folder")}}'},
-	  onSuccess: function(data) {
-	      if(data.response == "success")
-	      {
-		new Request.HTML({
-		    method: 'POST',
-		    url: "/filemanager/get_dir",
-		    data: {'path': data.path, 'name': data.name},
-		    onSuccess: function(li) {
-			//add node as first child of ul
-			var ul = this.ele.getChildren('ul')[0];
-			if(!ul)
-			{
-			  //remove the "Folder Empty" div
-			  this.ele.getChildren('div').dispose();
-
-			  //create new ul to contain subfolder
-			  ul = new Element("ul");
-			  ul.inject(this.ele, 'bottom');
-			}
-			li[0].inject(ul, 'top');
-			
-			//add directory as a subdirectory of the current item
-			this.directories.push(new Item(this.ui, data.path, data.name, ul.firstChild));
-		    }.bind(this),
-		    onFailure: indicateFail
-		}).send();
-		indicateSuccess();
-	      } else
-	      {
-		//error from json code...
-		indicateFail();
-	      }
-	  }.bind(this),
-	  onFailure: indicateFail
+      method: 'POST',
+      url: "/json/filemanager/mkdir",
+      data: {'path': this.path + "/" + this.name, 'name': '{{_("New folder")}}'},
+      onSuccess: function(data) {
+          if(data.response == "success")
+          {
+        new Request.HTML({
+            method: 'POST',
+            url: "/filemanager/get_dir",
+            data: {'path': data.path, 'name': data.name},
+            onSuccess: function(li) {
+            //add node as first child of ul
+            var ul = this.ele.getChildren('ul')[0];
+            if(!ul)
+            {
+              //remove the "Folder Empty" div
+              this.ele.getChildren('div').dispose();
+
+              //create new ul to contain subfolder
+              ul = new Element("ul");
+              ul.inject(this.ele, 'bottom');
+            }
+            li[0].inject(ul, 'top');
+            
+            //add directory as a subdirectory of the current item
+            this.directories.push(new Item(this.ui, data.path, data.name, ul.firstChild));
+            }.bind(this),
+            onFailure: indicateFail
+        }).send();
+        indicateSuccess();
+          } else
+          {
+        //error from json code...
+        indicateFail();
+          }
+      }.bind(this),
+      onFailure: indicateFail
       }).send();
 
       event.stop();
@@ -276,16 +276,16 @@ var Item = new Class({
 
     toggle: function() {
         var child = this.ele.getElement('ul');
-	if(child == null)
-	  child = this.ele.getElement('div');
-	
-	if(child != null)
-	{
-	  if (child.getStyle('display') == "block") {
-	      child.dissolve();
-	  } else {
-	      child.reveal();
-	  }
-	}
+    if(child == null)
+      child = this.ele.getElement('div');
+    
+    if(child != null)
+    {
+      if (child.getStyle('display') == "block") {
+          child.dissolve();
+      } else {
+          child.reveal();
+      }
+    }
     }
 });
diff --git a/pyload/webui/themes/estate/js/static/MooDialog.js b/pyload/webui/themes/estate/js/static/MooDialog.js
index 45a52496f..237984981 100644
--- a/pyload/webui/themes/estate/js/static/MooDialog.js
+++ b/pyload/webui/themes/estate/js/static/MooDialog.js
@@ -12,129 +12,129 @@ provides: [MooDialog, Element.MooDialog]
 
 var MooDialog = new Class({
 
-	Implements: [Options, Events],
-
-	options: {
-		'class': 'MooDialog',
-		title: null,
-		scroll: true, // IE
-		forceScroll: false,
-		useEscKey: true,
-		destroyOnHide: true,
-		autoOpen: true,
-		closeButton: true,
-		onInitialize: function(){
-			this.wrapper.setStyle('display', 'none');
-		},
-		onBeforeOpen: function(){
-			this.wrapper.setStyle('display', 'block');
-			this.fireEvent('show');
-		},
-		onBeforeClose: function(){
-			this.wrapper.setStyle('display', 'none');
-			this.fireEvent('hide');
-		}/*,
-		onOpen: function(){},
-		onClose: function(){},
-		onShow: function(){},
-		onHide: function(){},
-		onInitialize: function(wrapper){},
-		onContentChange: function(content){}*/
-	},
-
-	initialize: function(options){
-		this.setOptions(options);
-		this.options.inject = this.options.inject || document.body;
-		options = this.options;
-
-		var wrapper = this.wrapper = new Element('div.' + options['class'].replace(' ', '.')).inject(options.inject);
-		this.content = new Element('div.content').inject(wrapper);
-
-		if (options.title){
-			this.title = new Element('div.title').set('text', options.title).inject(wrapper);
-			wrapper.addClass('MooDialogTitle');
-		}
-
-		if (options.closeButton){
-			this.closeButton = new Element('a.close', {
-				events: {click: this.close.bind(this)}
-			}).inject(wrapper);
-		}
-
-
-		/*<ie6>*/// IE 6 scroll
-		if ((options.scroll && Browser.ie6) || options.forceScroll){
-			wrapper.setStyle('position', 'absolute');
-			var position = wrapper.getPosition(options.inject);
-			window.addEvent('scroll', function(){
-				var scroll = document.getScroll();
-				wrapper.setPosition({
-					x: position.x + scroll.x,
-					y: position.y + scroll.y
-				});
-			});
-		}
-		/*</ie6>*/
-
-		if (options.useEscKey){
-			// Add event for the esc key
-			document.addEvent('keydown', function(e){
-				if (e.key == 'esc') this.close();
-			}.bind(this));
-		}
-
-		this.addEvent('hide', function(){
-			if (options.destroyOnHide) this.destroy();
-		}.bind(this));
-
-		this.fireEvent('initialize', wrapper);
-	},
-
-	setContent: function(){
-		var content = Array.from(arguments);
-		if (content.length == 1) content = content[0];
-
-		this.content.empty();
-
-		var type = typeOf(content);
-		if (['string', 'number'].contains(type)) this.content.set('text', content);
-		else this.content.adopt(content);
-
-		this.fireEvent('contentChange', this.content);
-
-		return this;
-	},
-
-	open: function(){
-		this.fireEvent('beforeOpen', this.wrapper).fireEvent('open');
-		this.opened = true;
-		return this;
-	},
-
-	close: function(){
-		this.fireEvent('beforeClose', this.wrapper).fireEvent('close');
-		this.opened = false;
-		return this;
-	},
-
-	destroy: function(){
-		this.wrapper.destroy();
-	},
-
-	toElement: function(){
-		return this.wrapper;
-	}
+    Implements: [Options, Events],
+
+    options: {
+        'class': 'MooDialog',
+        title: null,
+        scroll: true, // IE
+        forceScroll: false,
+        useEscKey: true,
+        destroyOnHide: true,
+        autoOpen: true,
+        closeButton: true,
+        onInitialize: function(){
+            this.wrapper.setStyle('display', 'none');
+        },
+        onBeforeOpen: function(){
+            this.wrapper.setStyle('display', 'block');
+            this.fireEvent('show');
+        },
+        onBeforeClose: function(){
+            this.wrapper.setStyle('display', 'none');
+            this.fireEvent('hide');
+        }/*,
+        onOpen: function(){},
+        onClose: function(){},
+        onShow: function(){},
+        onHide: function(){},
+        onInitialize: function(wrapper){},
+        onContentChange: function(content){}*/
+    },
+
+    initialize: function(options){
+        this.setOptions(options);
+        this.options.inject = this.options.inject || document.body;
+        options = this.options;
+
+        var wrapper = this.wrapper = new Element('div.' + options['class'].replace(' ', '.')).inject(options.inject);
+        this.content = new Element('div.content').inject(wrapper);
+
+        if (options.title){
+            this.title = new Element('div.title').set('text', options.title).inject(wrapper);
+            wrapper.addClass('MooDialogTitle');
+        }
+
+        if (options.closeButton){
+            this.closeButton = new Element('a.close', {
+                events: {click: this.close.bind(this)}
+            }).inject(wrapper);
+        }
+
+
+        /*<ie6>*/// IE 6 scroll
+        if ((options.scroll && Browser.ie6) || options.forceScroll){
+            wrapper.setStyle('position', 'absolute');
+            var position = wrapper.getPosition(options.inject);
+            window.addEvent('scroll', function(){
+                var scroll = document.getScroll();
+                wrapper.setPosition({
+                    x: position.x + scroll.x,
+                    y: position.y + scroll.y
+                });
+            });
+        }
+        /*</ie6>*/
+
+        if (options.useEscKey){
+            // Add event for the esc key
+            document.addEvent('keydown', function(e){
+                if (e.key == 'esc') this.close();
+            }.bind(this));
+        }
+
+        this.addEvent('hide', function(){
+            if (options.destroyOnHide) this.destroy();
+        }.bind(this));
+
+        this.fireEvent('initialize', wrapper);
+    },
+
+    setContent: function(){
+        var content = Array.from(arguments);
+        if (content.length == 1) content = content[0];
+
+        this.content.empty();
+
+        var type = typeOf(content);
+        if (['string', 'number'].contains(type)) this.content.set('text', content);
+        else this.content.adopt(content);
+
+        this.fireEvent('contentChange', this.content);
+
+        return this;
+    },
+
+    open: function(){
+        this.fireEvent('beforeOpen', this.wrapper).fireEvent('open');
+        this.opened = true;
+        return this;
+    },
+
+    close: function(){
+        this.fireEvent('beforeClose', this.wrapper).fireEvent('close');
+        this.opened = false;
+        return this;
+    },
+
+    destroy: function(){
+        this.wrapper.destroy();
+    },
+
+    toElement: function(){
+        return this.wrapper;
+    }
 
 });
 
 
 Element.implement({
 
-	MooDialog: function(options){
-		this.store('MooDialog',
-			new MooDialog(options).setContent(this).open()
-		);
-		return this;
-	}
+    MooDialog: function(options){
+        this.store('MooDialog',
+            new MooDialog(options).setContent(this).open()
+        );
+        return this;
+    }
 
 });
diff --git a/pyload/webui/themes/estate/js/static/MooDropMenu.js b/pyload/webui/themes/estate/js/static/MooDropMenu.js
index ac0fa1874..08dc79c1e 100644
--- a/pyload/webui/themes/estate/js/static/MooDropMenu.js
+++ b/pyload/webui/themes/estate/js/static/MooDropMenu.js
@@ -19,68 +19,68 @@ provides: [MooDropMenu, Element.MooDropMenu]
 
 var MooDropMenu = new Class({
 
-	Implements: [Options, Events],
+  Implements: [Options, Events],
 
-	options: {
-		onOpen: function(el){
-			el.removeClass('close').addClass('open');
-		},
-		onClose: function(el){
-			el.removeClass('open').addClass('close');
-		},
-		onInitialize: function(el){
-			el.removeClass('open').addClass('close');
-		},
-		mouseoutDelay: 200,
-		mouseoverDelay: 0,
-		listSelector: 'ul',
-		itemSelector: 'li',
-		openEvent: 'mouseenter',
-		closeEvent: 'mouseleave'
-	},
+  options: {
+    onOpen: function(el){
+      el.removeClass('close').addClass('open');
+    },
+    onClose: function(el){
+      el.removeClass('open').addClass('close');
+    },
+    onInitialize: function(el){
+      el.removeClass('open').addClass('close');
+    },
+    mouseoutDelay: 200,
+    mouseoverDelay: 0,
+    listSelector: 'ul',
+    itemSelector: 'li',
+    openEvent: 'mouseenter',
+    closeEvent: 'mouseleave'
+  },
 
-	initialize: function(menu, options, level){
-		this.setOptions(options);
-		options = this.options;
+  initialize: function(menu, options, level){
+    this.setOptions(options);
+    options = this.options;
 
-		var menu = this.menu = document.id(menu);
+    var menu = this.menu = document.id(menu);
 
-		menu.getElements(options.itemSelector + ' > ' + options.listSelector).each(function(el){
+    menu.getElements(options.itemSelector + ' > ' + options.listSelector).each(function(el){
 
-			this.fireEvent('initialize', el);
+      this.fireEvent('initialize', el);
 
-			var parent = el.getParent(options.itemSelector),
-				timer;
+      var parent = el.getParent(options.itemSelector),
+        timer;
 
-			parent.addEvent(options.openEvent, function(){
-				parent.store('DropDownOpen', true);
+      parent.addEvent(options.openEvent, function(){
+        parent.store('DropDownOpen', true);
 
-				clearTimeout(timer);
-				if (options.mouseoverDelay) timer = this.fireEvent.delay(options.mouseoverDelay, this, ['open', el]);
-				else this.fireEvent('open', el);
+        clearTimeout(timer);
+        if (options.mouseoverDelay) timer = this.fireEvent.delay(options.mouseoverDelay, this, ['open', el]);
+        else this.fireEvent('open', el);
 
-			}.bind(this)).addEvent(options.closeEvent, function(){
-				parent.store('DropDownOpen', false);
+      }.bind(this)).addEvent(options.closeEvent, function(){
+        parent.store('DropDownOpen', false);
 
-				clearTimeout(timer);
-				timer = (function(){
-					if (!parent.retrieve('DropDownOpen')) this.fireEvent('close', el);
-				}).delay(options.mouseoutDelay, this);
+        clearTimeout(timer);
+        timer = (function(){
+          if (!parent.retrieve('DropDownOpen')) this.fireEvent('close', el);
+        }).delay(options.mouseoutDelay, this);
 
-			}.bind(this));
+      }.bind(this));
 
-		}, this);
-	},
+    }, this);
+  },
 
-	toElement: function(){
-		return this.menu
-	}
+  toElement: function(){
+    return this.menu
+  }
 
 });
 
 /* So you can do like this $('nav').MooDropMenu(); or even $('nav').MooDropMenu().setStyle('border',1); */
 Element.implement({
-	MooDropMenu: function(options){
-		return this.store('MooDropMenu', new MooDropMenu(this, options));
-	}
+  MooDropMenu: function(options){
+    return this.store('MooDropMenu', new MooDropMenu(this, options));
+  }
 });
diff --git a/pyload/webui/themes/estate/js/static/mootools-core.js b/pyload/webui/themes/estate/js/static/mootools-core.js
index e73f1df1e..bfa57abbc 100644
--- a/pyload/webui/themes/estate/js/static/mootools-core.js
+++ b/pyload/webui/themes/estate/js/static/mootools-core.js
@@ -36,38 +36,38 @@ provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
 (function(){
 
 this.MooTools = {
-	version: '1.5.0',
-	build: '0f7b690afee9349b15909f33016a25d2e4d9f4e3'
+  version: '1.5.0',
+  build: '0f7b690afee9349b15909f33016a25d2e4d9f4e3'
 };
 
 // typeOf, instanceOf
 
 var typeOf = this.typeOf = function(item){
-	if (item == null) return 'null';
-	if (item.$family != null) return item.$family();
-
-	if (item.nodeName){
-		if (item.nodeType == 1) return 'element';
-		if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
-	} else if (typeof item.length == 'number'){
-		if ('callee' in item) return 'arguments';
-		if ('item' in item) return 'collection';
-	}
-
-	return typeof item;
+  if (item == null) return 'null';
+  if (item.$family != null) return item.$family();
+
+  if (item.nodeName){
+    if (item.nodeType == 1) return 'element';
+    if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace';
+  } else if (typeof item.length == 'number'){
+    if ('callee' in item) return 'arguments';
+    if ('item' in item) return 'collection';
+  }
+
+  return typeof item;
 };
 
 var instanceOf = this.instanceOf = function(item, object){
-	if (item == null) return false;
-	var constructor = item.$constructor || item.constructor;
-	while (constructor){
-		if (constructor === object) return true;
-		constructor = constructor.parent;
-	}
-	/*<ltIE8>*/
-	if (!item.hasOwnProperty) return false;
-	/*</ltIE8>*/
-	return item instanceof object;
+  if (item == null) return false;
+  var constructor = item.$constructor || item.constructor;
+  while (constructor){
+    if (constructor === object) return true;
+    constructor = constructor.parent;
+  }
+  /*<ltIE8>*/
+  if (!item.hasOwnProperty) return false;
+  /*</ltIE8>*/
+  return item instanceof object;
 };
 
 // Function overloading
@@ -79,45 +79,45 @@ for (var i in {toString: 1}) enumerables = null;
 if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
 
 Function.prototype.overloadSetter = function(usePlural){
-	var self = this;
-	return function(a, b){
-		if (a == null) return this;
-		if (usePlural || typeof a != 'string'){
-			for (var k in a) self.call(this, k, a[k]);
-			if (enumerables) for (var i = enumerables.length; i--;){
-				k = enumerables[i];
-				if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
-			}
-		} else {
-			self.call(this, a, b);
-		}
-		return this;
-	};
+  var self = this;
+  return function(a, b){
+    if (a == null) return this;
+    if (usePlural || typeof a != 'string'){
+      for (var k in a) self.call(this, k, a[k]);
+      if (enumerables) for (var i = enumerables.length; i--;){
+        k = enumerables[i];
+        if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
+      }
+    } else {
+      self.call(this, a, b);
+    }
+    return this;
+  };
 };
 
 Function.prototype.overloadGetter = function(usePlural){
-	var self = this;
-	return function(a){
-		var args, result;
-		if (typeof a != 'string') args = a;
-		else if (arguments.length > 1) args = arguments;
-		else if (usePlural) args = [a];
-		if (args){
-			result = {};
-			for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
-		} else {
-			result = self.call(this, a);
-		}
-		return result;
-	};
+  var self = this;
+  return function(a){
+    var args, result;
+    if (typeof a != 'string') args = a;
+    else if (arguments.length > 1) args = arguments;
+    else if (usePlural) args = [a];
+    if (args){
+      result = {};
+      for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
+    } else {
+      result = self.call(this, a);
+    }
+    return result;
+  };
 };
 
 Function.prototype.extend = function(key, value){
-	this[key] = value;
+  this[key] = value;
 }.overloadSetter();
 
 Function.prototype.implement = function(key, value){
-	this.prototype[key] = value;
+  this.prototype[key] = value;
 }.overloadSetter();
 
 // From
@@ -125,120 +125,120 @@ Function.prototype.implement = function(key, value){
 var slice = Array.prototype.slice;
 
 Function.from = function(item){
-	return (typeOf(item) == 'function') ? item : function(){
-		return item;
-	};
+  return (typeOf(item) == 'function') ? item : function(){
+    return item;
+  };
 };
 
 Array.from = function(item){
-	if (item == null) return [];
-	return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
+  if (item == null) return [];
+  return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
 };
 
 Number.from = function(item){
-	var number = parseFloat(item);
-	return isFinite(number) ? number : null;
+  var number = parseFloat(item);
+  return isFinite(number) ? number : null;
 };
 
 String.from = function(item){
-	return item + '';
+  return item + '';
 };
 
 // hide, protect
 
 Function.implement({
 
-	hide: function(){
-		this.$hidden = true;
-		return this;
-	},
+  hide: function(){
+    this.$hidden = true;
+    return this;
+  },
 
-	protect: function(){
-		this.$protected = true;
-		return this;
-	}
+  protect: function(){
+    this.$protected = true;
+    return this;
+  }
 
 });
 
 // Type
 
 var Type = this.Type = function(name, object){
-	if (name){
-		var lower = name.toLowerCase();
-		var typeCheck = function(item){
-			return (typeOf(item) == lower);
-		};
-
-		Type['is' + name] = typeCheck;
-		if (object != null){
-			object.prototype.$family = (function(){
-				return lower;
-			}).hide();
-			
-		}
-	}
-
-	if (object == null) return null;
-
-	object.extend(this);
-	object.$constructor = Type;
-	object.prototype.$constructor = object;
-
-	return object;
+  if (name){
+    var lower = name.toLowerCase();
+    var typeCheck = function(item){
+      return (typeOf(item) == lower);
+    };
+
+    Type['is' + name] = typeCheck;
+    if (object != null){
+      object.prototype.$family = (function(){
+        return lower;
+      }).hide();
+      
+    }
+  }
+
+  if (object == null) return null;
+
+  object.extend(this);
+  object.$constructor = Type;
+  object.prototype.$constructor = object;
+
+  return object;
 };
 
 var toString = Object.prototype.toString;
 
 Type.isEnumerable = function(item){
-	return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
+  return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
 };
 
 var hooks = {};
 
 var hooksOf = function(object){
-	var type = typeOf(object.prototype);
-	return hooks[type] || (hooks[type] = []);
+  var type = typeOf(object.prototype);
+  return hooks[type] || (hooks[type] = []);
 };
 
 var implement = function(name, method){
-	if (method && method.$hidden) return;
+  if (method && method.$hidden) return;
 
-	var hooks = hooksOf(this);
+  var hooks = hooksOf(this);
 
-	for (var i = 0; i < hooks.length; i++){
-		var hook = hooks[i];
-		if (typeOf(hook) == 'type') implement.call(hook, name, method);
-		else hook.call(this, name, method);
-	}
+  for (var i = 0; i < hooks.length; i++){
+    var hook = hooks[i];
+    if (typeOf(hook) == 'type') implement.call(hook, name, method);
+    else hook.call(this, name, method);
+  }
 
-	var previous = this.prototype[name];
-	if (previous == null || !previous.$protected) this.prototype[name] = method;
+  var previous = this.prototype[name];
+  if (previous == null || !previous.$protected) this.prototype[name] = method;
 
-	if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
-		return method.apply(item, slice.call(arguments, 1));
-	});
+  if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){
+    return method.apply(item, slice.call(arguments, 1));
+  });
 };
 
 var extend = function(name, method){
-	if (method && method.$hidden) return;
-	var previous = this[name];
-	if (previous == null || !previous.$protected) this[name] = method;
+  if (method && method.$hidden) return;
+  var previous = this[name];
+  if (previous == null || !previous.$protected) this[name] = method;
 };
 
 Type.implement({
 
-	implement: implement.overloadSetter(),
+  implement: implement.overloadSetter(),
 
-	extend: extend.overloadSetter(),
+  extend: extend.overloadSetter(),
 
-	alias: function(name, existing){
-		implement.call(this, name, this.prototype[existing]);
-	}.overloadSetter(),
+  alias: function(name, existing){
+    implement.call(this, name, this.prototype[existing]);
+  }.overloadSetter(),
 
-	mirror: function(hook){
-		hooksOf(this).push(hook);
-		return this;
-	}
+  mirror: function(hook){
+    hooksOf(this).push(hook);
+    return this;
+  }
 
 });
 
@@ -247,55 +247,55 @@ new Type('Type', Type);
 // Default Types
 
 var force = function(name, object, methods){
-	var isType = (object != Object),
-		prototype = object.prototype;
-
-	if (isType) object = new Type(name, object);
-
-	for (var i = 0, l = methods.length; i < l; i++){
-		var key = methods[i],
-			generic = object[key],
-			proto = prototype[key];
-
-		if (generic) generic.protect();
-		if (isType && proto) object.implement(key, proto.protect());
-	}
-
-	if (isType){
-		var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
-		object.forEachMethod = function(fn){
-			if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
-				fn.call(prototype, prototype[methods[i]], methods[i]);
-			}
-			for (var key in prototype) fn.call(prototype, prototype[key], key);
-		};
-	}
-
-	return force;
+  var isType = (object != Object),
+    prototype = object.prototype;
+
+  if (isType) object = new Type(name, object);
+
+  for (var i = 0, l = methods.length; i < l; i++){
+    var key = methods[i],
+      generic = object[key],
+      proto = prototype[key];
+
+    if (generic) generic.protect();
+    if (isType && proto) object.implement(key, proto.protect());
+  }
+
+  if (isType){
+    var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
+    object.forEachMethod = function(fn){
+      if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
+        fn.call(prototype, prototype[methods[i]], methods[i]);
+      }
+      for (var key in prototype) fn.call(prototype, prototype[key], key);
+    };
+  }
+
+  return force;
 };
 
 force('String', String, [
-	'charAt', 'charCodeAt', 'concat', 'contains', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
-	'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
+  'charAt', 'charCodeAt', 'concat', 'contains', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
+  'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
 ])('Array', Array, [
-	'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
-	'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
+  'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice',
+  'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'
 ])('Number', Number, [
-	'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
+  'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
 ])('Function', Function, [
-	'apply', 'call', 'bind'
+  'apply', 'call', 'bind'
 ])('RegExp', RegExp, [
-	'exec', 'test'
+  'exec', 'test'
 ])('Object', Object, [
-	'create', 'defineProperty', 'defineProperties', 'keys',
-	'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
-	'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
+  'create', 'defineProperty', 'defineProperties', 'keys',
+  'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
+  'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
 ])('Date', Date, ['now']);
 
 Object.extend = extend.overloadSetter();
 
 Date.extend('now', function(){
-	return +(new Date);
+  return +(new Date);
 });
 
 new Type('Boolean', Boolean);
@@ -303,102 +303,102 @@ new Type('Boolean', Boolean);
 // fixes NaN returning as Number
 
 Number.prototype.$family = function(){
-	return isFinite(this) ? 'number' : 'null';
+  return isFinite(this) ? 'number' : 'null';
 }.hide();
 
 // Number.random
 
 Number.extend('random', function(min, max){
-	return Math.floor(Math.random() * (max - min + 1) + min);
+  return Math.floor(Math.random() * (max - min + 1) + min);
 });
 
 // forEach, each
 
 var hasOwnProperty = Object.prototype.hasOwnProperty;
 Object.extend('forEach', function(object, fn, bind){
-	for (var key in object){
-		if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
-	}
+  for (var key in object){
+    if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
+  }
 });
 
 Object.each = Object.forEach;
 
 Array.implement({
 
-	/*<!ES5>*/
-	forEach: function(fn, bind){
-		for (var i = 0, l = this.length; i < l; i++){
-			if (i in this) fn.call(bind, this[i], i, this);
-		}
-	},
-	/*</!ES5>*/
+  /*<!ES5>*/
+  forEach: function(fn, bind){
+    for (var i = 0, l = this.length; i < l; i++){
+      if (i in this) fn.call(bind, this[i], i, this);
+    }
+  },
+  /*</!ES5>*/
 
-	each: function(fn, bind){
-		Array.forEach(this, fn, bind);
-		return this;
-	}
+  each: function(fn, bind){
+    Array.forEach(this, fn, bind);
+    return this;
+  }
 
 });
 
 // Array & Object cloning, Object merging and appending
 
 var cloneOf = function(item){
-	switch (typeOf(item)){
-		case 'array': return item.clone();
-		case 'object': return Object.clone(item);
-		default: return item;
-	}
+  switch (typeOf(item)){
+    case 'array': return item.clone();
+    case 'object': return Object.clone(item);
+    default: return item;
+  }
 };
 
 Array.implement('clone', function(){
-	var i = this.length, clone = new Array(i);
-	while (i--) clone[i] = cloneOf(this[i]);
-	return clone;
+  var i = this.length, clone = new Array(i);
+  while (i--) clone[i] = cloneOf(this[i]);
+  return clone;
 });
 
 var mergeOne = function(source, key, current){
-	switch (typeOf(current)){
-		case 'object':
-			if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
-			else source[key] = Object.clone(current);
-		break;
-		case 'array': source[key] = current.clone(); break;
-		default: source[key] = current;
-	}
-	return source;
+  switch (typeOf(current)){
+    case 'object':
+      if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
+      else source[key] = Object.clone(current);
+    break;
+    case 'array': source[key] = current.clone(); break;
+    default: source[key] = current;
+  }
+  return source;
 };
 
 Object.extend({
 
-	merge: function(source, k, v){
-		if (typeOf(k) == 'string') return mergeOne(source, k, v);
-		for (var i = 1, l = arguments.length; i < l; i++){
-			var object = arguments[i];
-			for (var key in object) mergeOne(source, key, object[key]);
-		}
-		return source;
-	},
-
-	clone: function(object){
-		var clone = {};
-		for (var key in object) clone[key] = cloneOf(object[key]);
-		return clone;
-	},
-
-	append: function(original){
-		for (var i = 1, l = arguments.length; i < l; i++){
-			var extended = arguments[i] || {};
-			for (var key in extended) original[key] = extended[key];
-		}
-		return original;
-	}
+  merge: function(source, k, v){
+    if (typeOf(k) == 'string') return mergeOne(source, k, v);
+    for (var i = 1, l = arguments.length; i < l; i++){
+      var object = arguments[i];
+      for (var key in object) mergeOne(source, key, object[key]);
+    }
+    return source;
+  },
+
+  clone: function(object){
+    var clone = {};
+    for (var key in object) clone[key] = cloneOf(object[key]);
+    return clone;
+  },
+
+  append: function(original){
+    for (var i = 1, l = arguments.length; i < l; i++){
+      var extended = arguments[i] || {};
+      for (var key in extended) original[key] = extended[key];
+    }
+    return original;
+  }
 
 });
 
 // Object-less types
 
 ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){
-	new Type(name);
+  new Type(name);
 });
 
 // Unique ID
@@ -406,7 +406,7 @@ Object.extend({
 var UID = Date.now();
 
 String.extend('uniqueID', function(){
-	return (UID++).toString(36);
+  return (UID++).toString(36);
 });
 
 
@@ -432,155 +432,155 @@ provides: Array
 
 Array.implement({
 
-	/*<!ES5>*/
-	every: function(fn, bind){
-		for (var i = 0, l = this.length >>> 0; i < l; i++){
-			if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
-		}
-		return true;
-	},
-
-	filter: function(fn, bind){
-		var results = [];
-		for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){
-			value = this[i];
-			if (fn.call(bind, value, i, this)) results.push(value);
-		}
-		return results;
-	},
-
-	indexOf: function(item, from){
-		var length = this.length >>> 0;
-		for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){
-			if (this[i] === item) return i;
-		}
-		return -1;
-	},
-
-	map: function(fn, bind){
-		var length = this.length >>> 0, results = Array(length);
-		for (var i = 0; i < length; i++){
-			if (i in this) results[i] = fn.call(bind, this[i], i, this);
-		}
-		return results;
-	},
-
-	some: function(fn, bind){
-		for (var i = 0, l = this.length >>> 0; i < l; i++){
-			if ((i in this) && fn.call(bind, this[i], i, this)) return true;
-		}
-		return false;
-	},
-	/*</!ES5>*/
-
-	clean: function(){
-		return this.filter(function(item){
-			return item != null;
-		});
-	},
-
-	invoke: function(methodName){
-		var args = Array.slice(arguments, 1);
-		return this.map(function(item){
-			return item[methodName].apply(item, args);
-		});
-	},
-
-	associate: function(keys){
-		var obj = {}, length = Math.min(this.length, keys.length);
-		for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
-		return obj;
-	},
-
-	link: function(object){
-		var result = {};
-		for (var i = 0, l = this.length; i < l; i++){
-			for (var key in object){
-				if (object[key](this[i])){
-					result[key] = this[i];
-					delete object[key];
-					break;
-				}
-			}
-		}
-		return result;
-	},
-
-	contains: function(item, from){
-		return this.indexOf(item, from) != -1;
-	},
-
-	append: function(array){
-		this.push.apply(this, array);
-		return this;
-	},
-
-	getLast: function(){
-		return (this.length) ? this[this.length - 1] : null;
-	},
-
-	getRandom: function(){
-		return (this.length) ? this[Number.random(0, this.length - 1)] : null;
-	},
-
-	include: function(item){
-		if (!this.contains(item)) this.push(item);
-		return this;
-	},
-
-	combine: function(array){
-		for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
-		return this;
-	},
-
-	erase: function(item){
-		for (var i = this.length; i--;){
-			if (this[i] === item) this.splice(i, 1);
-		}
-		return this;
-	},
-
-	empty: function(){
-		this.length = 0;
-		return this;
-	},
-
-	flatten: function(){
-		var array = [];
-		for (var i = 0, l = this.length; i < l; i++){
-			var type = typeOf(this[i]);
-			if (type == 'null') continue;
-			array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
-		}
-		return array;
-	},
-
-	pick: function(){
-		for (var i = 0, l = this.length; i < l; i++){
-			if (this[i] != null) return this[i];
-		}
-		return null;
-	},
-
-	hexToRgb: function(array){
-		if (this.length != 3) return null;
-		var rgb = this.map(function(value){
-			if (value.length == 1) value += value;
-			return parseInt(value, 16);
-		});
-		return (array) ? rgb : 'rgb(' + rgb + ')';
-	},
-
-	rgbToHex: function(array){
-		if (this.length < 3) return null;
-		if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
-		var hex = [];
-		for (var i = 0; i < 3; i++){
-			var bit = (this[i] - 0).toString(16);
-			hex.push((bit.length == 1) ? '0' + bit : bit);
-		}
-		return (array) ? hex : '#' + hex.join('');
-	}
+  /*<!ES5>*/
+  every: function(fn, bind){
+    for (var i = 0, l = this.length >>> 0; i < l; i++){
+      if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
+    }
+    return true;
+  },
+
+  filter: function(fn, bind){
+    var results = [];
+    for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){
+      value = this[i];
+      if (fn.call(bind, value, i, this)) results.push(value);
+    }
+    return results;
+  },
+
+  indexOf: function(item, from){
+    var length = this.length >>> 0;
+    for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){
+      if (this[i] === item) return i;
+    }
+    return -1;
+  },
+
+  map: function(fn, bind){
+    var length = this.length >>> 0, results = Array(length);
+    for (var i = 0; i < length; i++){
+      if (i in this) results[i] = fn.call(bind, this[i], i, this);
+    }
+    return results;
+  },
+
+  some: function(fn, bind){
+    for (var i = 0, l = this.length >>> 0; i < l; i++){
+      if ((i in this) && fn.call(bind, this[i], i, this)) return true;
+    }
+    return false;
+  },
+  /*</!ES5>*/
+
+  clean: function(){
+    return this.filter(function(item){
+      return item != null;
+    });
+  },
+
+  invoke: function(methodName){
+    var args = Array.slice(arguments, 1);
+    return this.map(function(item){
+      return item[methodName].apply(item, args);
+    });
+  },
+
+  associate: function(keys){
+    var obj = {}, length = Math.min(this.length, keys.length);
+    for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
+    return obj;
+  },
+
+  link: function(object){
+    var result = {};
+    for (var i = 0, l = this.length; i < l; i++){
+      for (var key in object){
+        if (object[key](this[i])){
+          result[key] = this[i];
+          delete object[key];
+          break;
+        }
+      }
+    }
+    return result;
+  },
+
+  contains: function(item, from){
+    return this.indexOf(item, from) != -1;
+  },
+
+  append: function(array){
+    this.push.apply(this, array);
+    return this;
+  },
+
+  getLast: function(){
+    return (this.length) ? this[this.length - 1] : null;
+  },
+
+  getRandom: function(){
+    return (this.length) ? this[Number.random(0, this.length - 1)] : null;
+  },
+
+  include: function(item){
+    if (!this.contains(item)) this.push(item);
+    return this;
+  },
+
+  combine: function(array){
+    for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
+    return this;
+  },
+
+  erase: function(item){
+    for (var i = this.length; i--;){
+      if (this[i] === item) this.splice(i, 1);
+    }
+    return this;
+  },
+
+  empty: function(){
+    this.length = 0;
+    return this;
+  },
+
+  flatten: function(){
+    var array = [];
+    for (var i = 0, l = this.length; i < l; i++){
+      var type = typeOf(this[i]);
+      if (type == 'null') continue;
+      array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
+    }
+    return array;
+  },
+
+  pick: function(){
+    for (var i = 0, l = this.length; i < l; i++){
+      if (this[i] != null) return this[i];
+    }
+    return null;
+  },
+
+  hexToRgb: function(array){
+    if (this.length != 3) return null;
+    var rgb = this.map(function(value){
+      if (value.length == 1) value += value;
+      return parseInt(value, 16);
+    });
+    return (array) ? rgb : 'rgb(' + rgb + ')';
+  },
+
+  rgbToHex: function(array){
+    if (this.length < 3) return null;
+    if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
+    var hex = [];
+    for (var i = 0; i < 3; i++){
+      var bit = (this[i] - 0).toString(16);
+      hex.push((bit.length == 1) ? '0' + bit : bit);
+    }
+    return (array) ? hex : '#' + hex.join('');
+  }
 
 });
 
@@ -605,70 +605,70 @@ provides: String
 
 String.implement({
 
-	//<!ES6>
-	contains: function(string, index){
-		return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
-	},
-	//</!ES6>
-
-	test: function(regex, params){
-		return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
-	},
-
-	trim: function(){
-		return String(this).replace(/^\s+|\s+$/g, '');
-	},
-
-	clean: function(){
-		return String(this).replace(/\s+/g, ' ').trim();
-	},
-
-	camelCase: function(){
-		return String(this).replace(/-\D/g, function(match){
-			return match.charAt(1).toUpperCase();
-		});
-	},
-
-	hyphenate: function(){
-		return String(this).replace(/[A-Z]/g, function(match){
-			return ('-' + match.charAt(0).toLowerCase());
-		});
-	},
-
-	capitalize: function(){
-		return String(this).replace(/\b[a-z]/g, function(match){
-			return match.toUpperCase();
-		});
-	},
-
-	escapeRegExp: function(){
-		return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
-	},
-
-	toInt: function(base){
-		return parseInt(this, base || 10);
-	},
-
-	toFloat: function(){
-		return parseFloat(this);
-	},
-
-	hexToRgb: function(array){
-		var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
-		return (hex) ? hex.slice(1).hexToRgb(array) : null;
-	},
-
-	rgbToHex: function(array){
-		var rgb = String(this).match(/\d{1,3}/g);
-		return (rgb) ? rgb.rgbToHex(array) : null;
-	},
-
-	substitute: function(object, regexp){
-		return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
-			if (match.charAt(0) == '\\') return match.slice(1);
-			return (object[name] != null) ? object[name] : '';
-		});
-	}
+  //<!ES6>
+  contains: function(string, index){
+    return (index ? String(this).slice(index) : String(this)).indexOf(string) > -1;
+  },
+  //</!ES6>
+
+  test: function(regex, params){
+    return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this);
+  },
+
+  trim: function(){
+    return String(this).replace(/^\s+|\s+$/g, '');
+  },
+
+  clean: function(){
+    return String(this).replace(/\s+/g, ' ').trim();
+  },
+
+  camelCase: function(){
+    return String(this).replace(/-\D/g, function(match){
+      return match.charAt(1).toUpperCase();
+    });
+  },
+
+  hyphenate: function(){
+    return String(this).replace(/[A-Z]/g, function(match){
+      return ('-' + match.charAt(0).toLowerCase());
+    });
+  },
+
+  capitalize: function(){
+    return String(this).replace(/\b[a-z]/g, function(match){
+      return match.toUpperCase();
+    });
+  },
+
+  escapeRegExp: function(){
+    return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
+  },
+
+  toInt: function(base){
+    return parseInt(this, base || 10);
+  },
+
+  toFloat: function(){
+    return parseFloat(this);
+  },
+
+  hexToRgb: function(array){
+    var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
+    return (hex) ? hex.slice(1).hexToRgb(array) : null;
+  },
+
+  rgbToHex: function(array){
+    var rgb = String(this).match(/\d{1,3}/g);
+    return (rgb) ? rgb.rgbToHex(array) : null;
+  },
+
+  substitute: function(object, regexp){
+    return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
+      if (match.charAt(0) == '\\') return match.slice(1);
+      return (object[name] != null) ? object[name] : '';
+    });
+  }
 
 });
 
@@ -693,39 +693,39 @@ provides: Number
 
 Number.implement({
 
-	limit: function(min, max){
-		return Math.min(max, Math.max(min, this));
-	},
+  limit: function(min, max){
+    return Math.min(max, Math.max(min, this));
+  },
 
-	round: function(precision){
-		precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
-		return Math.round(this * precision) / precision;
-	},
+  round: function(precision){
+    precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
+    return Math.round(this * precision) / precision;
+  },
 
-	times: function(fn, bind){
-		for (var i = 0; i < this; i++) fn.call(bind, i, this);
-	},
+  times: function(fn, bind){
+    for (var i = 0; i < this; i++) fn.call(bind, i, this);
+  },
 
-	toFloat: function(){
-		return parseFloat(this);
-	},
+  toFloat: function(){
+    return parseFloat(this);
+  },
 
-	toInt: function(base){
-		return parseInt(this, base || 10);
-	}
+  toInt: function(base){
+    return parseInt(this, base || 10);
+  }
 
 });
 
 Number.alias('each', 'times');
 
 (function(math){
-	var methods = {};
-	math.each(function(name){
-		if (!Number[name]) methods[name] = function(){
-			return Math[name].apply(null, [this].concat(Array.from(arguments)));
-		};
-	});
-	Number.implement(methods);
+  var methods = {};
+  math.each(function(name){
+    if (!Number[name]) methods[name] = function(){
+      return Math[name].apply(null, [this].concat(Array.from(arguments)));
+    };
+  });
+  Number.implement(methods);
 })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
 
 
@@ -747,63 +747,63 @@ provides: Function
 
 Function.extend({
 
-	attempt: function(){
-		for (var i = 0, l = arguments.length; i < l; i++){
-			try {
-				return arguments[i]();
-			} catch (e){}
-		}
-		return null;
-	}
+  attempt: function(){
+    for (var i = 0, l = arguments.length; i < l; i++){
+      try {
+        return arguments[i]();
+      } catch (e){}
+    }
+    return null;
+  }
 
 });
 
 Function.implement({
 
-	attempt: function(args, bind){
-		try {
-			return this.apply(bind, Array.from(args));
-		} catch (e){}
-
-		return null;
-	},
-
-	/*<!ES5-bind>*/
-	bind: function(that){
-		var self = this,
-			args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
-			F = function(){};
-
-		var bound = function(){
-			var context = that, length = arguments.length;
-			if (this instanceof bound){
-				F.prototype = self.prototype;
-				context = new F;
-			}
-			var result = (!args && !length)
-				? self.call(context)
-				: self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
-			return context == that ? result : context;
-		};
-		return bound;
-	},
-	/*</!ES5-bind>*/
-
-	pass: function(args, bind){
-		var self = this;
-		if (args != null) args = Array.from(args);
-		return function(){
-			return self.apply(bind, args || arguments);
-		};
-	},
-
-	delay: function(delay, bind, args){
-		return setTimeout(this.pass((args == null ? [] : args), bind), delay);
-	},
-
-	periodical: function(periodical, bind, args){
-		return setInterval(this.pass((args == null ? [] : args), bind), periodical);
-	}
+  attempt: function(args, bind){
+    try {
+      return this.apply(bind, Array.from(args));
+    } catch (e){}
+
+    return null;
+  },
+
+  /*<!ES5-bind>*/
+  bind: function(that){
+    var self = this,
+      args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
+      F = function(){};
+
+    var bound = function(){
+      var context = that, length = arguments.length;
+      if (this instanceof bound){
+        F.prototype = self.prototype;
+        context = new F;
+      }
+      var result = (!args && !length)
+        ? self.call(context)
+        : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments);
+      return context == that ? result : context;
+    };
+    return bound;
+  },
+  /*</!ES5-bind>*/
+
+  pass: function(args, bind){
+    var self = this;
+    if (args != null) args = Array.from(args);
+    return function(){
+      return self.apply(bind, args || arguments);
+    };
+  },
+
+  delay: function(delay, bind, args){
+    return setTimeout(this.pass((args == null ? [] : args), bind), delay);
+  },
+
+  periodical: function(periodical, bind, args){
+    return setInterval(this.pass((args == null ? [] : args), bind), periodical);
+  }
 
 });
 
@@ -832,99 +832,99 @@ var hasOwnProperty = Object.prototype.hasOwnProperty;
 
 Object.extend({
 
-	subset: function(object, keys){
-		var results = {};
-		for (var i = 0, l = keys.length; i < l; i++){
-			var k = keys[i];
-			if (k in object) results[k] = object[k];
-		}
-		return results;
-	},
-
-	map: function(object, fn, bind){
-		var results = {};
-		for (var key in object){
-			if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);
-		}
-		return results;
-	},
-
-	filter: function(object, fn, bind){
-		var results = {};
-		for (var key in object){
-			var value = object[key];
-			if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
-		}
-		return results;
-	},
-
-	every: function(object, fn, bind){
-		for (var key in object){
-			if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
-		}
-		return true;
-	},
-
-	some: function(object, fn, bind){
-		for (var key in object){
-			if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;
-		}
-		return false;
-	},
-
-	keys: function(object){
-		var keys = [];
-		for (var key in object){
-			if (hasOwnProperty.call(object, key)) keys.push(key);
-		}
-		return keys;
-	},
-
-	values: function(object){
-		var values = [];
-		for (var key in object){
-			if (hasOwnProperty.call(object, key)) values.push(object[key]);
-		}
-		return values;
-	},
-
-	getLength: function(object){
-		return Object.keys(object).length;
-	},
-
-	keyOf: function(object, value){
-		for (var key in object){
-			if (hasOwnProperty.call(object, key) && object[key] === value) return key;
-		}
-		return null;
-	},
-
-	contains: function(object, value){
-		return Object.keyOf(object, value) != null;
-	},
-
-	toQueryString: function(object, base){
-		var queryString = [];
-
-		Object.each(object, function(value, key){
-			if (base) key = base + '[' + key + ']';
-			var result;
-			switch (typeOf(value)){
-				case 'object': result = Object.toQueryString(value, key); break;
-				case 'array':
-					var qs = {};
-					value.each(function(val, i){
-						qs[i] = val;
-					});
-					result = Object.toQueryString(qs, key);
-				break;
-				default: result = key + '=' + encodeURIComponent(value);
-			}
-			if (value != null) queryString.push(result);
-		});
-
-		return queryString.join('&');
-	}
+  subset: function(object, keys){
+    var results = {};
+    for (var i = 0, l = keys.length; i < l; i++){
+      var k = keys[i];
+      if (k in object) results[k] = object[k];
+    }
+    return results;
+  },
+
+  map: function(object, fn, bind){
+    var results = {};
+    for (var key in object){
+      if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object);
+    }
+    return results;
+  },
+
+  filter: function(object, fn, bind){
+    var results = {};
+    for (var key in object){
+      var value = object[key];
+      if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
+    }
+    return results;
+  },
+
+  every: function(object, fn, bind){
+    for (var key in object){
+      if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
+    }
+    return true;
+  },
+
+  some: function(object, fn, bind){
+    for (var key in object){
+      if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true;
+    }
+    return false;
+  },
+
+  keys: function(object){
+    var keys = [];
+    for (var key in object){
+      if (hasOwnProperty.call(object, key)) keys.push(key);
+    }
+    return keys;
+  },
+
+  values: function(object){
+    var values = [];
+    for (var key in object){
+      if (hasOwnProperty.call(object, key)) values.push(object[key]);
+    }
+    return values;
+  },
+
+  getLength: function(object){
+    return Object.keys(object).length;
+  },
+
+  keyOf: function(object, value){
+    for (var key in object){
+      if (hasOwnProperty.call(object, key) && object[key] === value) return key;
+    }
+    return null;
+  },
+
+  contains: function(object, value){
+    return Object.keyOf(object, value) != null;
+  },
+
+  toQueryString: function(object, base){
+    var queryString = [];
+
+    Object.each(object, function(value, key){
+      if (base) key = base + '[' + key + ']';
+      var result;
+      switch (typeOf(value)){
+        case 'object': result = Object.toQueryString(value, key); break;
+        case 'array':
+          var qs = {};
+          value.each(function(val, i){
+            qs[i] = val;
+          });
+          result = Object.toQueryString(qs, key);
+        break;
+        default: result = key + '=' + encodeURIComponent(value);
+      }
+      if (value != null) queryString.push(result);
+    });
+
+    return queryString.join('&');
+  }
 
 });
 
@@ -955,43 +955,43 @@ var document = this.document;
 var window = document.window = this;
 
 var parse = function(ua, platform){
-	ua = ua.toLowerCase();
-	platform = (platform ? platform.toLowerCase() : '');
-
-	var UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [null, 'unknown', 0];
-
-	if (UA[1] == 'trident'){
-		UA[1] = 'ie';
-		if (UA[4]) UA[2] = UA[4];
-	} else if (UA[1] == 'crios') {
-		UA[1] = 'chrome';
-	}
-
-	var platform = ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0];
-	if (platform == 'win') platform = 'windows';
-
-	return {
-		extend: Function.prototype.extend,
-		name: (UA[1] == 'version') ? UA[3] : UA[1],
-		version: parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
-		platform: platform
-	};
+  ua = ua.toLowerCase();
+  platform = (platform ? platform.toLowerCase() : '');
+
+  var UA = ua.match(/(opera|ie|firefox|chrome|trident|crios|version)[\s\/:]([\w\d\.]+)?.*?(safari|(?:rv[\s\/:]|version[\s\/:])([\w\d\.]+)|$)/) || [null, 'unknown', 0];
+
+  if (UA[1] == 'trident'){
+    UA[1] = 'ie';
+    if (UA[4]) UA[2] = UA[4];
+  } else if (UA[1] == 'crios') {
+    UA[1] = 'chrome';
+  }
+
+  var platform = ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0];
+  if (platform == 'win') platform = 'windows';
+
+  return {
+    extend: Function.prototype.extend,
+    name: (UA[1] == 'version') ? UA[3] : UA[1],
+    version: parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
+    platform: platform
+  };
 };
 
 var Browser = this.Browser = parse(navigator.userAgent, navigator.platform);
 
 if (Browser.ie){
-	Browser.version = document.documentMode;
+  Browser.version = document.documentMode;
 }
 
 Browser.extend({
-	Features: {
-		xpath: !!(document.evaluate),
-		air: !!(window.runtime),
-		query: !!(document.querySelector),
-		json: !!(window.JSON)
-	},
-	parseUA: parse
+  Features: {
+    xpath: !!(document.evaluate),
+    air: !!(window.runtime),
+    query: !!(document.querySelector),
+    json: !!(window.JSON)
+  },
+  parseUA: parse
 });
 
 
@@ -1000,28 +1000,28 @@ Browser.extend({
 
 Browser.Request = (function(){
 
-	var XMLHTTP = function(){
-		return new XMLHttpRequest();
-	};
-
-	var MSXML2 = function(){
-		return new ActiveXObject('MSXML2.XMLHTTP');
-	};
-
-	var MSXML = function(){
-		return new ActiveXObject('Microsoft.XMLHTTP');
-	};
-
-	return Function.attempt(function(){
-		XMLHTTP();
-		return XMLHTTP;
-	}, function(){
-		MSXML2();
-		return MSXML2;
-	}, function(){
-		MSXML();
-		return MSXML;
-	});
+  var XMLHTTP = function(){
+    return new XMLHttpRequest();
+  };
+
+  var MSXML2 = function(){
+    return new ActiveXObject('MSXML2.XMLHTTP');
+  };
+
+  var MSXML = function(){
+    return new ActiveXObject('Microsoft.XMLHTTP');
+  };
+
+  return Function.attempt(function(){
+    XMLHTTP();
+    return XMLHTTP;
+  }, function(){
+    MSXML2();
+    return MSXML2;
+  }, function(){
+    MSXML();
+    return MSXML;
+  });
 
 })();
 
@@ -1032,37 +1032,37 @@ Browser.Features.xhr = !!(Browser.Request);
 // String scripts
 
 Browser.exec = function(text){
-	if (!text) return text;
-	if (window.execScript){
-		window.execScript(text);
-	} else {
-		var script = document.createElement('script');
-		script.setAttribute('type', 'text/javascript');
-		script.text = text;
-		document.head.appendChild(script);
-		document.head.removeChild(script);
-	}
-	return text;
+  if (!text) return text;
+  if (window.execScript){
+    window.execScript(text);
+  } else {
+    var script = document.createElement('script');
+    script.setAttribute('type', 'text/javascript');
+    script.text = text;
+    document.head.appendChild(script);
+    document.head.removeChild(script);
+  }
+  return text;
 };
 
 String.implement('stripScripts', function(exec){
-	var scripts = '';
-	var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
-		scripts += code + '\n';
-		return '';
-	});
-	if (exec === true) Browser.exec(scripts);
-	else if (typeOf(exec) == 'function') exec(scripts, text);
-	return text;
+  var scripts = '';
+  var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){
+    scripts += code + '\n';
+    return '';
+  });
+  if (exec === true) Browser.exec(scripts);
+  else if (typeOf(exec) == 'function') exec(scripts, text);
+  return text;
 });
 
 // Window, Document
 
 Browser.extend({
-	Document: this.Document,
-	Window: this.Window,
-	Element: this.Element,
-	Event: this.Event
+  Document: this.Document,
+  Window: this.Window,
+  Element: this.Element,
+  Event: this.Event
 });
 
 this.Window = this.$constructor = new Type('Window', function(){});
@@ -1070,7 +1070,7 @@ this.Window = this.$constructor = new Type('Window', function(){});
 this.$family = Function.from('window').hide();
 
 Window.mirror(function(name, method){
-	window[name] = method;
+  window[name] = method;
 });
 
 this.Document = document.$constructor = new Type('Document', function(){});
@@ -1078,47 +1078,47 @@ this.Document = document.$constructor = new Type('Document', function(){});
 document.$family = Function.from('document').hide();
 
 Document.mirror(function(name, method){
-	document[name] = method;
+  document[name] = method;
 });
 
 document.html = document.documentElement;
 if (!document.head) document.head = document.getElementsByTagName('head')[0];
 
 if (document.execCommand) try {
-	document.execCommand("BackgroundImageCache", false, true);
+  document.execCommand("BackgroundImageCache", false, true);
 } catch (e){}
 
 /*<ltIE9>*/
 if (this.attachEvent && !this.addEventListener){
-	var unloadEvent = function(){
-		this.detachEvent('onunload', unloadEvent);
-		document.head = document.html = document.window = null;
-	};
-	this.attachEvent('onunload', unloadEvent);
+  var unloadEvent = function(){
+    this.detachEvent('onunload', unloadEvent);
+    document.head = document.html = document.window = null;
+  };
+  this.attachEvent('onunload', unloadEvent);
 }
 
 // IE fails on collections and <select>.options (refers to <select>)
 var arrayFrom = Array.from;
 try {
-	arrayFrom(document.html.childNodes);
+  arrayFrom(document.html.childNodes);
 } catch(e){
-	Array.from = function(item){
-		if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
-			var i = item.length, array = new Array(i);
-			while (i--) array[i] = item[i];
-			return array;
-		}
-		return arrayFrom(item);
-	};
-
-	var prototype = Array.prototype,
-		slice = prototype.slice;
-	['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
-		var method = prototype[name];
-		Array[name] = function(item){
-			return method.apply(Array.from(item), slice.call(arguments, 1));
-		};
-	});
+  Array.from = function(item){
+    if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){
+      var i = item.length, array = new Array(i);
+      while (i--) array[i] = item[i];
+      return array;
+    }
+    return arrayFrom(item);
+  };
+
+  var prototype = Array.prototype,
+    slice = prototype.slice;
+  ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){
+    var method = prototype[name];
+    Array[name] = function(item){
+      return method.apply(Array.from(item), slice.call(arguments, 1));
+    };
+  });
 }
 /*</ltIE9>*/
 
@@ -1148,96 +1148,96 @@ provides: Event
 var _keys = {};
 
 var DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){
-	if (!win) win = window;
-	event = event || win.event;
-	if (event.$extended) return event;
-	this.event = event;
-	this.$extended = true;
-	this.shift = event.shiftKey;
-	this.control = event.ctrlKey;
-	this.alt = event.altKey;
-	this.meta = event.metaKey;
-	var type = this.type = event.type;
-	var target = event.target || event.srcElement;
-	while (target && target.nodeType == 3) target = target.parentNode;
-	this.target = document.id(target);
-
-	if (type.indexOf('key') == 0){
-		var code = this.code = (event.which || event.keyCode);
-		this.key = _keys[code];
-		if (type == 'keydown' || type == 'keyup'){
-			if (code > 111 && code < 124) this.key = 'f' + (code - 111);
-			else if (code > 95 && code < 106) this.key = code - 96;
-		}
-		if (this.key == null) this.key = String.fromCharCode(code).toLowerCase();
-	} else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
-		var doc = win.document;
-		doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
-		this.page = {
-			x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
-			y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
-		};
-		this.client = {
-			x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
-			y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
-		};
-		if (type == 'DOMMouseScroll' || type == 'mousewheel')
-			this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
-
-		this.rightClick = (event.which == 3 || event.button == 2);
-		if (type == 'mouseover' || type == 'mouseout'){
-			var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
-			while (related && related.nodeType == 3) related = related.parentNode;
-			this.relatedTarget = document.id(related);
-		}
-	} else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
-		this.rotation = event.rotation;
-		this.scale = event.scale;
-		this.targetTouches = event.targetTouches;
-		this.changedTouches = event.changedTouches;
-		var touches = this.touches = event.touches;
-		if (touches && touches[0]){
-			var touch = touches[0];
-			this.page = {x: touch.pageX, y: touch.pageY};
-			this.client = {x: touch.clientX, y: touch.clientY};
-		}
-	}
-
-	if (!this.client) this.client = {};
-	if (!this.page) this.page = {};
+  if (!win) win = window;
+  event = event || win.event;
+  if (event.$extended) return event;
+  this.event = event;
+  this.$extended = true;
+  this.shift = event.shiftKey;
+  this.control = event.ctrlKey;
+  this.alt = event.altKey;
+  this.meta = event.metaKey;
+  var type = this.type = event.type;
+  var target = event.target || event.srcElement;
+  while (target && target.nodeType == 3) target = target.parentNode;
+  this.target = document.id(target);
+
+  if (type.indexOf('key') == 0){
+    var code = this.code = (event.which || event.keyCode);
+    this.key = _keys[code];
+    if (type == 'keydown' || type == 'keyup'){
+      if (code > 111 && code < 124) this.key = 'f' + (code - 111);
+      else if (code > 95 && code < 106) this.key = code - 96;
+    }
+    if (this.key == null) this.key = String.fromCharCode(code).toLowerCase();
+  } else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
+    var doc = win.document;
+    doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
+    this.page = {
+      x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
+      y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
+    };
+    this.client = {
+      x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
+      y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
+    };
+    if (type == 'DOMMouseScroll' || type == 'mousewheel')
+      this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
+
+    this.rightClick = (event.which == 3 || event.button == 2);
+    if (type == 'mouseover' || type == 'mouseout'){
+      var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
+      while (related && related.nodeType == 3) related = related.parentNode;
+      this.relatedTarget = document.id(related);
+    }
+  } else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
+    this.rotation = event.rotation;
+    this.scale = event.scale;
+    this.targetTouches = event.targetTouches;
+    this.changedTouches = event.changedTouches;
+    var touches = this.touches = event.touches;
+    if (touches && touches[0]){
+      var touch = touches[0];
+      this.page = {x: touch.pageX, y: touch.pageY};
+      this.client = {x: touch.clientX, y: touch.clientY};
+    }
+  }
+
+  if (!this.client) this.client = {};
+  if (!this.page) this.page = {};
 });
 
 DOMEvent.implement({
 
-	stop: function(){
-		return this.preventDefault().stopPropagation();
-	},
+  stop: function(){
+    return this.preventDefault().stopPropagation();
+  },
 
-	stopPropagation: function(){
-		if (this.event.stopPropagation) this.event.stopPropagation();
-		else this.event.cancelBubble = true;
-		return this;
-	},
+  stopPropagation: function(){
+    if (this.event.stopPropagation) this.event.stopPropagation();
+    else this.event.cancelBubble = true;
+    return this;
+  },
 
-	preventDefault: function(){
-		if (this.event.preventDefault) this.event.preventDefault();
-		else this.event.returnValue = false;
-		return this;
-	}
+  preventDefault: function(){
+    if (this.event.preventDefault) this.event.preventDefault();
+    else this.event.returnValue = false;
+    return this;
+  }
 
 });
 
 DOMEvent.defineKey = function(code, key){
-	_keys[code] = key;
-	return this;
+  _keys[code] = key;
+  return this;
 };
 
 DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);
 
 DOMEvent.defineKeys({
-	'38': 'up', '40': 'down', '37': 'left', '39': 'right',
-	'27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
-	'46': 'delete', '13': 'enter'
+  '38': 'up', '40': 'down', '37': 'left', '39': 'right',
+  '27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
+  '46': 'delete', '13': 'enter'
 });
 
 })();
@@ -1266,99 +1266,99 @@ provides: Class
 (function(){
 
 var Class = this.Class = new Type('Class', function(params){
-	if (instanceOf(params, Function)) params = {initialize: params};
-
-	var newClass = function(){
-		reset(this);
-		if (newClass.$prototyping) return this;
-		this.$caller = null;
-		var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
-		this.$caller = this.caller = null;
-		return value;
-	}.extend(this).implement(params);
-
-	newClass.$constructor = Class;
-	newClass.prototype.$constructor = newClass;
-	newClass.prototype.parent = parent;
-
-	return newClass;
+  if (instanceOf(params, Function)) params = {initialize: params};
+
+  var newClass = function(){
+    reset(this);
+    if (newClass.$prototyping) return this;
+    this.$caller = null;
+    var value = (this.initialize) ? this.initialize.apply(this, arguments) : this;
+    this.$caller = this.caller = null;
+    return value;
+  }.extend(this).implement(params);
+
+  newClass.$constructor = Class;
+  newClass.prototype.$constructor = newClass;
+  newClass.prototype.parent = parent;
+
+  return newClass;
 });
 
 var parent = function(){
-	if (!this.$caller) throw new Error('The method "parent" cannot be called.');
-	var name = this.$caller.$name,
-		parent = this.$caller.$owner.parent,
-		previous = (parent) ? parent.prototype[name] : null;
-	if (!previous) throw new Error('The method "' + name + '" has no parent.');
-	return previous.apply(this, arguments);
+  if (!this.$caller) throw new Error('The method "parent" cannot be called.');
+  var name = this.$caller.$name,
+    parent = this.$caller.$owner.parent,
+    previous = (parent) ? parent.prototype[name] : null;
+  if (!previous) throw new Error('The method "' + name + '" has no parent.');
+  return previous.apply(this, arguments);
 };
 
 var reset = function(object){
-	for (var key in object){
-		var value = object[key];
-		switch (typeOf(value)){
-			case 'object':
-				var F = function(){};
-				F.prototype = value;
-				object[key] = reset(new F);
-			break;
-			case 'array': object[key] = value.clone(); break;
-		}
-	}
-	return object;
+  for (var key in object){
+    var value = object[key];
+    switch (typeOf(value)){
+      case 'object':
+        var F = function(){};
+        F.prototype = value;
+        object[key] = reset(new F);
+      break;
+      case 'array': object[key] = value.clone(); break;
+    }
+  }
+  return object;
 };
 
 var wrap = function(self, key, method){
-	if (method.$origin) method = method.$origin;
-	var wrapper = function(){
-		if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
-		var caller = this.caller, current = this.$caller;
-		this.caller = current; this.$caller = wrapper;
-		var result = method.apply(this, arguments);
-		this.$caller = current; this.caller = caller;
-		return result;
-	}.extend({$owner: self, $origin: method, $name: key});
-	return wrapper;
+  if (method.$origin) method = method.$origin;
+  var wrapper = function(){
+    if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.');
+    var caller = this.caller, current = this.$caller;
+    this.caller = current; this.$caller = wrapper;
+    var result = method.apply(this, arguments);
+    this.$caller = current; this.caller = caller;
+    return result;
+  }.extend({$owner: self, $origin: method, $name: key});
+  return wrapper;
 };
 
 var implement = function(key, value, retain){
-	if (Class.Mutators.hasOwnProperty(key)){
-		value = Class.Mutators[key].call(this, value);
-		if (value == null) return this;
-	}
-
-	if (typeOf(value) == 'function'){
-		if (value.$hidden) return this;
-		this.prototype[key] = (retain) ? value : wrap(this, key, value);
-	} else {
-		Object.merge(this.prototype, key, value);
-	}
-
-	return this;
+  if (Class.Mutators.hasOwnProperty(key)){
+    value = Class.Mutators[key].call(this, value);
+    if (value == null) return this;
+  }
+
+  if (typeOf(value) == 'function'){
+    if (value.$hidden) return this;
+    this.prototype[key] = (retain) ? value : wrap(this, key, value);
+  } else {
+    Object.merge(this.prototype, key, value);
+  }
+
+  return this;
 };
 
 var getInstance = function(klass){
-	klass.$prototyping = true;
-	var proto = new klass;
-	delete klass.$prototyping;
-	return proto;
+  klass.$prototyping = true;
+  var proto = new klass;
+  delete klass.$prototyping;
+  return proto;
 };
 
 Class.implement('implement', implement.overloadSetter());
 
 Class.Mutators = {
 
-	Extends: function(parent){
-		this.parent = parent;
-		this.prototype = getInstance(parent);
-	},
-
-	Implements: function(items){
-		Array.from(items).each(function(item){
-			var instance = new item;
-			for (var key in instance) implement.call(this, key, instance[key], true);
-		}, this);
-	}
+  Extends: function(parent){
+    this.parent = parent;
+    this.prototype = getInstance(parent);
+  },
+
+  Implements: function(items){
+    Array.from(items).each(function(item){
+      var instance = new item;
+      for (var key in instance) implement.call(this, key, instance[key], true);
+    }, this);
+  }
 };
 
 })();
@@ -1384,101 +1384,101 @@ provides: [Class.Extras, Chain, Events, Options]
 
 this.Chain = new Class({
 
-	$chain: [],
+  $chain: [],
 
-	chain: function(){
-		this.$chain.append(Array.flatten(arguments));
-		return this;
-	},
+  chain: function(){
+    this.$chain.append(Array.flatten(arguments));
+    return this;
+  },
 
-	callChain: function(){
-		return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
-	},
+  callChain: function(){
+    return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false;
+  },
 
-	clearChain: function(){
-		this.$chain.empty();
-		return this;
-	}
+  clearChain: function(){
+    this.$chain.empty();
+    return this;
+  }
 
 });
 
 var removeOn = function(string){
-	return string.replace(/^on([A-Z])/, function(full, first){
-		return first.toLowerCase();
-	});
+  return string.replace(/^on([A-Z])/, function(full, first){
+    return first.toLowerCase();
+  });
 };
 
 this.Events = new Class({
 
-	$events: {},
-
-	addEvent: function(type, fn, internal){
-		type = removeOn(type);
-
-		
-
-		this.$events[type] = (this.$events[type] || []).include(fn);
-		if (internal) fn.internal = true;
-		return this;
-	},
-
-	addEvents: function(events){
-		for (var type in events) this.addEvent(type, events[type]);
-		return this;
-	},
-
-	fireEvent: function(type, args, delay){
-		type = removeOn(type);
-		var events = this.$events[type];
-		if (!events) return this;
-		args = Array.from(args);
-		events.each(function(fn){
-			if (delay) fn.delay(delay, this, args);
-			else fn.apply(this, args);
-		}, this);
-		return this;
-	},
-
-	removeEvent: function(type, fn){
-		type = removeOn(type);
-		var events = this.$events[type];
-		if (events && !fn.internal){
-			var index =  events.indexOf(fn);
-			if (index != -1) delete events[index];
-		}
-		return this;
-	},
-
-	removeEvents: function(events){
-		var type;
-		if (typeOf(events) == 'object'){
-			for (type in events) this.removeEvent(type, events[type]);
-			return this;
-		}
-		if (events) events = removeOn(events);
-		for (type in this.$events){
-			if (events && events != type) continue;
-			var fns = this.$events[type];
-			for (var i = fns.length; i--;) if (i in fns){
-				this.removeEvent(type, fns[i]);
-			}
-		}
-		return this;
-	}
+  $events: {},
+
+  addEvent: function(type, fn, internal){
+    type = removeOn(type);
+
+    
+
+    this.$events[type] = (this.$events[type] || []).include(fn);
+    if (internal) fn.internal = true;
+    return this;
+  },
+
+  addEvents: function(events){
+    for (var type in events) this.addEvent(type, events[type]);
+    return this;
+  },
+
+  fireEvent: function(type, args, delay){
+    type = removeOn(type);
+    var events = this.$events[type];
+    if (!events) return this;
+    args = Array.from(args);
+    events.each(function(fn){
+      if (delay) fn.delay(delay, this, args);
+      else fn.apply(this, args);
+    }, this);
+    return this;
+  },
+
+  removeEvent: function(type, fn){
+    type = removeOn(type);
+    var events = this.$events[type];
+    if (events && !fn.internal){
+      var index =  events.indexOf(fn);
+      if (index != -1) delete events[index];
+    }
+    return this;
+  },
+
+  removeEvents: function(events){
+    var type;
+    if (typeOf(events) == 'object'){
+      for (type in events) this.removeEvent(type, events[type]);
+      return this;
+    }
+    if (events) events = removeOn(events);
+    for (type in this.$events){
+      if (events && events != type) continue;
+      var fns = this.$events[type];
+      for (var i = fns.length; i--;) if (i in fns){
+        this.removeEvent(type, fns[i]);
+      }
+    }
+    return this;
+  }
 
 });
 
 this.Options = new Class({
 
-	setOptions: function(){
-		var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
-		if (this.addEvent) for (var option in options){
-			if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
-			this.addEvent(option, options[option]);
-			delete options[option];
-		}
-		return this;
-	}
+  setOptions: function(){
+    var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
+    if (this.addEvent) for (var option in options){
+      if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
+      this.addEvent(option, options[option]);
+      delete options[option];
+    }
+    return this;
+  }
 
 });
 
@@ -1496,63 +1496,63 @@ provides: Slick.Parser
 ;(function(){
 
 var parsed,
-	separatorIndex,
-	combinatorIndex,
-	reversed,
-	cache = {},
-	reverseCache = {},
-	reUnescape = /\\/g;
+  separatorIndex,
+  combinatorIndex,
+  reversed,
+  cache = {},
+  reverseCache = {},
+  reUnescape = /\\/g;
 
 var parse = function(expression, isReversed){
-	if (expression == null) return null;
-	if (expression.Slick === true) return expression;
-	expression = ('' + expression).replace(/^\s+|\s+$/g, '');
-	reversed = !!isReversed;
-	var currentCache = (reversed) ? reverseCache : cache;
-	if (currentCache[expression]) return currentCache[expression];
-	parsed = {
-		Slick: true,
-		expressions: [],
-		raw: expression,
-		reverse: function(){
-			return parse(this.raw, true);
-		}
-	};
-	separatorIndex = -1;
-	while (expression != (expression = expression.replace(regexp, parser)));
-	parsed.length = parsed.expressions.length;
-	return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
+  if (expression == null) return null;
+  if (expression.Slick === true) return expression;
+  expression = ('' + expression).replace(/^\s+|\s+$/g, '');
+  reversed = !!isReversed;
+  var currentCache = (reversed) ? reverseCache : cache;
+  if (currentCache[expression]) return currentCache[expression];
+  parsed = {
+    Slick: true,
+    expressions: [],
+    raw: expression,
+    reverse: function(){
+      return parse(this.raw, true);
+    }
+  };
+  separatorIndex = -1;
+  while (expression != (expression = expression.replace(regexp, parser)));
+  parsed.length = parsed.expressions.length;
+  return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
 };
 
 var reverseCombinator = function(combinator){
-	if (combinator === '!') return ' ';
-	else if (combinator === ' ') return '!';
-	else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
-	else return '!' + combinator;
+  if (combinator === '!') return ' ';
+  else if (combinator === ' ') return '!';
+  else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
+  else return '!' + combinator;
 };
 
 var reverse = function(expression){
-	var expressions = expression.expressions;
-	for (var i = 0; i < expressions.length; i++){
-		var exp = expressions[i];
-		var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
-
-		for (var j = 0; j < exp.length; j++){
-			var cexp = exp[j];
-			if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
-			cexp.combinator = cexp.reverseCombinator;
-			delete cexp.reverseCombinator;
-		}
-
-		exp.reverse().push(last);
-	}
-	return expression;
+  var expressions = expression.expressions;
+  for (var i = 0; i < expressions.length; i++){
+    var exp = expressions[i];
+    var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)};
+
+    for (var j = 0; j < exp.length; j++){
+      var cexp = exp[j];
+      if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
+      cexp.combinator = cexp.reverseCombinator;
+      delete cexp.reverseCombinator;
+    }
+
+    exp.reverse().push(last);
+  }
+  return expression;
 };
 
 var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
-	return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
-		return '\\' + match;
-	});
+  return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
+    return '\\' + match;
+  });
 };
 
 var regexp = new RegExp(
@@ -1560,146 +1560,146 @@ var regexp = new RegExp(
 #!/usr/bin/env ruby
 puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
 __END__
-	"(?x)^(?:\
-	  \\s* ( , ) \\s*               # Separator          \n\
-	| \\s* ( <combinator>+ ) \\s*   # Combinator         \n\
-	|      ( \\s+ )                 # CombinatorChildren \n\
-	|      ( <unicode>+ | \\* )     # Tag                \n\
-	| \\#  ( <unicode>+       )     # ID                 \n\
-	| \\.  ( <unicode>+       )     # ClassName          \n\
-	|                               # Attribute          \n\
-	\\[  \
-		\\s* (<unicode1>+)  (?:  \
-			\\s* ([*^$!~|]?=)  (?:  \
-				\\s* (?:\
-					([\"']?)(.*?)\\9 \
-				)\
-			)  \
-		)?  \\s*  \
-	\\](?!\\]) \n\
-	|   :+ ( <unicode>+ )(?:\
-	\\( (?:\
-		(?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
-	) \\)\
-	)?\
-	)"
+  "(?x)^(?:\
+    \\s* ( , ) \\s*               # Separator          \n\
+  | \\s* ( <combinator>+ ) \\s*   # Combinator         \n\
+  |      ( \\s+ )                 # CombinatorChildren \n\
+  |      ( <unicode>+ | \\* )     # Tag                \n\
+  | \\#  ( <unicode>+       )     # ID                 \n\
+  | \\.  ( <unicode>+       )     # ClassName          \n\
+  |                               # Attribute          \n\
+  \\[  \
+    \\s* (<unicode1>+)  (?:  \
+      \\s* ([*^$!~|]?=)  (?:  \
+        \\s* (?:\
+          ([\"']?)(.*?)\\9 \
+        )\
+      )  \
+    )?  \\s*  \
+  \\](?!\\]) \n\
+  |   :+ ( <unicode>+ )(?:\
+  \\( (?:\
+    (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
+  ) \\)\
+  )?\
+  )"
 */
-	"^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
-	.replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
-	.replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
-	.replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
+  "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)"
+  .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
+  .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
+  .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
 );
 
 function parser(
-	rawMatch,
-
-	separator,
-	combinator,
-	combinatorChildren,
-
-	tagName,
-	id,
-	className,
-
-	attributeKey,
-	attributeOperator,
-	attributeQuote,
-	attributeValue,
-
-	pseudoMarker,
-	pseudoClass,
-	pseudoQuote,
-	pseudoClassQuotedValue,
-	pseudoClassValue
+  rawMatch,
+
+  separator,
+  combinator,
+  combinatorChildren,
+
+  tagName,
+  id,
+  className,
+
+  attributeKey,
+  attributeOperator,
+  attributeQuote,
+  attributeValue,
+
+  pseudoMarker,
+  pseudoClass,
+  pseudoQuote,
+  pseudoClassQuotedValue,
+  pseudoClassValue
 ){
-	if (separator || separatorIndex === -1){
-		parsed.expressions[++separatorIndex] = [];
-		combinatorIndex = -1;
-		if (separator) return '';
-	}
-
-	if (combinator || combinatorChildren || combinatorIndex === -1){
-		combinator = combinator || ' ';
-		var currentSeparator = parsed.expressions[separatorIndex];
-		if (reversed && currentSeparator[combinatorIndex])
-			currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
-		currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
-	}
-
-	var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
-
-	if (tagName){
-		currentParsed.tag = tagName.replace(reUnescape, '');
-
-	} else if (id){
-		currentParsed.id = id.replace(reUnescape, '');
-
-	} else if (className){
-		className = className.replace(reUnescape, '');
-
-		if (!currentParsed.classList) currentParsed.classList = [];
-		if (!currentParsed.classes) currentParsed.classes = [];
-		currentParsed.classList.push(className);
-		currentParsed.classes.push({
-			value: className,
-			regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
-		});
-
-	} else if (pseudoClass){
-		pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
-		pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
-
-		if (!currentParsed.pseudos) currentParsed.pseudos = [];
-		currentParsed.pseudos.push({
-			key: pseudoClass.replace(reUnescape, ''),
-			value: pseudoClassValue,
-			type: pseudoMarker.length == 1 ? 'class' : 'element'
-		});
-
-	} else if (attributeKey){
-		attributeKey = attributeKey.replace(reUnescape, '');
-		attributeValue = (attributeValue || '').replace(reUnescape, '');
-
-		var test, regexp;
-
-		switch (attributeOperator){
-			case '^=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue)            ); break;
-			case '$=' : regexp = new RegExp(            escapeRegExp(attributeValue) +'$'       ); break;
-			case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
-			case '|=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue) +'(-|$)'   ); break;
-			case  '=' : test = function(value){
-				return attributeValue == value;
-			}; break;
-			case '*=' : test = function(value){
-				return value && value.indexOf(attributeValue) > -1;
-			}; break;
-			case '!=' : test = function(value){
-				return attributeValue != value;
-			}; break;
-			default   : test = function(value){
-				return !!value;
-			};
-		}
-
-		if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
-			return false;
-		};
-
-		if (!test) test = function(value){
-			return value && regexp.test(value);
-		};
-
-		if (!currentParsed.attributes) currentParsed.attributes = [];
-		currentParsed.attributes.push({
-			key: attributeKey,
-			operator: attributeOperator,
-			value: attributeValue,
-			test: test
-		});
-
-	}
-
-	return '';
+  if (separator || separatorIndex === -1){
+    parsed.expressions[++separatorIndex] = [];
+    combinatorIndex = -1;
+    if (separator) return '';
+  }
+
+  if (combinator || combinatorChildren || combinatorIndex === -1){
+    combinator = combinator || ' ';
+    var currentSeparator = parsed.expressions[separatorIndex];
+    if (reversed && currentSeparator[combinatorIndex])
+      currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator);
+    currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
+  }
+
+  var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
+
+  if (tagName){
+    currentParsed.tag = tagName.replace(reUnescape, '');
+
+  } else if (id){
+    currentParsed.id = id.replace(reUnescape, '');
+
+  } else if (className){
+    className = className.replace(reUnescape, '');
+
+    if (!currentParsed.classList) currentParsed.classList = [];
+    if (!currentParsed.classes) currentParsed.classes = [];
+    currentParsed.classList.push(className);
+    currentParsed.classes.push({
+      value: className,
+      regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
+    });
+
+  } else if (pseudoClass){
+    pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
+    pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null;
+
+    if (!currentParsed.pseudos) currentParsed.pseudos = [];
+    currentParsed.pseudos.push({
+      key: pseudoClass.replace(reUnescape, ''),
+      value: pseudoClassValue,
+      type: pseudoMarker.length == 1 ? 'class' : 'element'
+    });
+
+  } else if (attributeKey){
+    attributeKey = attributeKey.replace(reUnescape, '');
+    attributeValue = (attributeValue || '').replace(reUnescape, '');
+
+    var test, regexp;
+
+    switch (attributeOperator){
+      case '^=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue)            ); break;
+      case '$=' : regexp = new RegExp(            escapeRegExp(attributeValue) +'$'       ); break;
+      case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break;
+      case '|=' : regexp = new RegExp(       '^'+ escapeRegExp(attributeValue) +'(-|$)'   ); break;
+      case  '=' : test = function(value){
+        return attributeValue == value;
+      }; break;
+      case '*=' : test = function(value){
+        return value && value.indexOf(attributeValue) > -1;
+      }; break;
+      case '!=' : test = function(value){
+        return attributeValue != value;
+      }; break;
+      default   : test = function(value){
+        return !!value;
+      };
+    }
+
+    if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){
+      return false;
+    };
+
+    if (!test) test = function(value){
+      return value && regexp.test(value);
+    };
+
+    if (!currentParsed.attributes) currentParsed.attributes = [];
+    currentParsed.attributes.push({
+      key: attributeKey,
+      operator: attributeOperator,
+      value: attributeValue,
+      test: test
+    });
+
+  }
+
+  return '';
 };
 
 // Slick NS
@@ -1707,7 +1707,7 @@ function parser(
 var Slick = (this.Slick || {});
 
 Slick.parse = function(expression){
-	return parse(expression);
+  return parse(expression);
 };
 
 Slick.escapeRegExp = escapeRegExp;
@@ -1729,456 +1729,456 @@ requires: Slick.Parser
 ;(function(){
 
 var local = {},
-	featuresCache = {},
-	toString = Object.prototype.toString;
+  featuresCache = {},
+  toString = Object.prototype.toString;
 
 // Feature / Bug detection
 
 local.isNativeCode = function(fn){
-	return (/\{\s*\[native code\]\s*\}/).test('' + fn);
+  return (/\{\s*\[native code\]\s*\}/).test('' + fn);
 };
 
 local.isXML = function(document){
-	return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
-	(document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
+  return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
+  (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
 };
 
 local.setDocument = function(document){
 
-	// convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
-	var nodeType = document.nodeType;
-	if (nodeType == 9); // document
-	else if (nodeType) document = document.ownerDocument; // node
-	else if (document.navigator) document = document.document; // window
-	else return;
-
-	// check if it's the old document
-
-	if (this.document === document) return;
-	this.document = document;
-
-	// check if we have done feature detection on this document before
-
-	var root = document.documentElement,
-		rootUid = this.getUIDXML(root),
-		features = featuresCache[rootUid],
-		feature;
-
-	if (features){
-		for (feature in features){
-			this[feature] = features[feature];
-		}
-		return;
-	}
-
-	features = featuresCache[rootUid] = {};
-
-	features.root = root;
-	features.isXMLDocument = this.isXML(document);
-
-	features.brokenStarGEBTN
-	= features.starSelectsClosedQSA
-	= features.idGetsName
-	= features.brokenMixedCaseQSA
-	= features.brokenGEBCN
-	= features.brokenCheckedQSA
-	= features.brokenEmptyAttributeQSA
-	= features.isHTMLDocument
-	= features.nativeMatchesSelector
-	= false;
-
-	var starSelectsClosed, starSelectsComments,
-		brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
-		brokenFormAttributeGetter;
-
-	var selected, id = 'slick_uniqueid';
-	var testNode = document.createElement('div');
-
-	var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
-	testRoot.appendChild(testNode);
-
-	// on non-HTML documents innerHTML and getElementsById doesnt work properly
-	try {
-		testNode.innerHTML = '<a id="'+id+'"></a>';
-		features.isHTMLDocument = !!document.getElementById(id);
-	} catch(e){};
-
-	if (features.isHTMLDocument){
-
-		testNode.style.display = 'none';
-
-		// IE returns comment nodes for getElementsByTagName('*') for some documents
-		testNode.appendChild(document.createComment(''));
-		starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
-
-		// IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
-		try {
-			testNode.innerHTML = 'foo</foo>';
-			selected = testNode.getElementsByTagName('*');
-			starSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
-		} catch(e){};
-
-		features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
-
-		// IE returns elements with the name instead of just id for getElementsById for some documents
-		try {
-			testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>';
-			features.idGetsName = document.getElementById(id) === testNode.firstChild;
-		} catch(e){};
-
-		if (testNode.getElementsByClassName){
-
-			// Safari 3.2 getElementsByClassName caches results
-			try {
-				testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
-				testNode.getElementsByClassName('b').length;
-				testNode.firstChild.className = 'b';
-				cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);
-			} catch(e){};
-
-			// Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
-			try {
-				testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
-				brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);
-			} catch(e){};
-
-			features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
-		}
-
-		if (testNode.querySelectorAll){
-			// IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
-			try {
-				testNode.innerHTML = 'foo</foo>';
-				selected = testNode.querySelectorAll('*');
-				features.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
-			} catch(e){};
-
-			// Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
-			try {
-				testNode.innerHTML = '<a class="MiX"></a>';
-				features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;
-			} catch(e){};
-
-			// Webkit and Opera dont return selected options on querySelectorAll
-			try {
-				testNode.innerHTML = '<select><option selected="selected">a</option></select>';
-				features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);
-			} catch(e){};
-
-			// IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
-			try {
-				testNode.innerHTML = '<a class=""></a>';
-				features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0);
-			} catch(e){};
-
-		}
-
-		// IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input
-		try {
-			testNode.innerHTML = '<form action="s"><input id="action"/></form>';
-			brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');
-		} catch(e){};
-
-		// native matchesSelector function
-
-		features.nativeMatchesSelector = root.matches || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
-		if (features.nativeMatchesSelector) try {
-			// if matchesSelector trows errors on incorrect sintaxes we can use it
-			features.nativeMatchesSelector.call(root, ':slick');
-			features.nativeMatchesSelector = null;
-		} catch(e){};
-
-	}
-
-	try {
-		root.slick_expando = 1;
-		delete root.slick_expando;
-		features.getUID = this.getUIDHTML;
-	} catch(e) {
-		features.getUID = this.getUIDXML;
-	}
-
-	testRoot.removeChild(testNode);
-	testNode = selected = testRoot = null;
-
-	// getAttribute
-
-	features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){
-		var method = this.attributeGetters[name];
-		if (method) return method.call(node);
-		var attributeNode = node.getAttributeNode(name);
-		return (attributeNode) ? attributeNode.nodeValue : null;
-	} : function(node, name){
-		var method = this.attributeGetters[name];
-		return (method) ? method.call(node) : node.getAttribute(name);
-	};
-
-	// hasAttribute
-
-	features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
-		return node.hasAttribute(attribute);
-	} : function(node, attribute) {
-		node = node.getAttributeNode(attribute);
-		return !!(node && (node.specified || node.nodeValue));
-	};
-
-	// contains
-	// FIXME: Add specs: local.contains should be different for xml and html documents?
-	var nativeRootContains = root && this.isNativeCode(root.contains),
-		nativeDocumentContains = document && this.isNativeCode(document.contains);
-
-	features.contains = (nativeRootContains && nativeDocumentContains) ? function(context, node){
-		return context.contains(node);
-	} : (nativeRootContains && !nativeDocumentContains) ? function(context, node){
-		// IE8 does not have .contains on document.
-		return context === node || ((context === document) ? document.documentElement : context).contains(node);
-	} : (root && root.compareDocumentPosition) ? function(context, node){
-		return context === node || !!(context.compareDocumentPosition(node) & 16);
-	} : function(context, node){
-		if (node) do {
-			if (node === context) return true;
-		} while ((node = node.parentNode));
-		return false;
-	};
-
-	// document order sorting
-	// credits to Sizzle (http://sizzlejs.com/)
-
-	features.documentSorter = (root.compareDocumentPosition) ? function(a, b){
-		if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
-		return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
-	} : ('sourceIndex' in root) ? function(a, b){
-		if (!a.sourceIndex || !b.sourceIndex) return 0;
-		return a.sourceIndex - b.sourceIndex;
-	} : (document.createRange) ? function(a, b){
-		if (!a.ownerDocument || !b.ownerDocument) return 0;
-		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
-		aRange.setStart(a, 0);
-		aRange.setEnd(a, 0);
-		bRange.setStart(b, 0);
-		bRange.setEnd(b, 0);
-		return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
-	} : null ;
-
-	root = null;
-
-	for (feature in features){
-		this[feature] = features[feature];
-	}
+  // convert elements / window arguments to document. if document cannot be extrapolated, the function returns.
+  var nodeType = document.nodeType;
+  if (nodeType == 9); // document
+  else if (nodeType) document = document.ownerDocument; // node
+  else if (document.navigator) document = document.document; // window
+  else return;
+
+  // check if it's the old document
+
+  if (this.document === document) return;
+  this.document = document;
+
+  // check if we have done feature detection on this document before
+
+  var root = document.documentElement,
+    rootUid = this.getUIDXML(root),
+    features = featuresCache[rootUid],
+    feature;
+
+  if (features){
+    for (feature in features){
+      this[feature] = features[feature];
+    }
+    return;
+  }
+
+  features = featuresCache[rootUid] = {};
+
+  features.root = root;
+  features.isXMLDocument = this.isXML(document);
+
+  features.brokenStarGEBTN
+  = features.starSelectsClosedQSA
+  = features.idGetsName
+  = features.brokenMixedCaseQSA
+  = features.brokenGEBCN
+  = features.brokenCheckedQSA
+  = features.brokenEmptyAttributeQSA
+  = features.isHTMLDocument
+  = features.nativeMatchesSelector
+  = false;
+
+  var starSelectsClosed, starSelectsComments,
+    brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
+    brokenFormAttributeGetter;
+
+  var selected, id = 'slick_uniqueid';
+  var testNode = document.createElement('div');
+
+  var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
+  testRoot.appendChild(testNode);
+
+  // on non-HTML documents innerHTML and getElementsById doesnt work properly
+  try {
+    testNode.innerHTML = '<a id="'+id+'"></a>';
+    features.isHTMLDocument = !!document.getElementById(id);
+  } catch(e){};
+
+  if (features.isHTMLDocument){
+
+    testNode.style.display = 'none';
+
+    // IE returns comment nodes for getElementsByTagName('*') for some documents
+    testNode.appendChild(document.createComment(''));
+    starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
+
+    // IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents
+    try {
+      testNode.innerHTML = 'foo</foo>';
+      selected = testNode.getElementsByTagName('*');
+      starSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
+    } catch(e){};
+
+    features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
+
+    // IE returns elements with the name instead of just id for getElementsById for some documents
+    try {
+      testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>';
+      features.idGetsName = document.getElementById(id) === testNode.firstChild;
+    } catch(e){};
+
+    if (testNode.getElementsByClassName){
+
+      // Safari 3.2 getElementsByClassName caches results
+      try {
+        testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
+        testNode.getElementsByClassName('b').length;
+        testNode.firstChild.className = 'b';
+        cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2);
+      } catch(e){};
+
+      // Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one
+      try {
+        testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
+        brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2);
+      } catch(e){};
+
+      features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN;
+    }
+
+    if (testNode.querySelectorAll){
+      // IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents
+      try {
+        testNode.innerHTML = 'foo</foo>';
+        selected = testNode.querySelectorAll('*');
+        features.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/');
+      } catch(e){};
+
+      // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
+      try {
+        testNode.innerHTML = '<a class="MiX"></a>';
+        features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;
+      } catch(e){};
+
+      // Webkit and Opera dont return selected options on querySelectorAll
+      try {
+        testNode.innerHTML = '<select><option selected="selected">a</option></select>';
+        features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0);
+      } catch(e){};
+
+      // IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll
+      try {
+        testNode.innerHTML = '<a class=""></a>';
+        features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0);
+      } catch(e){};
+
+    }
+
+    // IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input
+    try {
+      testNode.innerHTML = '<form action="s"><input id="action"/></form>';
+      brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');
+    } catch(e){};
+
+    // native matchesSelector function
+
+    features.nativeMatchesSelector = root.matches || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
+    if (features.nativeMatchesSelector) try {
+      // if matchesSelector trows errors on incorrect sintaxes we can use it
+      features.nativeMatchesSelector.call(root, ':slick');
+      features.nativeMatchesSelector = null;
+    } catch(e){};
+
+  }
+
+  try {
+    root.slick_expando = 1;
+    delete root.slick_expando;
+    features.getUID = this.getUIDHTML;
+  } catch(e) {
+    features.getUID = this.getUIDXML;
+  }
+
+  testRoot.removeChild(testNode);
+  testNode = selected = testRoot = null;
+
+  // getAttribute
+
+  features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){
+    var method = this.attributeGetters[name];
+    if (method) return method.call(node);
+    var attributeNode = node.getAttributeNode(name);
+    return (attributeNode) ? attributeNode.nodeValue : null;
+  } : function(node, name){
+    var method = this.attributeGetters[name];
+    return (method) ? method.call(node) : node.getAttribute(name);
+  };
+
+  // hasAttribute
+
+  features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
+    return node.hasAttribute(attribute);
+  } : function(node, attribute) {
+    node = node.getAttributeNode(attribute);
+    return !!(node && (node.specified || node.nodeValue));
+  };
+
+  // contains
+  // FIXME: Add specs: local.contains should be different for xml and html documents?
+  var nativeRootContains = root && this.isNativeCode(root.contains),
+    nativeDocumentContains = document && this.isNativeCode(document.contains);
+
+  features.contains = (nativeRootContains && nativeDocumentContains) ? function(context, node){
+    return context.contains(node);
+  } : (nativeRootContains && !nativeDocumentContains) ? function(context, node){
+    // IE8 does not have .contains on document.
+    return context === node || ((context === document) ? document.documentElement : context).contains(node);
+  } : (root && root.compareDocumentPosition) ? function(context, node){
+    return context === node || !!(context.compareDocumentPosition(node) & 16);
+  } : function(context, node){
+    if (node) do {
+      if (node === context) return true;
+    } while ((node = node.parentNode));
+    return false;
+  };
+
+  // document order sorting
+  // credits to Sizzle (http://sizzlejs.com/)
+
+  features.documentSorter = (root.compareDocumentPosition) ? function(a, b){
+    if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
+    return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+  } : ('sourceIndex' in root) ? function(a, b){
+    if (!a.sourceIndex || !b.sourceIndex) return 0;
+    return a.sourceIndex - b.sourceIndex;
+  } : (document.createRange) ? function(a, b){
+    if (!a.ownerDocument || !b.ownerDocument) return 0;
+    var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+    aRange.setStart(a, 0);
+    aRange.setEnd(a, 0);
+    bRange.setStart(b, 0);
+    bRange.setEnd(b, 0);
+    return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+  } : null ;
+
+  root = null;
+
+  for (feature in features){
+    this[feature] = features[feature];
+  }
 };
 
 // Main Method
 
 var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/,
-	reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
-	qsaFailExpCache = {};
+  reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
+  qsaFailExpCache = {};
 
 local.search = function(context, expression, append, first){
 
-	var found = this.found = (first) ? null : (append || []);
-
-	if (!context) return found;
-	else if (context.navigator) context = context.document; // Convert the node from a window to a document
-	else if (!context.nodeType) return found;
-
-	// setup
-
-	var parsed, i,
-		uniques = this.uniques = {},
-		hasOthers = !!(append && append.length),
-		contextIsDocument = (context.nodeType == 9);
-
-	if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);
-
-	// avoid duplicating items already in the append array
-	if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true;
-
-	// expression checks
-
-	if (typeof expression == 'string'){ // expression is a string
-
-		/*<simple-selectors-override>*/
-		var simpleSelector = expression.match(reSimpleSelector);
-		simpleSelectors: if (simpleSelector) {
-
-			var symbol = simpleSelector[1],
-				name = simpleSelector[2],
-				node, nodes;
-
-			if (!symbol){
-
-				if (name == '*' && this.brokenStarGEBTN) break simpleSelectors;
-				nodes = context.getElementsByTagName(name);
-				if (first) return nodes[0] || null;
-				for (i = 0; node = nodes[i++];){
-					if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
-				}
-
-			} else if (symbol == '#'){
-
-				if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
-				node = context.getElementById(name);
-				if (!node) return found;
-				if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors;
-				if (first) return node || null;
-				if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
-
-			} else if (symbol == '.'){
-
-				if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors;
-				if (context.getElementsByClassName && !this.brokenGEBCN){
-					nodes = context.getElementsByClassName(name);
-					if (first) return nodes[0] || null;
-					for (i = 0; node = nodes[i++];){
-						if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
-					}
-				} else {
-					var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s|$)');
-					nodes = context.getElementsByTagName('*');
-					for (i = 0; node = nodes[i++];){
-						className = node.className;
-						if (!(className && matchClass.test(className))) continue;
-						if (first) return node;
-						if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
-					}
-				}
-
-			}
-
-			if (hasOthers) this.sort(found);
-			return (first) ? null : found;
-
-		}
-		/*</simple-selectors-override>*/
-
-		/*<query-selector-override>*/
-		querySelector: if (context.querySelectorAll) {
-
-			if (!this.isHTMLDocument
-				|| qsaFailExpCache[expression]
-				//TODO: only skip when expression is actually mixed case
-				|| this.brokenMixedCaseQSA
-				|| (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)
-				|| (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))
-				|| (!contextIsDocument //Abort when !contextIsDocument and...
-					//  there are multiple expressions in the selector
-					//  since we currently only fix non-document rooted QSA for single expression selectors
-					&& expression.indexOf(',') > -1
-				)
-				|| Slick.disableQSA
-			) break querySelector;
-
-			var _expression = expression, _context = context;
-			if (!contextIsDocument){
-				// non-document rooted QSA
-				// credits to Andrew Dupont
-				var currentId = _context.getAttribute('id'), slickid = 'slickid__';
-				_context.setAttribute('id', slickid);
-				_expression = '#' + slickid + ' ' + _expression;
-				context = _context.parentNode;
-			}
-
-			try {
-				if (first) return context.querySelector(_expression) || null;
-				else nodes = context.querySelectorAll(_expression);
-			} catch(e) {
-				qsaFailExpCache[expression] = 1;
-				break querySelector;
-			} finally {
-				if (!contextIsDocument){
-					if (currentId) _context.setAttribute('id', currentId);
-					else _context.removeAttribute('id');
-					context = _context;
-				}
-			}
-
-			if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
-				if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node);
-			} else for (i = 0; node = nodes[i++];){
-				if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
-			}
-
-			if (hasOthers) this.sort(found);
-			return found;
-
-		}
-		/*</query-selector-override>*/
-
-		parsed = this.Slick.parse(expression);
-		if (!parsed.length) return found;
-	} else if (expression == null){ // there is no expression
-		return found;
-	} else if (expression.Slick){ // expression is a parsed Slick object
-		parsed = expression;
-	} else if (this.contains(context.documentElement || context, expression)){ // expression is a node
-		(found) ? found.push(expression) : found = expression;
-		return found;
-	} else { // other junk
-		return found;
-	}
-
-	/*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
-
-	// cache elements for the nth selectors
-
-	this.posNTH = {};
-	this.posNTHLast = {};
-	this.posNTHType = {};
-	this.posNTHTypeLast = {};
-
-	/*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
-
-	// if append is null and there is only a single selector with one expression use pushArray, else use pushUID
-	this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;
-
-	if (found == null) found = [];
-
-	// default engine
-
-	var j, m, n;
-	var combinator, tag, id, classList, classes, attributes, pseudos;
-	var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
-
-	search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
-
-		combinator = 'combinator:' + currentBit.combinator;
-		if (!this[combinator]) continue search;
-
-		tag        = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();
-		id         = currentBit.id;
-		classList  = currentBit.classList;
-		classes    = currentBit.classes;
-		attributes = currentBit.attributes;
-		pseudos    = currentBit.pseudos;
-		lastBit    = (j === (currentExpression.length - 1));
-
-		this.bitUniques = {};
-
-		if (lastBit){
-			this.uniques = uniques;
-			this.found = found;
-		} else {
-			this.uniques = {};
-			this.found = [];
-		}
-
-		if (j === 0){
-			this[combinator](context, tag, id, classes, attributes, pseudos, classList);
-			if (first && lastBit && found.length) break search;
-		} else {
-			if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
-				this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
-				if (found.length) break search;
-			} else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
-		}
-
-		currentItems = this.found;
-	}
-
-	// should sort if there are nodes in append and if you pass multiple expressions.
-	if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
-
-	return (first) ? (found[0] || null) : found;
+  var found = this.found = (first) ? null : (append || []);
+
+  if (!context) return found;
+  else if (context.navigator) context = context.document; // Convert the node from a window to a document
+  else if (!context.nodeType) return found;
+
+  // setup
+
+  var parsed, i,
+    uniques = this.uniques = {},
+    hasOthers = !!(append && append.length),
+    contextIsDocument = (context.nodeType == 9);
+
+  if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context);
+
+  // avoid duplicating items already in the append array
+  if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true;
+
+  // expression checks
+
+  if (typeof expression == 'string'){ // expression is a string
+
+    /*<simple-selectors-override>*/
+    var simpleSelector = expression.match(reSimpleSelector);
+    simpleSelectors: if (simpleSelector) {
+
+      var symbol = simpleSelector[1],
+        name = simpleSelector[2],
+        node, nodes;
+
+      if (!symbol){
+
+        if (name == '*' && this.brokenStarGEBTN) break simpleSelectors;
+        nodes = context.getElementsByTagName(name);
+        if (first) return nodes[0] || null;
+        for (i = 0; node = nodes[i++];){
+          if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
+        }
+
+      } else if (symbol == '#'){
+
+        if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
+        node = context.getElementById(name);
+        if (!node) return found;
+        if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors;
+        if (first) return node || null;
+        if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
+
+      } else if (symbol == '.'){
+
+        if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors;
+        if (context.getElementsByClassName && !this.brokenGEBCN){
+          nodes = context.getElementsByClassName(name);
+          if (first) return nodes[0] || null;
+          for (i = 0; node = nodes[i++];){
+            if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
+          }
+        } else {
+          var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s|$)');
+          nodes = context.getElementsByTagName('*');
+          for (i = 0; node = nodes[i++];){
+            className = node.className;
+            if (!(className && matchClass.test(className))) continue;
+            if (first) return node;
+            if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
+          }
+        }
+
+      }
+
+      if (hasOthers) this.sort(found);
+      return (first) ? null : found;
+
+    }
+    /*</simple-selectors-override>*/
+
+    /*<query-selector-override>*/
+    querySelector: if (context.querySelectorAll) {
+
+      if (!this.isHTMLDocument
+        || qsaFailExpCache[expression]
+        //TODO: only skip when expression is actually mixed case
+        || this.brokenMixedCaseQSA
+        || (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)
+        || (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))
+        || (!contextIsDocument //Abort when !contextIsDocument and...
+          //  there are multiple expressions in the selector
+          //  since we currently only fix non-document rooted QSA for single expression selectors
+          && expression.indexOf(',') > -1
+        )
+        || Slick.disableQSA
+      ) break querySelector;
+
+      var _expression = expression, _context = context;
+      if (!contextIsDocument){
+        // non-document rooted QSA
+        // credits to Andrew Dupont
+        var currentId = _context.getAttribute('id'), slickid = 'slickid__';
+        _context.setAttribute('id', slickid);
+        _expression = '#' + slickid + ' ' + _expression;
+        context = _context.parentNode;
+      }
+
+      try {
+        if (first) return context.querySelector(_expression) || null;
+        else nodes = context.querySelectorAll(_expression);
+      } catch(e) {
+        qsaFailExpCache[expression] = 1;
+        break querySelector;
+      } finally {
+        if (!contextIsDocument){
+          if (currentId) _context.setAttribute('id', currentId);
+          else _context.removeAttribute('id');
+          context = _context;
+        }
+      }
+
+      if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
+        if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node);
+      } else for (i = 0; node = nodes[i++];){
+        if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
+      }
+
+      if (hasOthers) this.sort(found);
+      return found;
+
+    }
+    /*</query-selector-override>*/
+
+    parsed = this.Slick.parse(expression);
+    if (!parsed.length) return found;
+  } else if (expression == null){ // there is no expression
+    return found;
+  } else if (expression.Slick){ // expression is a parsed Slick object
+    parsed = expression;
+  } else if (this.contains(context.documentElement || context, expression)){ // expression is a node
+    (found) ? found.push(expression) : found = expression;
+    return found;
+  } else { // other junk
+    return found;
+  }
+
+  /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
+
+  // cache elements for the nth selectors
+
+  this.posNTH = {};
+  this.posNTHLast = {};
+  this.posNTHType = {};
+  this.posNTHTypeLast = {};
+
+  /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
+
+  // if append is null and there is only a single selector with one expression use pushArray, else use pushUID
+  this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID;
+
+  if (found == null) found = [];
+
+  // default engine
+
+  var j, m, n;
+  var combinator, tag, id, classList, classes, attributes, pseudos;
+  var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
+
+  search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
+
+    combinator = 'combinator:' + currentBit.combinator;
+    if (!this[combinator]) continue search;
+
+    tag        = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase();
+    id         = currentBit.id;
+    classList  = currentBit.classList;
+    classes    = currentBit.classes;
+    attributes = currentBit.attributes;
+    pseudos    = currentBit.pseudos;
+    lastBit    = (j === (currentExpression.length - 1));
+
+    this.bitUniques = {};
+
+    if (lastBit){
+      this.uniques = uniques;
+      this.found = found;
+    } else {
+      this.uniques = {};
+      this.found = [];
+    }
+
+    if (j === 0){
+      this[combinator](context, tag, id, classes, attributes, pseudos, classList);
+      if (first && lastBit && found.length) break search;
+    } else {
+      if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
+        this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
+        if (found.length) break search;
+      } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
+    }
+
+    currentItems = this.found;
+  }
+
+  // should sort if there are nodes in append and if you pass multiple expressions.
+  if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
+
+  return (first) ? (found[0] || null) : found;
 };
 
 // Utils
@@ -2187,24 +2187,24 @@ local.uidx = 1;
 local.uidk = 'slick-uniqueid';
 
 local.getUIDXML = function(node){
-	var uid = node.getAttribute(this.uidk);
-	if (!uid){
-		uid = this.uidx++;
-		node.setAttribute(this.uidk, uid);
-	}
-	return uid;
+  var uid = node.getAttribute(this.uidk);
+  if (!uid){
+    uid = this.uidx++;
+    node.setAttribute(this.uidk, uid);
+  }
+  return uid;
 };
 
 local.getUIDHTML = function(node){
-	return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
+  return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
 };
 
 // sort based on the setDocument documentSorter method.
 
 local.sort = function(results){
-	if (!this.documentSorter) return results;
-	results.sort(this.documentSorter);
-	return results;
+  if (!this.documentSorter) return results;
+  results.sort(this.documentSorter);
+  return results;
 };
 
 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
@@ -2214,253 +2214,253 @@ local.cacheNTH = {};
 local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
 
 local.parseNTHArgument = function(argument){
-	var parsed = argument.match(this.matchNTH);
-	if (!parsed) return false;
-	var special = parsed[2] || false;
-	var a = parsed[1] || 1;
-	if (a == '-') a = -1;
-	var b = +parsed[3] || 0;
-	parsed =
-		(special == 'n')	? {a: a, b: b} :
-		(special == 'odd')	? {a: 2, b: 1} :
-		(special == 'even')	? {a: 2, b: 0} : {a: 0, b: a};
-
-	return (this.cacheNTH[argument] = parsed);
+  var parsed = argument.match(this.matchNTH);
+  if (!parsed) return false;
+  var special = parsed[2] || false;
+  var a = parsed[1] || 1;
+  if (a == '-') a = -1;
+  var b = +parsed[3] || 0;
+  parsed =
+    (special == 'n')  ? {a: a, b: b} :
+    (special == 'odd')  ? {a: 2, b: 1} :
+    (special == 'even')  ? {a: 2, b: 0} : {a: 0, b: a};
+
+  return (this.cacheNTH[argument] = parsed);
 };
 
 local.createNTHPseudo = function(child, sibling, positions, ofType){
-	return function(node, argument){
-		var uid = this.getUID(node);
-		if (!this[positions][uid]){
-			var parent = node.parentNode;
-			if (!parent) return false;
-			var el = parent[child], count = 1;
-			if (ofType){
-				var nodeName = node.nodeName;
-				do {
-					if (el.nodeName != nodeName) continue;
-					this[positions][this.getUID(el)] = count++;
-				} while ((el = el[sibling]));
-			} else {
-				do {
-					if (el.nodeType != 1) continue;
-					this[positions][this.getUID(el)] = count++;
-				} while ((el = el[sibling]));
-			}
-		}
-		argument = argument || 'n';
-		var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
-		if (!parsed) return false;
-		var a = parsed.a, b = parsed.b, pos = this[positions][uid];
-		if (a == 0) return b == pos;
-		if (a > 0){
-			if (pos < b) return false;
-		} else {
-			if (b < pos) return false;
-		}
-		return ((pos - b) % a) == 0;
-	};
+  return function(node, argument){
+    var uid = this.getUID(node);
+    if (!this[positions][uid]){
+      var parent = node.parentNode;
+      if (!parent) return false;
+      var el = parent[child], count = 1;
+      if (ofType){
+        var nodeName = node.nodeName;
+        do {
+          if (el.nodeName != nodeName) continue;
+          this[positions][this.getUID(el)] = count++;
+        } while ((el = el[sibling]));
+      } else {
+        do {
+          if (el.nodeType != 1) continue;
+          this[positions][this.getUID(el)] = count++;
+        } while ((el = el[sibling]));
+      }
+    }
+    argument = argument || 'n';
+    var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
+    if (!parsed) return false;
+    var a = parsed.a, b = parsed.b, pos = this[positions][uid];
+    if (a == 0) return b == pos;
+    if (a > 0){
+      if (pos < b) return false;
+    } else {
+      if (b < pos) return false;
+    }
+    return ((pos - b) % a) == 0;
+  };
 };
 
 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
 
 local.pushArray = function(node, tag, id, classes, attributes, pseudos){
-	if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);
+  if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node);
 };
 
 local.pushUID = function(node, tag, id, classes, attributes, pseudos){
-	var uid = this.getUID(node);
-	if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){
-		this.uniques[uid] = true;
-		this.found.push(node);
-	}
+  var uid = this.getUID(node);
+  if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){
+    this.uniques[uid] = true;
+    this.found.push(node);
+  }
 };
 
 local.matchNode = function(node, selector){
-	if (this.isHTMLDocument && this.nativeMatchesSelector){
-		try {
-			return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
-		} catch(matchError) {}
-	}
-
-	var parsed = this.Slick.parse(selector);
-	if (!parsed) return true;
-
-	// simple (single) selectors
-	var expressions = parsed.expressions, simpleExpCounter = 0, i;
-	for (i = 0; (currentExpression = expressions[i]); i++){
-		if (currentExpression.length == 1){
-			var exp = currentExpression[0];
-			if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
-			simpleExpCounter++;
-		}
-	}
-
-	if (simpleExpCounter == parsed.length) return false;
-
-	var nodes = this.search(this.document, parsed), item;
-	for (i = 0; item = nodes[i++];){
-		if (item === node) return true;
-	}
-	return false;
+  if (this.isHTMLDocument && this.nativeMatchesSelector){
+    try {
+      return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
+    } catch(matchError) {}
+  }
+
+  var parsed = this.Slick.parse(selector);
+  if (!parsed) return true;
+
+  // simple (single) selectors
+  var expressions = parsed.expressions, simpleExpCounter = 0, i;
+  for (i = 0; (currentExpression = expressions[i]); i++){
+    if (currentExpression.length == 1){
+      var exp = currentExpression[0];
+      if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
+      simpleExpCounter++;
+    }
+  }
+
+  if (simpleExpCounter == parsed.length) return false;
+
+  var nodes = this.search(this.document, parsed), item;
+  for (i = 0; item = nodes[i++];){
+    if (item === node) return true;
+  }
+  return false;
 };
 
 local.matchPseudo = function(node, name, argument){
-	var pseudoName = 'pseudo:' + name;
-	if (this[pseudoName]) return this[pseudoName](node, argument);
-	var attribute = this.getAttribute(node, name);
-	return (argument) ? argument == attribute : !!attribute;
+  var pseudoName = 'pseudo:' + name;
+  if (this[pseudoName]) return this[pseudoName](node, argument);
+  var attribute = this.getAttribute(node, name);
+  return (argument) ? argument == attribute : !!attribute;
 };
 
 local.matchSelector = function(node, tag, id, classes, attributes, pseudos){
-	if (tag){
-		var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase();
-		if (tag == '*'){
-			if (nodeName < '@') return false; // Fix for comment nodes and closed nodes
-		} else {
-			if (nodeName != tag) return false;
-		}
-	}
-
-	if (id && node.getAttribute('id') != id) return false;
-
-	var i, part, cls;
-	if (classes) for (i = classes.length; i--;){
-		cls = this.getAttribute(node, 'class');
-		if (!(cls && classes[i].regexp.test(cls))) return false;
-	}
-	if (attributes) for (i = attributes.length; i--;){
-		part = attributes[i];
-		if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;
-	}
-	if (pseudos) for (i = pseudos.length; i--;){
-		part = pseudos[i];
-		if (!this.matchPseudo(node, part.key, part.value)) return false;
-	}
-	return true;
+  if (tag){
+    var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase();
+    if (tag == '*'){
+      if (nodeName < '@') return false; // Fix for comment nodes and closed nodes
+    } else {
+      if (nodeName != tag) return false;
+    }
+  }
+
+  if (id && node.getAttribute('id') != id) return false;
+
+  var i, part, cls;
+  if (classes) for (i = classes.length; i--;){
+    cls = this.getAttribute(node, 'class');
+    if (!(cls && classes[i].regexp.test(cls))) return false;
+  }
+  if (attributes) for (i = attributes.length; i--;){
+    part = attributes[i];
+    if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false;
+  }
+  if (pseudos) for (i = pseudos.length; i--;){
+    part = pseudos[i];
+    if (!this.matchPseudo(node, part.key, part.value)) return false;
+  }
+  return true;
 };
 
 var combinators = {
 
-	' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
-
-		var i, item, children;
-
-		if (this.isHTMLDocument){
-			getById: if (id){
-				item = this.document.getElementById(id);
-				if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){
-					// all[id] returns all the elements with that name or id inside node
-					// if theres just one it will return the element, else it will be a collection
-					children = node.all[id];
-					if (!children) return;
-					if (!children[0]) children = [children];
-					for (i = 0; item = children[i++];){
-						var idNode = item.getAttributeNode('id');
-						if (idNode && idNode.nodeValue == id){
-							this.push(item, tag, null, classes, attributes, pseudos);
-							break;
-						}
-					}
-					return;
-				}
-				if (!item){
-					// if the context is in the dom we return, else we will try GEBTN, breaking the getById label
-					if (this.contains(this.root, node)) return;
-					else break getById;
-				} else if (this.document !== node && !this.contains(node, item)) return;
-				this.push(item, tag, null, classes, attributes, pseudos);
-				return;
-			}
-			getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){
-				children = node.getElementsByClassName(classList.join(' '));
-				if (!(children && children.length)) break getByClass;
-				for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);
-				return;
-			}
-		}
-		getByTag: {
-			children = node.getElementsByTagName(tag);
-			if (!(children && children.length)) break getByTag;
-			if (!this.brokenStarGEBTN) tag = null;
-			for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
-		}
-	},
-
-	'>': function(node, tag, id, classes, attributes, pseudos){ // direct children
-		if ((node = node.firstChild)) do {
-			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
-		} while ((node = node.nextSibling));
-	},
-
-	'+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
-		while ((node = node.nextSibling)) if (node.nodeType == 1){
-			this.push(node, tag, id, classes, attributes, pseudos);
-			break;
-		}
-	},
-
-	'^': function(node, tag, id, classes, attributes, pseudos){ // first child
-		node = node.firstChild;
-		if (node){
-			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
-			else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
-		}
-	},
-
-	'~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
-		while ((node = node.nextSibling)){
-			if (node.nodeType != 1) continue;
-			var uid = this.getUID(node);
-			if (this.bitUniques[uid]) break;
-			this.bitUniques[uid] = true;
-			this.push(node, tag, id, classes, attributes, pseudos);
-		}
-	},
-
-	'++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling
-		this['combinator:+'](node, tag, id, classes, attributes, pseudos);
-		this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
-	},
-
-	'~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
-		this['combinator:~'](node, tag, id, classes, attributes, pseudos);
-		this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
-	},
-
-	'!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document
-		while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
-	},
-
-	'!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
-		node = node.parentNode;
-		if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
-	},
-
-	'!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
-		while ((node = node.previousSibling)) if (node.nodeType == 1){
-			this.push(node, tag, id, classes, attributes, pseudos);
-			break;
-		}
-	},
-
-	'!^': function(node, tag, id, classes, attributes, pseudos){ // last child
-		node = node.lastChild;
-		if (node){
-			if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
-			else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
-		}
-	},
-
-	'!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
-		while ((node = node.previousSibling)){
-			if (node.nodeType != 1) continue;
-			var uid = this.getUID(node);
-			if (this.bitUniques[uid]) break;
-			this.bitUniques[uid] = true;
-			this.push(node, tag, id, classes, attributes, pseudos);
-		}
-	}
+  ' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
+
+    var i, item, children;
+
+    if (this.isHTMLDocument){
+      getById: if (id){
+        item = this.document.getElementById(id);
+        if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){
+          // all[id] returns all the elements with that name or id inside node
+          // if theres just one it will return the element, else it will be a collection
+          children = node.all[id];
+          if (!children) return;
+          if (!children[0]) children = [children];
+          for (i = 0; item = children[i++];){
+            var idNode = item.getAttributeNode('id');
+            if (idNode && idNode.nodeValue == id){
+              this.push(item, tag, null, classes, attributes, pseudos);
+              break;
+            }
+          }
+          return;
+        }
+        if (!item){
+          // if the context is in the dom we return, else we will try GEBTN, breaking the getById label
+          if (this.contains(this.root, node)) return;
+          else break getById;
+        } else if (this.document !== node && !this.contains(node, item)) return;
+        this.push(item, tag, null, classes, attributes, pseudos);
+        return;
+      }
+      getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){
+        children = node.getElementsByClassName(classList.join(' '));
+        if (!(children && children.length)) break getByClass;
+        for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos);
+        return;
+      }
+    }
+    getByTag: {
+      children = node.getElementsByTagName(tag);
+      if (!(children && children.length)) break getByTag;
+      if (!this.brokenStarGEBTN) tag = null;
+      for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
+    }
+  },
+
+  '>': function(node, tag, id, classes, attributes, pseudos){ // direct children
+    if ((node = node.firstChild)) do {
+      if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
+    } while ((node = node.nextSibling));
+  },
+
+  '+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
+    while ((node = node.nextSibling)) if (node.nodeType == 1){
+      this.push(node, tag, id, classes, attributes, pseudos);
+      break;
+    }
+  },
+
+  '^': function(node, tag, id, classes, attributes, pseudos){ // first child
+    node = node.firstChild;
+    if (node){
+      if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
+      else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
+    }
+  },
+
+  '~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
+    while ((node = node.nextSibling)){
+      if (node.nodeType != 1) continue;
+      var uid = this.getUID(node);
+      if (this.bitUniques[uid]) break;
+      this.bitUniques[uid] = true;
+      this.push(node, tag, id, classes, attributes, pseudos);
+    }
+  },
+
+  '++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling
+    this['combinator:+'](node, tag, id, classes, attributes, pseudos);
+    this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
+  },
+
+  '~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
+    this['combinator:~'](node, tag, id, classes, attributes, pseudos);
+    this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
+  },
+
+  '!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document
+    while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
+  },
+
+  '!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
+    node = node.parentNode;
+    if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
+  },
+
+  '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
+    while ((node = node.previousSibling)) if (node.nodeType == 1){
+      this.push(node, tag, id, classes, attributes, pseudos);
+      break;
+    }
+  },
+
+  '!^': function(node, tag, id, classes, attributes, pseudos){ // last child
+    node = node.lastChild;
+    if (node){
+      if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos);
+      else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
+    }
+  },
+
+  '!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
+    while ((node = node.previousSibling)){
+      if (node.nodeType != 1) continue;
+      var uid = this.getUID(node);
+      if (this.bitUniques[uid]) break;
+      this.bitUniques[uid] = true;
+      this.push(node, tag, id, classes, attributes, pseudos);
+    }
+  }
 
 };
 
@@ -2468,114 +2468,114 @@ for (var c in combinators) local['combinator:' + c] = combinators[c];
 
 var pseudos = {
 
-	/*<pseudo-selectors>*/
+  /*<pseudo-selectors>*/
 
-	'empty': function(node){
-		var child = node.firstChild;
-		return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
-	},
+  'empty': function(node){
+    var child = node.firstChild;
+    return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
+  },
 
-	'not': function(node, expression){
-		return !this.matchNode(node, expression);
-	},
+  'not': function(node, expression){
+    return !this.matchNode(node, expression);
+  },
 
-	'contains': function(node, text){
-		return (node.innerText || node.textContent || '').indexOf(text) > -1;
-	},
+  'contains': function(node, text){
+    return (node.innerText || node.textContent || '').indexOf(text) > -1;
+  },
 
-	'first-child': function(node){
-		while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
-		return true;
-	},
+  'first-child': function(node){
+    while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
+    return true;
+  },
 
-	'last-child': function(node){
-		while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
-		return true;
-	},
+  'last-child': function(node){
+    while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
+    return true;
+  },
 
-	'only-child': function(node){
-		var prev = node;
-		while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;
-		var next = node;
-		while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
-		return true;
-	},
+  'only-child': function(node){
+    var prev = node;
+    while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;
+    var next = node;
+    while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
+    return true;
+  },
 
-	/*<nth-pseudo-selectors>*/
+  /*<nth-pseudo-selectors>*/
 
-	'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
+  'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
 
-	'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
+  'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
 
-	'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),
+  'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true),
 
-	'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),
+  'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true),
 
-	'index': function(node, index){
-		return this['pseudo:nth-child'](node, '' + (index + 1));
-	},
+  'index': function(node, index){
+    return this['pseudo:nth-child'](node, '' + (index + 1));
+  },
 
-	'even': function(node){
-		return this['pseudo:nth-child'](node, '2n');
-	},
+  'even': function(node){
+    return this['pseudo:nth-child'](node, '2n');
+  },
 
-	'odd': function(node){
-		return this['pseudo:nth-child'](node, '2n+1');
-	},
+  'odd': function(node){
+    return this['pseudo:nth-child'](node, '2n+1');
+  },
 
-	/*</nth-pseudo-selectors>*/
+  /*</nth-pseudo-selectors>*/
 
-	/*<of-type-pseudo-selectors>*/
+  /*<of-type-pseudo-selectors>*/
 
-	'first-of-type': function(node){
-		var nodeName = node.nodeName;
-		while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;
-		return true;
-	},
+  'first-of-type': function(node){
+    var nodeName = node.nodeName;
+    while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;
+    return true;
+  },
 
-	'last-of-type': function(node){
-		var nodeName = node.nodeName;
-		while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;
-		return true;
-	},
+  'last-of-type': function(node){
+    var nodeName = node.nodeName;
+    while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;
+    return true;
+  },
 
-	'only-of-type': function(node){
-		var prev = node, nodeName = node.nodeName;
-		while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;
-		var next = node;
-		while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;
-		return true;
-	},
+  'only-of-type': function(node){
+    var prev = node, nodeName = node.nodeName;
+    while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;
+    var next = node;
+    while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;
+    return true;
+  },
 
-	/*</of-type-pseudo-selectors>*/
+  /*</of-type-pseudo-selectors>*/
 
-	// custom pseudos
+  // custom pseudos
 
-	'enabled': function(node){
-		return !node.disabled;
-	},
+  'enabled': function(node){
+    return !node.disabled;
+  },
 
-	'disabled': function(node){
-		return node.disabled;
-	},
+  'disabled': function(node){
+    return node.disabled;
+  },
 
-	'checked': function(node){
-		return node.checked || node.selected;
-	},
+  'checked': function(node){
+    return node.checked || node.selected;
+  },
 
-	'focus': function(node){
-		return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
-	},
+  'focus': function(node){
+    return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
+  },
 
-	'root': function(node){
-		return (node === this.root);
-	},
+  'root': function(node){
+    return (node === this.root);
+  },
 
-	'selected': function(node){
-		return node.selected;
-	}
+  'selected': function(node){
+    return node.selected;
+  }
 
-	/*</pseudo-selectors>*/
+  /*</pseudo-selectors>*/
 };
 
 for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
@@ -2584,31 +2584,31 @@ for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
 
 var attributeGetters = local.attributeGetters = {
 
-	'for': function(){
-		return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
-	},
+  'for': function(){
+    return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
+  },
 
-	'href': function(){
-		return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');
-	},
+  'href': function(){
+    return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href');
+  },
 
-	'style': function(){
-		return (this.style) ? this.style.cssText : this.getAttribute('style');
-	},
+  'style': function(){
+    return (this.style) ? this.style.cssText : this.getAttribute('style');
+  },
 
-	'tabindex': function(){
-		var attributeNode = this.getAttributeNode('tabindex');
-		return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
-	},
+  'tabindex': function(){
+    var attributeNode = this.getAttributeNode('tabindex');
+    return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
+  },
 
-	'type': function(){
-		return this.getAttribute('type');
-	},
+  'type': function(){
+    return this.getAttribute('type');
+  },
 
-	'maxlength': function(){
-		var attributeNode = this.getAttributeNode('maxLength');
-		return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
-	}
+  'maxlength': function(){
+    var attributeNode = this.getAttributeNode('maxLength');
+    return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
+  }
 
 };
 
@@ -2623,80 +2623,80 @@ Slick.version = '1.1.7';
 // Slick finder
 
 Slick.search = function(context, expression, append){
-	return local.search(context, expression, append);
+  return local.search(context, expression, append);
 };
 
 Slick.find = function(context, expression){
-	return local.search(context, expression, null, true);
+  return local.search(context, expression, null, true);
 };
 
 // Slick containment checker
 
 Slick.contains = function(container, node){
-	local.setDocument(container);
-	return local.contains(container, node);
+  local.setDocument(container);
+  return local.contains(container, node);
 };
 
 // Slick attribute getter
 
 Slick.getAttribute = function(node, name){
-	local.setDocument(node);
-	return local.getAttribute(node, name);
+  local.setDocument(node);
+  return local.getAttribute(node, name);
 };
 
 Slick.hasAttribute = function(node, name){
-	local.setDocument(node);
-	return local.hasAttribute(node, name);
+  local.setDocument(node);
+  return local.hasAttribute(node, name);
 };
 
 // Slick matcher
 
 Slick.match = function(node, selector){
-	if (!(node && selector)) return false;
-	if (!selector || selector === node) return true;
-	local.setDocument(node);
-	return local.matchNode(node, selector);
+  if (!(node && selector)) return false;
+  if (!selector || selector === node) return true;
+  local.setDocument(node);
+  return local.matchNode(node, selector);
 };
 
 // Slick attribute accessor
 
 Slick.defineAttributeGetter = function(name, fn){
-	local.attributeGetters[name] = fn;
-	return this;
+  local.attributeGetters[name] = fn;
+  return this;
 };
 
 Slick.lookupAttributeGetter = function(name){
-	return local.attributeGetters[name];
+  return local.attributeGetters[name];
 };
 
 // Slick pseudo accessor
 
 Slick.definePseudo = function(name, fn){
-	local['pseudo:' + name] = function(node, argument){
-		return fn.call(node, argument);
-	};
-	return this;
+  local['pseudo:' + name] = function(node, argument){
+    return fn.call(node, argument);
+  };
+  return this;
 };
 
 Slick.lookupPseudo = function(name){
-	var pseudo = local['pseudo:' + name];
-	if (pseudo) return function(argument){
-		return pseudo.call(this, argument);
-	};
-	return null;
+  var pseudo = local['pseudo:' + name];
+  if (pseudo) return function(argument){
+    return pseudo.call(this, argument);
+  };
+  return null;
 };
 
 // Slick overrides accessor
 
 Slick.override = function(regexp, fn){
-	local.override(regexp, fn);
-	return this;
+  local.override(regexp, fn);
+  return this;
 };
 
 Slick.isXML = local.isXML;
 
 Slick.uidOf = function(node){
-	return local.getUIDHTML(node);
+  return local.getUIDHTML(node);
 };
 
 if (!this.Slick) this.Slick = Slick;
@@ -2721,70 +2721,70 @@ provides: [Element, Elements, $, $$, IFrame, Selectors]
 */
 
 var Element = this.Element = function(tag, props){
-	var konstructor = Element.Constructors[tag];
-	if (konstructor) return konstructor(props);
-	if (typeof tag != 'string') return document.id(tag).set(props);
+  var konstructor = Element.Constructors[tag];
+  if (konstructor) return konstructor(props);
+  if (typeof tag != 'string') return document.id(tag).set(props);
 
-	if (!props) props = {};
+  if (!props) props = {};
 
-	if (!(/^[\w-]+$/).test(tag)){
-		var parsed = Slick.parse(tag).expressions[0][0];
-		tag = (parsed.tag == '*') ? 'div' : parsed.tag;
-		if (parsed.id && props.id == null) props.id = parsed.id;
+  if (!(/^[\w-]+$/).test(tag)){
+    var parsed = Slick.parse(tag).expressions[0][0];
+    tag = (parsed.tag == '*') ? 'div' : parsed.tag;
+    if (parsed.id && props.id == null) props.id = parsed.id;
 
-		var attributes = parsed.attributes;
-		if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
-			attr = attributes[i];
-			if (props[attr.key] != null) continue;
+    var attributes = parsed.attributes;
+    if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
+      attr = attributes[i];
+      if (props[attr.key] != null) continue;
 
-			if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
-			else if (!attr.value && !attr.operator) props[attr.key] = true;
-		}
+      if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value;
+      else if (!attr.value && !attr.operator) props[attr.key] = true;
+    }
 
-		if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
-	}
+    if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
+  }
 
-	return document.newElement(tag, props);
+  return document.newElement(tag, props);
 };
 
 
 if (Browser.Element){
-	Element.prototype = Browser.Element.prototype;
-	// IE8 and IE9 require the wrapping.
-	Element.prototype._fireEvent = (function(fireEvent){
-		return function(type, event){
-			return fireEvent.call(this, type, event);
-		};
-	})(Element.prototype.fireEvent);
+  Element.prototype = Browser.Element.prototype;
+  // IE8 and IE9 require the wrapping.
+  Element.prototype._fireEvent = (function(fireEvent){
+    return function(type, event){
+      return fireEvent.call(this, type, event);
+    };
+  })(Element.prototype.fireEvent);
 }
 
 new Type('Element', Element).mirror(function(name){
-	if (Array.prototype[name]) return;
-
-	var obj = {};
-	obj[name] = function(){
-		var results = [], args = arguments, elements = true;
-		for (var i = 0, l = this.length; i < l; i++){
-			var element = this[i], result = results[i] = element[name].apply(element, args);
-			elements = (elements && typeOf(result) == 'element');
-		}
-		return (elements) ? new Elements(results) : results;
-	};
-
-	Elements.implement(obj);
+  if (Array.prototype[name]) return;
+
+  var obj = {};
+  obj[name] = function(){
+    var results = [], args = arguments, elements = true;
+    for (var i = 0, l = this.length; i < l; i++){
+      var element = this[i], result = results[i] = element[name].apply(element, args);
+      elements = (elements && typeOf(result) == 'element');
+    }
+    return (elements) ? new Elements(results) : results;
+  };
+
+  Elements.implement(obj);
 });
 
 if (!Browser.Element){
-	Element.parent = Object;
+  Element.parent = Object;
 
-	Element.Prototype = {
-		'$constructor': Element,
-		'$family': Function.from('element').hide()
-	};
+  Element.Prototype = {
+    '$constructor': Element,
+    '$family': Function.from('element').hide()
+  };
 
-	Element.mirror(function(name, method){
-		Element.Prototype[name] = method;
-	});
+  Element.mirror(function(name, method){
+    Element.Prototype[name] = method;
+  });
 }
 
 Element.Constructors = {};
@@ -2792,40 +2792,40 @@ Element.Constructors = {};
 
 
 var IFrame = new Type('IFrame', function(){
-	var params = Array.link(arguments, {
-		properties: Type.isObject,
-		iframe: function(obj){
-			return (obj != null);
-		}
-	});
-
-	var props = params.properties || {}, iframe;
-	if (params.iframe) iframe = document.id(params.iframe);
-	var onload = props.onload || function(){};
-	delete props.onload;
-	props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
-	iframe = new Element(iframe || 'iframe', props);
-
-	var onLoad = function(){
-		onload.call(iframe.contentWindow);
-	};
-
-	if (window.frames[props.id]) onLoad();
-	else iframe.addListener('load', onLoad);
-	return iframe;
+  var params = Array.link(arguments, {
+    properties: Type.isObject,
+    iframe: function(obj){
+      return (obj != null);
+    }
+  });
+
+  var props = params.properties || {}, iframe;
+  if (params.iframe) iframe = document.id(params.iframe);
+  var onload = props.onload || function(){};
+  delete props.onload;
+  props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick();
+  iframe = new Element(iframe || 'iframe', props);
+
+  var onLoad = function(){
+    onload.call(iframe.contentWindow);
+  };
+
+  if (window.frames[props.id]) onLoad();
+  else iframe.addListener('load', onLoad);
+  return iframe;
 });
 
 var Elements = this.Elements = function(nodes){
-	if (nodes && nodes.length){
-		var uniques = {}, node;
-		for (var i = 0; node = nodes[i++];){
-			var uid = Slick.uidOf(node);
-			if (!uniques[uid]){
-				uniques[uid] = true;
-				this.push(node);
-			}
-		}
-	}
+  if (nodes && nodes.length){
+    var uniques = {}, node;
+    for (var i = 0; node = nodes[i++];){
+      var uid = Slick.uidOf(node);
+      if (!uniques[uid]){
+        uniques[uid] = true;
+        this.push(node);
+      }
+    }
+  }
 };
 
 Elements.prototype = {length: 0};
@@ -2833,50 +2833,50 @@ Elements.parent = Array;
 
 new Type('Elements', Elements).implement({
 
-	filter: function(filter, bind){
-		if (!filter) return this;
-		return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
-			return item.match(filter);
-		} : filter, bind));
-	}.protect(),
-
-	push: function(){
-		var length = this.length;
-		for (var i = 0, l = arguments.length; i < l; i++){
-			var item = document.id(arguments[i]);
-			if (item) this[length++] = item;
-		}
-		return (this.length = length);
-	}.protect(),
-
-	unshift: function(){
-		var items = [];
-		for (var i = 0, l = arguments.length; i < l; i++){
-			var item = document.id(arguments[i]);
-			if (item) items.push(item);
-		}
-		return Array.prototype.unshift.apply(this, items);
-	}.protect(),
-
-	concat: function(){
-		var newElements = new Elements(this);
-		for (var i = 0, l = arguments.length; i < l; i++){
-			var item = arguments[i];
-			if (Type.isEnumerable(item)) newElements.append(item);
-			else newElements.push(item);
-		}
-		return newElements;
-	}.protect(),
-
-	append: function(collection){
-		for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
-		return this;
-	}.protect(),
-
-	empty: function(){
-		while (this.length) delete this[--this.length];
-		return this;
-	}.protect()
+  filter: function(filter, bind){
+    if (!filter) return this;
+    return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){
+      return item.match(filter);
+    } : filter, bind));
+  }.protect(),
+
+  push: function(){
+    var length = this.length;
+    for (var i = 0, l = arguments.length; i < l; i++){
+      var item = document.id(arguments[i]);
+      if (item) this[length++] = item;
+    }
+    return (this.length = length);
+  }.protect(),
+
+  unshift: function(){
+    var items = [];
+    for (var i = 0, l = arguments.length; i < l; i++){
+      var item = document.id(arguments[i]);
+      if (item) items.push(item);
+    }
+    return Array.prototype.unshift.apply(this, items);
+  }.protect(),
+
+  concat: function(){
+    var newElements = new Elements(this);
+    for (var i = 0, l = arguments.length; i < l; i++){
+      var item = arguments[i];
+      if (Type.isEnumerable(item)) newElements.append(item);
+      else newElements.push(item);
+    }
+    return newElements;
+  }.protect(),
+
+  append: function(collection){
+    for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
+    return this;
+  }.protect(),
+
+  empty: function(){
+    while (this.length) delete this[--this.length];
+    return this;
+  }.protect()
 
 });
 
@@ -2889,14 +2889,14 @@ var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
 
 splice.call(object, 1, 1);
 if (object[1] == 1) Elements.implement('splice', function(){
-	var length = this.length;
-	var result = splice.apply(this, arguments);
-	while (length >= this.length) delete this[length--];
-	return result;
+  var length = this.length;
+  var result = splice.apply(this, arguments);
+  while (length >= this.length) delete this[length--];
+  return result;
 }.protect());
 
 Array.forEachMethod(function(method, name){
-	Elements.implement(name, method);
+  Elements.implement(name, method);
 });
 
 Array.mirror(Elements);
@@ -2904,30 +2904,30 @@ Array.mirror(Elements);
 /*<ltIE8>*/
 var createElementAcceptsHTML;
 try {
-	createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x');
+  createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x');
 } catch (e){}
 
 var escapeQuotes = function(html){
-	return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
+  return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
 };
 /*</ltIE8>*/
 
 Document.implement({
 
-	newElement: function(tag, props){
-		if (props && props.checked != null) props.defaultChecked = props.checked;
-		/*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
-		if (createElementAcceptsHTML && props){
-			tag = '<' + tag;
-			if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
-			if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
-			tag += '>';
-			delete props.name;
-			delete props.type;
-		}
-		/*</ltIE8>*/
-		return this.id(this.createElement(tag)).set(props);
-	}
+  newElement: function(tag, props){
+    if (props && props.checked != null) props.defaultChecked = props.checked;
+    /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
+    if (createElementAcceptsHTML && props){
+      tag = '<' + tag;
+      if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
+      if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
+      tag += '>';
+      delete props.name;
+      delete props.type;
+    }
+    /*</ltIE8>*/
+    return this.id(this.createElement(tag)).set(props);
+  }
 
 });
 
@@ -2940,91 +2940,91 @@ Slick.uidOf(document);
 
 Document.implement({
 
-	newTextNode: function(text){
-		return this.createTextNode(text);
-	},
+  newTextNode: function(text){
+    return this.createTextNode(text);
+  },
 
-	getDocument: function(){
-		return this;
-	},
+  getDocument: function(){
+    return this;
+  },
 
-	getWindow: function(){
-		return this.window;
-	},
+  getWindow: function(){
+    return this.window;
+  },
 
-	id: (function(){
+  id: (function(){
 
-		var types = {
+    var types = {
 
-			string: function(id, nocash, doc){
-				id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
-				return (id) ? types.element(id, nocash) : null;
-			},
+      string: function(id, nocash, doc){
+        id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
+        return (id) ? types.element(id, nocash) : null;
+      },
 
-			element: function(el, nocash){
-				Slick.uidOf(el);
-				if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){
-					var fireEvent = el.fireEvent;
-					// wrapping needed in IE7, or else crash
-					el._fireEvent = function(type, event){
-						return fireEvent(type, event);
-					};
-					Object.append(el, Element.Prototype);
-				}
-				return el;
-			},
+      element: function(el, nocash){
+        Slick.uidOf(el);
+        if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){
+          var fireEvent = el.fireEvent;
+          // wrapping needed in IE7, or else crash
+          el._fireEvent = function(type, event){
+            return fireEvent(type, event);
+          };
+          Object.append(el, Element.Prototype);
+        }
+        return el;
+      },
 
-			object: function(obj, nocash, doc){
-				if (obj.toElement) return types.element(obj.toElement(doc), nocash);
-				return null;
-			}
+      object: function(obj, nocash, doc){
+        if (obj.toElement) return types.element(obj.toElement(doc), nocash);
+        return null;
+      }
 
-		};
+    };
 
-		types.textnode = types.whitespace = types.window = types.document = function(zero){
-			return zero;
-		};
+    types.textnode = types.whitespace = types.window = types.document = function(zero){
+      return zero;
+    };
 
-		return function(el, nocash, doc){
-			if (el && el.$family && el.uniqueNumber) return el;
-			var type = typeOf(el);
-			return (types[type]) ? types[type](el, nocash, doc || document) : null;
-		};
+    return function(el, nocash, doc){
+      if (el && el.$family && el.uniqueNumber) return el;
+      var type = typeOf(el);
+      return (types[type]) ? types[type](el, nocash, doc || document) : null;
+    };
 
-	})()
+  })()
 
 });
 
 if (window.$ == null) Window.implement('$', function(el, nc){
-	return document.id(el, nc, this.document);
+  return document.id(el, nc, this.document);
 });
 
 Window.implement({
 
-	getDocument: function(){
-		return this.document;
-	},
+  getDocument: function(){
+    return this.document;
+  },
 
-	getWindow: function(){
-		return this;
-	}
+  getWindow: function(){
+    return this;
+  }
 
 });
 
 [Document, Element].invoke('implement', {
 
-	getElements: function(expression){
-		return Slick.search(this, expression, new Elements);
-	},
+  getElements: function(expression){
+    return Slick.search(this, expression, new Elements);
+  },
 
-	getElement: function(expression){
-		return document.id(Slick.find(this, expression));
-	}
+  getElement: function(expression){
+    return document.id(Slick.find(this, expression));
+  }
 
 });
 
 var contains = {contains: function(element){
-	return Slick.contains(this, element);
+  return Slick.contains(this, element);
 }};
 
 if (!document.contains) Document.implement(contains);
@@ -3035,98 +3035,98 @@ if (!document.createElement('div').contains) Element.implement(contains);
 // tree walking
 
 var injectCombinator = function(expression, combinator){
-	if (!expression) return combinator;
+  if (!expression) return combinator;
 
-	expression = Object.clone(Slick.parse(expression));
+  expression = Object.clone(Slick.parse(expression));
 
-	var expressions = expression.expressions;
-	for (var i = expressions.length; i--;)
-		expressions[i][0].combinator = combinator;
+  var expressions = expression.expressions;
+  for (var i = expressions.length; i--;)
+    expressions[i][0].combinator = combinator;
 
-	return expression;
+  return expression;
 };
 
 Object.forEach({
-	getNext: '~',
-	getPrevious: '!~',
-	getParent: '!'
+  getNext: '~',
+  getPrevious: '!~',
+  getParent: '!'
 }, function(combinator, method){
-	Element.implement(method, function(expression){
-		return this.getElement(injectCombinator(expression, combinator));
-	});
+  Element.implement(method, function(expression){
+    return this.getElement(injectCombinator(expression, combinator));
+  });
 });
 
 Object.forEach({
-	getAllNext: '~',
-	getAllPrevious: '!~',
-	getSiblings: '~~',
-	getChildren: '>',
-	getParents: '!'
+  getAllNext: '~',
+  getAllPrevious: '!~',
+  getSiblings: '~~',
+  getChildren: '>',
+  getParents: '!'
 }, function(combinator, method){
-	Element.implement(method, function(expression){
-		return this.getElements(injectCombinator(expression, combinator));
-	});
+  Element.implement(method, function(expression){
+    return this.getElements(injectCombinator(expression, combinator));
+  });
 });
 
 Element.implement({
 
-	getFirst: function(expression){
-		return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
-	},
+  getFirst: function(expression){
+    return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]);
+  },
 
-	getLast: function(expression){
-		return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
-	},
+  getLast: function(expression){
+    return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast());
+  },
 
-	getWindow: function(){
-		return this.ownerDocument.window;
-	},
+  getWindow: function(){
+    return this.ownerDocument.window;
+  },
 
-	getDocument: function(){
-		return this.ownerDocument;
-	},
+  getDocument: function(){
+    return this.ownerDocument;
+  },
 
-	getElementById: function(id){
-		return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
-	},
+  getElementById: function(id){
+    return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1')));
+  },
 
-	match: function(expression){
-		return !expression || Slick.match(this, expression);
-	}
+  match: function(expression){
+    return !expression || Slick.match(this, expression);
+  }
 
 });
 
 
 
 if (window.$$ == null) Window.implement('$$', function(selector){
-	if (arguments.length == 1){
-		if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
-		else if (Type.isEnumerable(selector)) return new Elements(selector);
-	}
-	return new Elements(arguments);
+  if (arguments.length == 1){
+    if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements);
+    else if (Type.isEnumerable(selector)) return new Elements(selector);
+  }
+  return new Elements(arguments);
 });
 
 // Inserters
 
 var inserters = {
 
-	before: function(context, element){
-		var parent = element.parentNode;
-		if (parent) parent.insertBefore(context, element);
-	},
+  before: function(context, element){
+    var parent = element.parentNode;
+    if (parent) parent.insertBefore(context, element);
+  },
 
-	after: function(context, element){
-		var parent = element.parentNode;
-		if (parent) parent.insertBefore(context, element.nextSibling);
-	},
+  after: function(context, element){
+    var parent = element.parentNode;
+    if (parent) parent.insertBefore(context, element.nextSibling);
+  },
 
-	bottom: function(context, element){
-		element.appendChild(context);
-	},
+  bottom: function(context, element){
+    element.appendChild(context);
+  },
 
-	top: function(context, element){
-		element.insertBefore(context, element.firstChild);
-	}
+  top: function(context, element){
+    element.insertBefore(context, element.firstChild);
+  }
 
 };
 
@@ -3142,69 +3142,69 @@ var propertyGetters = {}, propertySetters = {};
 
 var properties = {};
 Array.forEach([
-	'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',
-	'frameBorder', 'rowSpan', 'tabIndex', 'useMap'
+  'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan',
+  'frameBorder', 'rowSpan', 'tabIndex', 'useMap'
 ], function(property){
-	properties[property.toLowerCase()] = property;
+  properties[property.toLowerCase()] = property;
 });
 
 properties.html = 'innerHTML';
 properties.text = (document.createElement('div').textContent == null) ? 'innerText': 'textContent';
 
 Object.forEach(properties, function(real, key){
-	propertySetters[key] = function(node, value){
-		node[real] = value;
-	};
-	propertyGetters[key] = function(node){
-		return node[real];
-	};
+  propertySetters[key] = function(node, value){
+    node[real] = value;
+  };
+  propertyGetters[key] = function(node){
+    return node[real];
+  };
 });
 
 // Booleans
 
 var bools = [
-	'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
-	'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
-	'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
-	'loop'
+  'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
+  'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
+  'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
+  'loop'
 ];
 
 var booleans = {};
 Array.forEach(bools, function(bool){
-	var lower = bool.toLowerCase();
-	booleans[lower] = bool;
-	propertySetters[lower] = function(node, value){
-		node[bool] = !!value;
-	};
-	propertyGetters[lower] = function(node){
-		return !!node[bool];
-	};
+  var lower = bool.toLowerCase();
+  booleans[lower] = bool;
+  propertySetters[lower] = function(node, value){
+    node[bool] = !!value;
+  };
+  propertyGetters[lower] = function(node){
+    return !!node[bool];
+  };
 });
 
 // Special cases
 
 Object.append(propertySetters, {
 
-	'class': function(node, value){
-		('className' in node) ? node.className = (value || '') : node.setAttribute('class', value);
-	},
+  'class': function(node, value){
+    ('className' in node) ? node.className = (value || '') : node.setAttribute('class', value);
+  },
 
-	'for': function(node, value){
-		('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
-	},
+  'for': function(node, value){
+    ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value);
+  },
 
-	'style': function(node, value){
-		(node.style) ? node.style.cssText = value : node.setAttribute('style', value);
-	},
+  'style': function(node, value){
+    (node.style) ? node.style.cssText = value : node.setAttribute('style', value);
+  },
 
-	'value': function(node, value){
-		node.value = (value != null) ? value : '';
-	}
+  'value': function(node, value){
+    node.value = (value != null) ? value : '';
+  }
 
 });
 
 propertyGetters['class'] = function(node){
-	return ('className' in node) ? node.className || null : node.getAttribute('class');
+  return ('className' in node) ? node.className || null : node.getAttribute('class');
 };
 
 /* <webkit> */
@@ -3212,7 +3212,7 @@ var el = document.createElement('button');
 // IE sets type as readonly and throws
 try { el.type = 'button'; } catch(e){}
 if (el.type != 'button') propertySetters.type = function(node, value){
-	node.setAttribute('type', value);
+  node.setAttribute('type', value);
 };
 el = null;
 /* </webkit> */
@@ -3222,9 +3222,9 @@ var input = document.createElement('input');
 input.value = 't';
 input.type = 'submit';
 if (input.value != 't') propertySetters.type = function(node, type){
-	var value = node.value;
-	node.type = type;
-	node.value = value;
+  var value = node.value;
+  node.type = type;
+  node.value = value;
 };
 input = null;
 /*</IE>*/
@@ -3233,206 +3233,206 @@ input = null;
 
 /* <ltIE9> */
 var pollutesGetAttribute = (function(div){
-	div.random = 'attribute';
-	return (div.getAttribute('random') == 'attribute');
+  div.random = 'attribute';
+  return (div.getAttribute('random') == 'attribute');
 })(document.createElement('div'));
 
 var hasCloneBug = (function(test){
-	test.innerHTML = '<object><param name="should_fix" value="the unknown"></object>';
-	return test.cloneNode(true).firstChild.childNodes.length != 1;
+  test.innerHTML = '<object><param name="should_fix" value="the unknown"></object>';
+  return test.cloneNode(true).firstChild.childNodes.length != 1;
 })(document.createElement('div'));
 /* </ltIE9> */
 
 var hasClassList = !!document.createElement('div').classList;
 
 var classes = function(className){
-	var classNames = (className || '').clean().split(" "), uniques = {};
-	return classNames.filter(function(className){
-		if (className !== "" && !uniques[className]) return uniques[className] = className;
-	});
+  var classNames = (className || '').clean().split(" "), uniques = {};
+  return classNames.filter(function(className){
+    if (className !== "" && !uniques[className]) return uniques[className] = className;
+  });
 };
 
 var addToClassList = function(name){
-	this.classList.add(name);
+  this.classList.add(name);
 };
 
 var removeFromClassList = function(name){
-	this.classList.remove(name);
+  this.classList.remove(name);
 };
 
 Element.implement({
 
-	setProperty: function(name, value){
-		var setter = propertySetters[name.toLowerCase()];
-		if (setter){
-			setter(this, value);
-		} else {
-			/* <ltIE9> */
-			var attributeWhiteList;
-			if (pollutesGetAttribute) attributeWhiteList = this.retrieve('$attributeWhiteList', {});
-			/* </ltIE9> */
-
-			if (value == null){
-				this.removeAttribute(name);
-				/* <ltIE9> */
-				if (pollutesGetAttribute) delete attributeWhiteList[name];
-				/* </ltIE9> */
-			} else {
-				this.setAttribute(name, '' + value);
-				/* <ltIE9> */
-				if (pollutesGetAttribute) attributeWhiteList[name] = true;
-				/* </ltIE9> */
-			}
-		}
-		return this;
-	},
-
-	setProperties: function(attributes){
-		for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
-		return this;
-	},
-
-	getProperty: function(name){
-		var getter = propertyGetters[name.toLowerCase()];
-		if (getter) return getter(this);
-		/* <ltIE9> */
-		if (pollutesGetAttribute){
-			var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {});
-			if (!attr) return null;
-			if (attr.expando && !attributeWhiteList[name]){
-				var outer = this.outerHTML;
-				// segment by the opening tag and find mention of attribute name
-				if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(name) < 0) return null;
-				attributeWhiteList[name] = true;
-			}
-		}
-		/* </ltIE9> */
-		var result = Slick.getAttribute(this, name);
-		return (!result && !Slick.hasAttribute(this, name)) ? null : result;
-	},
-
-	getProperties: function(){
-		var args = Array.from(arguments);
-		return args.map(this.getProperty, this).associate(args);
-	},
-
-	removeProperty: function(name){
-		return this.setProperty(name, null);
-	},
-
-	removeProperties: function(){
-		Array.each(arguments, this.removeProperty, this);
-		return this;
-	},
-
-	set: function(prop, value){
-		var property = Element.Properties[prop];
-		(property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
-	}.overloadSetter(),
-
-	get: function(prop){
-		var property = Element.Properties[prop];
-		return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
-	}.overloadGetter(),
-
-	erase: function(prop){
-		var property = Element.Properties[prop];
-		(property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
-		return this;
-	},
-
-	hasClass: hasClassList ? function(className){
-		return this.classList.contains(className);
-	} : function(className){
-		return this.className.clean().contains(className, ' ');
-	},
-
-	addClass: hasClassList ? function(className){
-		classes(className).forEach(addToClassList, this);
-		return this;
-	} : function(className){
-		this.className = classes(className + ' ' + this.className).join(' ');
-		return this;
-	},
-
-	removeClass: hasClassList ? function(className){
-		classes(className).forEach(removeFromClassList, this);
-		return this;
-	} : function(className){
-		var classNames = classes(this.className);
-		classes(className).forEach(classNames.erase, classNames);
-		this.className = classNames.join(' ');
-		return this;
-	},
-
-	toggleClass: function(className, force){
-		if (force == null) force = !this.hasClass(className);
-		return (force) ? this.addClass(className) : this.removeClass(className);
-	},
-
-	adopt: function(){
-		var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
-		if (length > 1) parent = fragment = document.createDocumentFragment();
-
-		for (var i = 0; i < length; i++){
-			var element = document.id(elements[i], true);
-			if (element) parent.appendChild(element);
-		}
-
-		if (fragment) this.appendChild(fragment);
-
-		return this;
-	},
-
-	appendText: function(text, where){
-		return this.grab(this.getDocument().newTextNode(text), where);
-	},
-
-	grab: function(el, where){
-		inserters[where || 'bottom'](document.id(el, true), this);
-		return this;
-	},
-
-	inject: function(el, where){
-		inserters[where || 'bottom'](this, document.id(el, true));
-		return this;
-	},
-
-	replaces: function(el){
-		el = document.id(el, true);
-		el.parentNode.replaceChild(this, el);
-		return this;
-	},
-
-	wraps: function(el, where){
-		el = document.id(el, true);
-		return this.replaces(el).grab(el, where);
-	},
-
-	getSelected: function(){
-		this.selectedIndex; // Safari 3.2.1
-		return new Elements(Array.from(this.options).filter(function(option){
-			return option.selected;
-		}));
-	},
-
-	toQueryString: function(){
-		var queryString = [];
-		this.getElements('input, select, textarea').each(function(el){
-			var type = el.type;
-			if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
-
-			var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
-				// IE
-				return document.id(opt).get('value');
-			}) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
-
-			Array.from(value).each(function(val){
-				if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
-			});
-		});
-		return queryString.join('&');
-	}
+  setProperty: function(name, value){
+    var setter = propertySetters[name.toLowerCase()];
+    if (setter){
+      setter(this, value);
+    } else {
+      /* <ltIE9> */
+      var attributeWhiteList;
+      if (pollutesGetAttribute) attributeWhiteList = this.retrieve('$attributeWhiteList', {});
+      /* </ltIE9> */
+
+      if (value == null){
+        this.removeAttribute(name);
+        /* <ltIE9> */
+        if (pollutesGetAttribute) delete attributeWhiteList[name];
+        /* </ltIE9> */
+      } else {
+        this.setAttribute(name, '' + value);
+        /* <ltIE9> */
+        if (pollutesGetAttribute) attributeWhiteList[name] = true;
+        /* </ltIE9> */
+      }
+    }
+    return this;
+  },
+
+  setProperties: function(attributes){
+    for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]);
+    return this;
+  },
+
+  getProperty: function(name){
+    var getter = propertyGetters[name.toLowerCase()];
+    if (getter) return getter(this);
+    /* <ltIE9> */
+    if (pollutesGetAttribute){
+      var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {});
+      if (!attr) return null;
+      if (attr.expando && !attributeWhiteList[name]){
+        var outer = this.outerHTML;
+        // segment by the opening tag and find mention of attribute name
+        if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(name) < 0) return null;
+        attributeWhiteList[name] = true;
+      }
+    }
+    /* </ltIE9> */
+    var result = Slick.getAttribute(this, name);
+    return (!result && !Slick.hasAttribute(this, name)) ? null : result;
+  },
+
+  getProperties: function(){
+    var args = Array.from(arguments);
+    return args.map(this.getProperty, this).associate(args);
+  },
+
+  removeProperty: function(name){
+    return this.setProperty(name, null);
+  },
+
+  removeProperties: function(){
+    Array.each(arguments, this.removeProperty, this);
+    return this;
+  },
+
+  set: function(prop, value){
+    var property = Element.Properties[prop];
+    (property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value);
+  }.overloadSetter(),
+
+  get: function(prop){
+    var property = Element.Properties[prop];
+    return (property && property.get) ? property.get.apply(this) : this.getProperty(prop);
+  }.overloadGetter(),
+
+  erase: function(prop){
+    var property = Element.Properties[prop];
+    (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop);
+    return this;
+  },
+
+  hasClass: hasClassList ? function(className){
+    return this.classList.contains(className);
+  } : function(className){
+    return this.className.clean().contains(className, ' ');
+  },
+
+  addClass: hasClassList ? function(className){
+    classes(className).forEach(addToClassList, this);
+    return this;
+  } : function(className){
+    this.className = classes(className + ' ' + this.className).join(' ');
+    return this;
+  },
+
+  removeClass: hasClassList ? function(className){
+    classes(className).forEach(removeFromClassList, this);
+    return this;
+  } : function(className){
+    var classNames = classes(this.className);
+    classes(className).forEach(classNames.erase, classNames);
+    this.className = classNames.join(' ');
+    return this;
+  },
+
+  toggleClass: function(className, force){
+    if (force == null) force = !this.hasClass(className);
+    return (force) ? this.addClass(className) : this.removeClass(className);
+  },
+
+  adopt: function(){
+    var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length;
+    if (length > 1) parent = fragment = document.createDocumentFragment();
+
+    for (var i = 0; i < length; i++){
+      var element = document.id(elements[i], true);
+      if (element) parent.appendChild(element);
+    }
+
+    if (fragment) this.appendChild(fragment);
+
+    return this;
+  },
+
+  appendText: function(text, where){
+    return this.grab(this.getDocument().newTextNode(text), where);
+  },
+
+  grab: function(el, where){
+    inserters[where || 'bottom'](document.id(el, true), this);
+    return this;
+  },
+
+  inject: function(el, where){
+    inserters[where || 'bottom'](this, document.id(el, true));
+    return this;
+  },
+
+  replaces: function(el){
+    el = document.id(el, true);
+    el.parentNode.replaceChild(this, el);
+    return this;
+  },
+
+  wraps: function(el, where){
+    el = document.id(el, true);
+    return this.replaces(el).grab(el, where);
+  },
+
+  getSelected: function(){
+    this.selectedIndex; // Safari 3.2.1
+    return new Elements(Array.from(this.options).filter(function(option){
+      return option.selected;
+    }));
+  },
+
+  toQueryString: function(){
+    var queryString = [];
+    this.getElements('input, select, textarea').each(function(el){
+      var type = el.type;
+      if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
+
+      var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){
+        // IE
+        return document.id(opt).get('value');
+      }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value');
+
+      Array.from(value).each(function(val){
+        if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
+      });
+    });
+    return queryString.join('&');
+  }
 
 });
 
@@ -3440,153 +3440,153 @@ Element.implement({
 // appendHTML
 
 var appendInserters = {
-	before: 'beforeBegin',
-	after: 'afterEnd',
-	bottom: 'beforeEnd',
-	top: 'afterBegin',
-	inside: 'beforeEnd'
+  before: 'beforeBegin',
+  after: 'afterEnd',
+  bottom: 'beforeEnd',
+  top: 'afterBegin',
+  inside: 'beforeEnd'
 };
 
 Element.implement('appendHTML', ('insertAdjacentHTML' in document.createElement('div')) ? function(html, where){
-	this.insertAdjacentHTML(appendInserters[where || 'bottom'], html);
-	return this;
+  this.insertAdjacentHTML(appendInserters[where || 'bottom'], html);
+  return this;
 } : function(html, where){
-	var temp = new Element('div', {html: html}),
-		children = temp.childNodes,
-		fragment = temp.firstChild;
-
-	if (!fragment) return this;
-	if (children.length > 1){
-		fragment = document.createDocumentFragment();
-		for (var i = 0, l = children.length; i < l; i++){
-			fragment.appendChild(children[i]);
-		}
-	}
-
-	inserters[where || 'bottom'](fragment, this);
-	return this;
+  var temp = new Element('div', {html: html}),
+    children = temp.childNodes,
+    fragment = temp.firstChild;
+
+  if (!fragment) return this;
+  if (children.length > 1){
+    fragment = document.createDocumentFragment();
+    for (var i = 0, l = children.length; i < l; i++){
+      fragment.appendChild(children[i]);
+    }
+  }
+
+  inserters[where || 'bottom'](fragment, this);
+  return this;
 });
 
 var collected = {}, storage = {};
 
 var get = function(uid){
-	return (storage[uid] || (storage[uid] = {}));
+  return (storage[uid] || (storage[uid] = {}));
 };
 
 var clean = function(item){
-	var uid = item.uniqueNumber;
-	if (item.removeEvents) item.removeEvents();
-	if (item.clearAttributes) item.clearAttributes();
-	if (uid != null){
-		delete collected[uid];
-		delete storage[uid];
-	}
-	return item;
+  var uid = item.uniqueNumber;
+  if (item.removeEvents) item.removeEvents();
+  if (item.clearAttributes) item.clearAttributes();
+  if (uid != null){
+    delete collected[uid];
+    delete storage[uid];
+  }
+  return item;
 };
 
 var formProps = {input: 'checked', option: 'selected', textarea: 'value'};
 
 Element.implement({
 
-	destroy: function(){
-		var children = clean(this).getElementsByTagName('*');
-		Array.each(children, clean);
-		Element.dispose(this);
-		return null;
-	},
-
-	empty: function(){
-		Array.from(this.childNodes).each(Element.dispose);
-		return this;
-	},
-
-	dispose: function(){
-		return (this.parentNode) ? this.parentNode.removeChild(this) : this;
-	},
-
-	clone: function(contents, keepid){
-		contents = contents !== false;
-		var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
-
-		if (contents){
-			ce.append(Array.from(clone.getElementsByTagName('*')));
-			te.append(Array.from(this.getElementsByTagName('*')));
-		}
-
-		for (i = ce.length; i--;){
-			var node = ce[i], element = te[i];
-			if (!keepid) node.removeAttribute('id');
-			/*<ltIE9>*/
-			if (node.clearAttributes){
-				node.clearAttributes();
-				node.mergeAttributes(element);
-				node.removeAttribute('uniqueNumber');
-				if (node.options){
-					var no = node.options, eo = element.options;
-					for (var j = no.length; j--;) no[j].selected = eo[j].selected;
-				}
-			}
-			/*</ltIE9>*/
-			var prop = formProps[element.tagName.toLowerCase()];
-			if (prop && element[prop]) node[prop] = element[prop];
-		}
-
-		/*<ltIE9>*/
-		if (hasCloneBug){
-			var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');
-			for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
-		}
-		/*</ltIE9>*/
-		return document.id(clone);
-	}
+  destroy: function(){
+    var children = clean(this).getElementsByTagName('*');
+    Array.each(children, clean);
+    Element.dispose(this);
+    return null;
+  },
+
+  empty: function(){
+    Array.from(this.childNodes).each(Element.dispose);
+    return this;
+  },
+
+  dispose: function(){
+    return (this.parentNode) ? this.parentNode.removeChild(this) : this;
+  },
+
+  clone: function(contents, keepid){
+    contents = contents !== false;
+    var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
+
+    if (contents){
+      ce.append(Array.from(clone.getElementsByTagName('*')));
+      te.append(Array.from(this.getElementsByTagName('*')));
+    }
+
+    for (i = ce.length; i--;){
+      var node = ce[i], element = te[i];
+      if (!keepid) node.removeAttribute('id');
+      /*<ltIE9>*/
+      if (node.clearAttributes){
+        node.clearAttributes();
+        node.mergeAttributes(element);
+        node.removeAttribute('uniqueNumber');
+        if (node.options){
+          var no = node.options, eo = element.options;
+          for (var j = no.length; j--;) no[j].selected = eo[j].selected;
+        }
+      }
+      /*</ltIE9>*/
+      var prop = formProps[element.tagName.toLowerCase()];
+      if (prop && element[prop]) node[prop] = element[prop];
+    }
+
+    /*<ltIE9>*/
+    if (hasCloneBug){
+      var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object');
+      for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
+    }
+    /*</ltIE9>*/
+    return document.id(clone);
+  }
 
 });
 
 [Element, Window, Document].invoke('implement', {
 
-	addListener: function(type, fn){
-		if (window.attachEvent && !window.addEventListener){
-			collected[Slick.uidOf(this)] = this;
-		}
-		if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
-		else this.attachEvent('on' + type, fn);
-		return this;
-	},
-
-	removeListener: function(type, fn){
-		if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
-		else this.detachEvent('on' + type, fn);
-		return this;
-	},
-
-	retrieve: function(property, dflt){
-		var storage = get(Slick.uidOf(this)), prop = storage[property];
-		if (dflt != null && prop == null) prop = storage[property] = dflt;
-		return prop != null ? prop : null;
-	},
-
-	store: function(property, value){
-		var storage = get(Slick.uidOf(this));
-		storage[property] = value;
-		return this;
-	},
-
-	eliminate: function(property){
-		var storage = get(Slick.uidOf(this));
-		delete storage[property];
-		return this;
-	}
+  addListener: function(type, fn){
+    if (window.attachEvent && !window.addEventListener){
+      collected[Slick.uidOf(this)] = this;
+    }
+    if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
+    else this.attachEvent('on' + type, fn);
+    return this;
+  },
+
+  removeListener: function(type, fn){
+    if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
+    else this.detachEvent('on' + type, fn);
+    return this;
+  },
+
+  retrieve: function(property, dflt){
+    var storage = get(Slick.uidOf(this)), prop = storage[property];
+    if (dflt != null && prop == null) prop = storage[property] = dflt;
+    return prop != null ? prop : null;
+  },
+
+  store: function(property, value){
+    var storage = get(Slick.uidOf(this));
+    storage[property] = value;
+    return this;
+  },
+
+  eliminate: function(property){
+    var storage = get(Slick.uidOf(this));
+    delete storage[property];
+    return this;
+  }
 
 });
 
 /*<ltIE9>*/
 if (window.attachEvent && !window.addEventListener){
-	var gc = function(){
-		Object.each(collected, clean);
-		if (window.CollectGarbage) CollectGarbage();
-		window.removeListener('unload', gc);
-	}
-	window.addListener('unload', gc);
+  var gc = function(){
+    Object.each(collected, clean);
+    if (window.CollectGarbage) CollectGarbage();
+    window.removeListener('unload', gc);
+  }
+  window.addListener('unload', gc);
 }
 /*</ltIE9>*/
 
@@ -3596,39 +3596,39 @@ Element.Properties = {};
 
 Element.Properties.style = {
 
-	set: function(style){
-		this.style.cssText = style;
-	},
+  set: function(style){
+    this.style.cssText = style;
+  },
 
-	get: function(){
-		return this.style.cssText;
-	},
+  get: function(){
+    return this.style.cssText;
+  },
 
-	erase: function(){
-		this.style.cssText = '';
-	}
+  erase: function(){
+    this.style.cssText = '';
+  }
 
 };
 
 Element.Properties.tag = {
 
-	get: function(){
-		return this.tagName.toLowerCase();
-	}
+  get: function(){
+    return this.tagName.toLowerCase();
+  }
 
 };
 
 Element.Properties.html = {
 
-	set: function(html){
-		if (html == null) html = '';
-		else if (typeOf(html) == 'array') html = html.join('');
-		this.innerHTML = html;
-	},
+  set: function(html){
+    if (html == null) html = '';
+    else if (typeOf(html) == 'array') html = html.join('');
+    this.innerHTML = html;
+  },
 
-	erase: function(){
-		this.innerHTML = '';
-	}
+  erase: function(){
+    this.innerHTML = '';
+  }
 
 };
 
@@ -3640,18 +3640,18 @@ var div = document.createElement('div');
 div.innerHTML = '<nav></nav>';
 supportsHTML5Elements = (div.childNodes.length == 1);
 if (!supportsHTML5Elements){
-	var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '),
-		fragment = document.createDocumentFragment(), l = tags.length;
-	while (l--) fragment.createElement(tags[l]);
+  var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '),
+    fragment = document.createDocumentFragment(), l = tags.length;
+  while (l--) fragment.createElement(tags[l]);
 }
 div = null;
 /*</ltIE9>*/
 
 /*<IE>*/
 supportsTableInnerHTML = Function.attempt(function(){
-	var table = document.createElement('table');
-	table.innerHTML = '<tr><td></td></tr>';
-	return true;
+  var table = document.createElement('table');
+  table.innerHTML = '<tr><td></td></tr>';
+  return true;
 });
 
 /*<ltFF4>*/
@@ -3663,32 +3663,32 @@ tr = null;
 
 if (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){
 
-	Element.Properties.html.set = (function(set){
+  Element.Properties.html.set = (function(set){
 
-		var translations = {
-			table: [1, '<table>', '</table>'],
-			select: [1, '<select>', '</select>'],
-			tbody: [2, '<table><tbody>', '</tbody></table>'],
-			tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
-		};
+    var translations = {
+      table: [1, '<table>', '</table>'],
+      select: [1, '<select>', '</select>'],
+      tbody: [2, '<table><tbody>', '</tbody></table>'],
+      tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
+    };
 
-		translations.thead = translations.tfoot = translations.tbody;
+    translations.thead = translations.tfoot = translations.tbody;
 
-		return function(html){
-			var wrap = translations[this.get('tag')];
-			if (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];
-			if (!wrap) return set.call(this, html);
+    return function(html){
+      var wrap = translations[this.get('tag')];
+      if (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];
+      if (!wrap) return set.call(this, html);
 
-			var level = wrap[0], wrapper = document.createElement('div'), target = wrapper;
-			if (!supportsHTML5Elements) fragment.appendChild(wrapper);
-			wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');
-			while (level--) target = target.firstChild;
-			this.empty().adopt(target.childNodes);
-			if (!supportsHTML5Elements) fragment.removeChild(wrapper);
-			wrapper = null;
-		};
+      var level = wrap[0], wrapper = document.createElement('div'), target = wrapper;
+      if (!supportsHTML5Elements) fragment.appendChild(wrapper);
+      wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');
+      while (level--) target = target.firstChild;
+      this.empty().adopt(target.childNodes);
+      if (!supportsHTML5Elements) fragment.removeChild(wrapper);
+      wrapper = null;
+    };
 
-	})(Element.Properties.html.set);
+  })(Element.Properties.html.set);
 }
 /*</IE>*/
 
@@ -3698,29 +3698,29 @@ testForm.innerHTML = '<select><option>s</option></select>';
 
 if (testForm.firstChild.value != 's') Element.Properties.value = {
 
-	set: function(value){
-		var tag = this.get('tag');
-		if (tag != 'select') return this.setProperty('value', value);
-		var options = this.getElements('option');
-		value = String(value);
-		for (var i = 0; i < options.length; i++){
-			var option = options[i],
-				attr = option.getAttributeNode('value'),
-				optionValue = (attr && attr.specified) ? option.value : option.get('text');
-			if (optionValue === value) return option.selected = true;
-		}
-	},
+  set: function(value){
+    var tag = this.get('tag');
+    if (tag != 'select') return this.setProperty('value', value);
+    var options = this.getElements('option');
+    value = String(value);
+    for (var i = 0; i < options.length; i++){
+      var option = options[i],
+        attr = option.getAttributeNode('value'),
+        optionValue = (attr && attr.specified) ? option.value : option.get('text');
+      if (optionValue === value) return option.selected = true;
+    }
+  },
 
-	get: function(){
-		var option = this, tag = option.get('tag');
+  get: function(){
+    var option = this, tag = option.get('tag');
 
-		if (tag != 'select' && tag != 'option') return this.getProperty('value');
+    if (tag != 'select' && tag != 'option') return this.getProperty('value');
 
-		if (tag == 'select' && !(option = option.getSelected()[0])) return '';
+    if (tag == 'select' && !(option = option.getSelected()[0])) return '';
 
-		var attr = option.getAttributeNode('value');
-		return (attr && attr.specified) ? option.value : option.get('text');
-	}
+    var attr = option.getAttributeNode('value');
+    return (attr && attr.specified) ? option.value : option.get('text');
+  }
 
 };
 testForm = null;
@@ -3728,15 +3728,15 @@ testForm = null;
 
 /*<IE>*/
 if (document.createElement('div').getAttributeNode('id')) Element.Properties.id = {
-	set: function(id){
-		this.id = this.getAttributeNode('id').value = id;
-	},
-	get: function(){
-		return this.id || null;
-	},
-	erase: function(){
-		this.id = this.getAttributeNode('id').value = '';
-	}
+  set: function(id){
+    this.id = this.getAttributeNode('id').value = id;
+  },
+  get: function(){
+    return this.id || null;
+  },
+  erase: function(){
+    this.id = this.getAttributeNode('id').value = '';
+  }
 };
 /*</IE>*/
 
@@ -3780,167 +3780,167 @@ el = null;
 var hasGetComputedStyle = !!window.getComputedStyle;
 
 Element.Properties.styles = {set: function(styles){
-	this.setStyles(styles);
+  this.setStyles(styles);
 }};
 
 var hasOpacity = (html.style.opacity != null),
-	hasFilter = (html.style.filter != null),
-	reAlpha = /alpha\(opacity=([\d.]+)\)/i;
+  hasFilter = (html.style.filter != null),
+  reAlpha = /alpha\(opacity=([\d.]+)\)/i;
 
 var setVisibility = function(element, opacity){
-	element.store('$opacity', opacity);
-	element.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden';
+  element.store('$opacity', opacity);
+  element.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden';
 };
 
 //<ltIE9>
 var setFilter = function(element, regexp, value){
-	var style = element.style,
-		filter = style.filter || element.getComputedStyle('filter') || '';
-	style.filter = (regexp.test(filter) ? filter.replace(regexp, value) : filter + ' ' + value).trim();
-	if (!style.filter) style.removeAttribute('filter');
+  var style = element.style,
+    filter = style.filter || element.getComputedStyle('filter') || '';
+  style.filter = (regexp.test(filter) ? filter.replace(regexp, value) : filter + ' ' + value).trim();
+  if (!style.filter) style.removeAttribute('filter');
 };
 //</ltIE9>
 
 var setOpacity = (hasOpacity ? function(element, opacity){
-	element.style.opacity = opacity;
+  element.style.opacity = opacity;
 } : (hasFilter ? function(element, opacity){
-	if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
-	if (opacity == null || opacity == 1){
-		setFilter(element, reAlpha, '');
-		if (opacity == 1 && getOpacity(element) != 1) setFilter(element, reAlpha, 'alpha(opacity=100)');
-	} else {
-		setFilter(element, reAlpha, 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')');
-	}
+  if (!element.currentStyle || !element.currentStyle.hasLayout) element.style.zoom = 1;
+  if (opacity == null || opacity == 1){
+    setFilter(element, reAlpha, '');
+    if (opacity == 1 && getOpacity(element) != 1) setFilter(element, reAlpha, 'alpha(opacity=100)');
+  } else {
+    setFilter(element, reAlpha, 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')');
+  }
 } : setVisibility));
 
 var getOpacity = (hasOpacity ? function(element){
-	var opacity = element.style.opacity || element.getComputedStyle('opacity');
-	return (opacity == '') ? 1 : opacity.toFloat();
+  var opacity = element.style.opacity || element.getComputedStyle('opacity');
+  return (opacity == '') ? 1 : opacity.toFloat();
 } : (hasFilter ? function(element){
-	var filter = (element.style.filter || element.getComputedStyle('filter')),
-		opacity;
-	if (filter) opacity = filter.match(reAlpha);
-	return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
+  var filter = (element.style.filter || element.getComputedStyle('filter')),
+    opacity;
+  if (filter) opacity = filter.match(reAlpha);
+  return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
 } : function(element){
-	var opacity = element.retrieve('$opacity');
-	if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);
-	return opacity;
+  var opacity = element.retrieve('$opacity');
+  if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);
+  return opacity;
 }));
 
 var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat',
-	namedPositions = {left: '0%', top: '0%', center: '50%', right: '100%', bottom: '100%'},
-	hasBackgroundPositionXY = (html.style.backgroundPositionX != null);
+  namedPositions = {left: '0%', top: '0%', center: '50%', right: '100%', bottom: '100%'},
+  hasBackgroundPositionXY = (html.style.backgroundPositionX != null);
 
 //<ltIE9>
 var removeStyle = function(style, property){
-	if (property == 'backgroundPosition'){
-		style.removeAttribute(property + 'X');
-		property += 'Y';
-	}
-	style.removeAttribute(property);
+  if (property == 'backgroundPosition'){
+    style.removeAttribute(property + 'X');
+    property += 'Y';
+  }
+  style.removeAttribute(property);
 };
 //</ltIE9>
 
 Element.implement({
 
-	getComputedStyle: function(property){
-		if (!hasGetComputedStyle && this.currentStyle) return this.currentStyle[property.camelCase()];
-		var defaultView = Element.getDocument(this).defaultView,
-			computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
-		return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : '';
-	},
-
-	setStyle: function(property, value){
-		if (property == 'opacity'){
-			if (value != null) value = parseFloat(value);
-			setOpacity(this, value);
-			return this;
-		}
-		property = (property == 'float' ? floatName : property).camelCase();
-		if (typeOf(value) != 'string'){
-			var map = (Element.Styles[property] || '@').split(' ');
-			value = Array.from(value).map(function(val, i){
-				if (!map[i]) return '';
-				return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
-			}).join(' ');
-		} else if (value == String(Number(value))){
-			value = Math.round(value);
-		}
-		this.style[property] = value;
-		//<ltIE9>
-		if ((value == '' || value == null) && doesNotRemoveStyles && this.style.removeAttribute){
-			removeStyle(this.style, property);
-		}
-		//</ltIE9>
-		return this;
-	},
-
-	getStyle: function(property){
-		if (property == 'opacity') return getOpacity(this);
-		property = (property == 'float' ? floatName : property).camelCase();
-		var result = this.style[property];
-		if (!result || property == 'zIndex'){
-			if (Element.ShortStyles.hasOwnProperty(property)){
-				result = [];
-				for (var s in Element.ShortStyles[property]) result.push(this.getStyle(s));
-				return result.join(' ');
-			}
-			result = this.getComputedStyle(property);
-		}
-		if (hasBackgroundPositionXY && /^backgroundPosition[XY]?$/.test(property)){
-			return result.replace(/(top|right|bottom|left)/g, function(position){
-				return namedPositions[position];
-			}) || '0px';
-		}
-		if (!result && property == 'backgroundPosition') return '0px 0px';
-		if (result){
-			result = String(result);
-			var color = result.match(/rgba?\([\d\s,]+\)/);
-			if (color) result = result.replace(color[0], color[0].rgbToHex());
-		}
-		if (!hasGetComputedStyle && !this.style[property]){
-			if ((/^(height|width)$/).test(property) && !(/px$/.test(result))){
-				var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
-				values.each(function(value){
-					size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
-				}, this);
-				return this['offset' + property.capitalize()] - size + 'px';
-			}
-			if ((/^border(.+)Width|margin|padding/).test(property) && isNaN(parseFloat(result))){
-				return '0px';
-			}
-		}
-		//<ltIE9>
-		if (returnsBordersInWrongOrder && /^border(Top|Right|Bottom|Left)?$/.test(property) && /^#/.test(result)){
-			return result.replace(/^(.+)\s(.+)\s(.+)$/, '$2 $3 $1');
-		}
-		//</ltIE9>
-		return result;
-	},
-
-	setStyles: function(styles){
-		for (var style in styles) this.setStyle(style, styles[style]);
-		return this;
-	},
-
-	getStyles: function(){
-		var result = {};
-		Array.flatten(arguments).each(function(key){
-			result[key] = this.getStyle(key);
-		}, this);
-		return result;
-	}
+  getComputedStyle: function(property){
+    if (!hasGetComputedStyle && this.currentStyle) return this.currentStyle[property.camelCase()];
+    var defaultView = Element.getDocument(this).defaultView,
+      computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
+    return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : '';
+  },
+
+  setStyle: function(property, value){
+    if (property == 'opacity'){
+      if (value != null) value = parseFloat(value);
+      setOpacity(this, value);
+      return this;
+    }
+    property = (property == 'float' ? floatName : property).camelCase();
+    if (typeOf(value) != 'string'){
+      var map = (Element.Styles[property] || '@').split(' ');
+      value = Array.from(value).map(function(val, i){
+        if (!map[i]) return '';
+        return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
+      }).join(' ');
+    } else if (value == String(Number(value))){
+      value = Math.round(value);
+    }
+    this.style[property] = value;
+    //<ltIE9>
+    if ((value == '' || value == null) && doesNotRemoveStyles && this.style.removeAttribute){
+      removeStyle(this.style, property);
+    }
+    //</ltIE9>
+    return this;
+  },
+
+  getStyle: function(property){
+    if (property == 'opacity') return getOpacity(this);
+    property = (property == 'float' ? floatName : property).camelCase();
+    var result = this.style[property];
+    if (!result || property == 'zIndex'){
+      if (Element.ShortStyles.hasOwnProperty(property)){
+        result = [];
+        for (var s in Element.ShortStyles[property]) result.push(this.getStyle(s));
+        return result.join(' ');
+      }
+      result = this.getComputedStyle(property);
+    }
+    if (hasBackgroundPositionXY && /^backgroundPosition[XY]?$/.test(property)){
+      return result.replace(/(top|right|bottom|left)/g, function(position){
+        return namedPositions[position];
+      }) || '0px';
+    }
+    if (!result && property == 'backgroundPosition') return '0px 0px';
+    if (result){
+      result = String(result);
+      var color = result.match(/rgba?\([\d\s,]+\)/);
+      if (color) result = result.replace(color[0], color[0].rgbToHex());
+    }
+    if (!hasGetComputedStyle && !this.style[property]){
+      if ((/^(height|width)$/).test(property) && !(/px$/.test(result))){
+        var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0;
+        values.each(function(value){
+          size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
+        }, this);
+        return this['offset' + property.capitalize()] - size + 'px';
+      }
+      if ((/^border(.+)Width|margin|padding/).test(property) && isNaN(parseFloat(result))){
+        return '0px';
+      }
+    }
+    //<ltIE9>
+    if (returnsBordersInWrongOrder && /^border(Top|Right|Bottom|Left)?$/.test(property) && /^#/.test(result)){
+      return result.replace(/^(.+)\s(.+)\s(.+)$/, '$2 $3 $1');
+    }
+    //</ltIE9>
+    return result;
+  },
+
+  setStyles: function(styles){
+    for (var style in styles) this.setStyle(style, styles[style]);
+    return this;
+  },
+
+  getStyles: function(){
+    var result = {};
+    Array.flatten(arguments).each(function(key){
+      result[key] = this.getStyle(key);
+    }, this);
+    return result;
+  }
 
 });
 
 Element.Styles = {
-	left: '@px', top: '@px', bottom: '@px', right: '@px',
-	width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
-	backgroundColor: 'rgb(@, @, @)', backgroundSize: '@px', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
-	fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
-	margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
-	borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
-	zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
+  left: '@px', top: '@px', bottom: '@px', right: '@px',
+  width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px',
+  backgroundColor: 'rgb(@, @, @)', backgroundSize: '@px', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
+  fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
+  margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
+  borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
+  zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
 };
 
 
@@ -3950,19 +3950,19 @@ Element.Styles = {
 Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}};
 
 ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
-	var Short = Element.ShortStyles;
-	var All = Element.Styles;
-	['margin', 'padding'].each(function(style){
-		var sd = style + direction;
-		Short[style][sd] = All[sd] = '@px';
-	});
-	var bd = 'border' + direction;
-	Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
-	var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
-	Short[bd] = {};
-	Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
-	Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
-	Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
+  var Short = Element.ShortStyles;
+  var All = Element.Styles;
+  ['margin', 'padding'].each(function(style){
+    var sd = style + direction;
+    Short[style][sd] = All[sd] = '@px';
+  });
+  var bd = 'border' + direction;
+  Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
+  var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
+  Short[bd] = {};
+  Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
+  Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
+  Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
 });
 
 if (hasBackgroundPositionXY) Element.ShortStyles.backgroundPosition = {backgroundPositionX: '@', backgroundPositionY: '@'};
@@ -3988,171 +3988,171 @@ provides: Element.Event
 (function(){
 
 Element.Properties.events = {set: function(events){
-	this.addEvents(events);
+  this.addEvents(events);
 }};
 
 [Element, Window, Document].invoke('implement', {
 
-	addEvent: function(type, fn){
-		var events = this.retrieve('events', {});
-		if (!events[type]) events[type] = {keys: [], values: []};
-		if (events[type].keys.contains(fn)) return this;
-		events[type].keys.push(fn);
-		var realType = type,
-			custom = Element.Events[type],
-			condition = fn,
-			self = this;
-		if (custom){
-			if (custom.onAdd) custom.onAdd.call(this, fn, type);
-			if (custom.condition){
-				condition = function(event){
-					if (custom.condition.call(this, event, type)) return fn.call(this, event);
-					return true;
-				};
-			}
-			if (custom.base) realType = Function.from(custom.base).call(this, type);
-		}
-		var defn = function(){
-			return fn.call(self);
-		};
-		var nativeEvent = Element.NativeEvents[realType];
-		if (nativeEvent){
-			if (nativeEvent == 2){
-				defn = function(event){
-					event = new DOMEvent(event, self.getWindow());
-					if (condition.call(self, event) === false) event.stop();
-				};
-			}
-			this.addListener(realType, defn, arguments[2]);
-		}
-		events[type].values.push(defn);
-		return this;
-	},
-
-	removeEvent: function(type, fn){
-		var events = this.retrieve('events');
-		if (!events || !events[type]) return this;
-		var list = events[type];
-		var index = list.keys.indexOf(fn);
-		if (index == -1) return this;
-		var value = list.values[index];
-		delete list.keys[index];
-		delete list.values[index];
-		var custom = Element.Events[type];
-		if (custom){
-			if (custom.onRemove) custom.onRemove.call(this, fn, type);
-			if (custom.base) type = Function.from(custom.base).call(this, type);
-		}
-		return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;
-	},
-
-	addEvents: function(events){
-		for (var event in events) this.addEvent(event, events[event]);
-		return this;
-	},
-
-	removeEvents: function(events){
-		var type;
-		if (typeOf(events) == 'object'){
-			for (type in events) this.removeEvent(type, events[type]);
-			return this;
-		}
-		var attached = this.retrieve('events');
-		if (!attached) return this;
-		if (!events){
-			for (type in attached) this.removeEvents(type);
-			this.eliminate('events');
-		} else if (attached[events]){
-			attached[events].keys.each(function(fn){
-				this.removeEvent(events, fn);
-			}, this);
-			delete attached[events];
-		}
-		return this;
-	},
-
-	fireEvent: function(type, args, delay){
-		var events = this.retrieve('events');
-		if (!events || !events[type]) return this;
-		args = Array.from(args);
-
-		events[type].keys.each(function(fn){
-			if (delay) fn.delay(delay, this, args);
-			else fn.apply(this, args);
-		}, this);
-		return this;
-	},
-
-	cloneEvents: function(from, type){
-		from = document.id(from);
-		var events = from.retrieve('events');
-		if (!events) return this;
-		if (!type){
-			for (var eventType in events) this.cloneEvents(from, eventType);
-		} else if (events[type]){
-			events[type].keys.each(function(fn){
-				this.addEvent(type, fn);
-			}, this);
-		}
-		return this;
-	}
+  addEvent: function(type, fn){
+    var events = this.retrieve('events', {});
+    if (!events[type]) events[type] = {keys: [], values: []};
+    if (events[type].keys.contains(fn)) return this;
+    events[type].keys.push(fn);
+    var realType = type,
+      custom = Element.Events[type],
+      condition = fn,
+      self = this;
+    if (custom){
+      if (custom.onAdd) custom.onAdd.call(this, fn, type);
+      if (custom.condition){
+        condition = function(event){
+          if (custom.condition.call(this, event, type)) return fn.call(this, event);
+          return true;
+        };
+      }
+      if (custom.base) realType = Function.from(custom.base).call(this, type);
+    }
+    var defn = function(){
+      return fn.call(self);
+    };
+    var nativeEvent = Element.NativeEvents[realType];
+    if (nativeEvent){
+      if (nativeEvent == 2){
+        defn = function(event){
+          event = new DOMEvent(event, self.getWindow());
+          if (condition.call(self, event) === false) event.stop();
+        };
+      }
+      this.addListener(realType, defn, arguments[2]);
+    }
+    events[type].values.push(defn);
+    return this;
+  },
+
+  removeEvent: function(type, fn){
+    var events = this.retrieve('events');
+    if (!events || !events[type]) return this;
+    var list = events[type];
+    var index = list.keys.indexOf(fn);
+    if (index == -1) return this;
+    var value = list.values[index];
+    delete list.keys[index];
+    delete list.values[index];
+    var custom = Element.Events[type];
+    if (custom){
+      if (custom.onRemove) custom.onRemove.call(this, fn, type);
+      if (custom.base) type = Function.from(custom.base).call(this, type);
+    }
+    return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;
+  },
+
+  addEvents: function(events){
+    for (var event in events) this.addEvent(event, events[event]);
+    return this;
+  },
+
+  removeEvents: function(events){
+    var type;
+    if (typeOf(events) == 'object'){
+      for (type in events) this.removeEvent(type, events[type]);
+      return this;
+    }
+    var attached = this.retrieve('events');
+    if (!attached) return this;
+    if (!events){
+      for (type in attached) this.removeEvents(type);
+      this.eliminate('events');
+    } else if (attached[events]){
+      attached[events].keys.each(function(fn){
+        this.removeEvent(events, fn);
+      }, this);
+      delete attached[events];
+    }
+    return this;
+  },
+
+  fireEvent: function(type, args, delay){
+    var events = this.retrieve('events');
+    if (!events || !events[type]) return this;
+    args = Array.from(args);
+
+    events[type].keys.each(function(fn){
+      if (delay) fn.delay(delay, this, args);
+      else fn.apply(this, args);
+    }, this);
+    return this;
+  },
+
+  cloneEvents: function(from, type){
+    from = document.id(from);
+    var events = from.retrieve('events');
+    if (!events) return this;
+    if (!type){
+      for (var eventType in events) this.cloneEvents(from, eventType);
+    } else if (events[type]){
+      events[type].keys.each(function(fn){
+        this.addEvent(type, fn);
+      }, this);
+    }
+    return this;
+  }
 
 });
 
 Element.NativeEvents = {
-	click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
-	mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
-	mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
-	keydown: 2, keypress: 2, keyup: 2, //keyboard
-	orientationchange: 2, // mobile
-	touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
-	gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
-	focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements
-	load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
-	hashchange: 1, popstate: 2, // history
-	error: 1, abort: 1, scroll: 1 //misc
+  click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
+  mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
+  mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
+  keydown: 2, keypress: 2, keyup: 2, //keyboard
+  orientationchange: 2, // mobile
+  touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
+  gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
+  focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements
+  load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
+  hashchange: 1, popstate: 2, // history
+  error: 1, abort: 1, scroll: 1 //misc
 };
 
 Element.Events = {
-	mousewheel: {
-		base: 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll'
-	}
+  mousewheel: {
+    base: 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll'
+  }
 };
 
 var check = function(event){
-	var related = event.relatedTarget;
-	if (related == null) return true;
-	if (!related) return false;
-	return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));
+  var related = event.relatedTarget;
+  if (related == null) return true;
+  if (!related) return false;
+  return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related));
 };
 
 if ('onmouseenter' in document.documentElement){
-	Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;
-	Element.MouseenterCheck = check;
+  Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;
+  Element.MouseenterCheck = check;
 } else {
-	Element.Events.mouseenter = {
-		base: 'mouseover',
-		condition: check
-	};
-
-	Element.Events.mouseleave = {
-		base: 'mouseout',
-		condition: check
-	};
+  Element.Events.mouseenter = {
+    base: 'mouseover',
+    condition: check
+  };
+
+  Element.Events.mouseleave = {
+    base: 'mouseout',
+    condition: check
+  };
 }
 
 /*<ltIE9>*/
 if (!window.addEventListener){
-	Element.NativeEvents.propertychange = 2;
-	Element.Events.change = {
-		base: function(){
-			var type = this.type;
-			return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change';
-		},
-		condition: function(event){
-			return event.type != 'propertychange' || event.event.propertyName == 'checked';
-		}
-	};
+  Element.NativeEvents.propertychange = 2;
+  Element.Events.change = {
+    base: function(){
+      var type = this.type;
+      return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change';
+    },
+    condition: function(event){
+      return event.type != 'propertychange' || event.event.propertyName == 'checked';
+    }
+  };
 }
 /*</ltIE9>*/
 
@@ -4184,181 +4184,181 @@ var eventListenerSupport = !!window.addEventListener;
 Element.NativeEvents.focusin = Element.NativeEvents.focusout = 2;
 
 var bubbleUp = function(self, match, fn, event, target){
-	while (target && target != self){
-		if (match(target, event)) return fn.call(target, event, target);
-		target = document.id(target.parentNode);
-	}
+  while (target && target != self){
+    if (match(target, event)) return fn.call(target, event, target);
+    target = document.id(target.parentNode);
+  }
 };
 
 var map = {
-	mouseenter: {
-		base: 'mouseover',
-		condition: Element.MouseenterCheck
-	},
-	mouseleave: {
-		base: 'mouseout',
-		condition: Element.MouseenterCheck
-	},
-	focus: {
-		base: 'focus' + (eventListenerSupport ? '' : 'in'),
-		capture: true
-	},
-	blur: {
-		base: eventListenerSupport ? 'blur' : 'focusout',
-		capture: true
-	}
+  mouseenter: {
+    base: 'mouseover',
+    condition: Element.MouseenterCheck
+  },
+  mouseleave: {
+    base: 'mouseout',
+    condition: Element.MouseenterCheck
+  },
+  focus: {
+    base: 'focus' + (eventListenerSupport ? '' : 'in'),
+    capture: true
+  },
+  blur: {
+    base: eventListenerSupport ? 'blur' : 'focusout',
+    capture: true
+  }
 };
 
 /*<ltIE9>*/
 var _key = '$delegation:';
 var formObserver = function(type){
 
-	return {
+  return {
 
-		base: 'focusin',
+    base: 'focusin',
 
-		remove: function(self, uid){
-			var list = self.retrieve(_key + type + 'listeners', {})[uid];
-			if (list && list.forms) for (var i = list.forms.length; i--;){
-				list.forms[i].removeEvent(type, list.fns[i]);
-			}
-		},
+    remove: function(self, uid){
+      var list = self.retrieve(_key + type + 'listeners', {})[uid];
+      if (list && list.forms) for (var i = list.forms.length; i--;){
+        list.forms[i].removeEvent(type, list.fns[i]);
+      }
+    },
 
-		listen: function(self, match, fn, event, target, uid){
-			var form = (target.get('tag') == 'form') ? target : event.target.getParent('form');
-			if (!form) return;
+    listen: function(self, match, fn, event, target, uid){
+      var form = (target.get('tag') == 'form') ? target : event.target.getParent('form');
+      if (!form) return;
 
-			var listeners = self.retrieve(_key + type + 'listeners', {}),
-				listener = listeners[uid] || {forms: [], fns: []},
-				forms = listener.forms, fns = listener.fns;
+      var listeners = self.retrieve(_key + type + 'listeners', {}),
+        listener = listeners[uid] || {forms: [], fns: []},
+        forms = listener.forms, fns = listener.fns;
 
-			if (forms.indexOf(form) != -1) return;
-			forms.push(form);
+      if (forms.indexOf(form) != -1) return;
+      forms.push(form);
 
-			var _fn = function(event){
-				bubbleUp(self, match, fn, event, target);
-			};
-			form.addEvent(type, _fn);
-			fns.push(_fn);
+      var _fn = function(event){
+        bubbleUp(self, match, fn, event, target);
+      };
+      form.addEvent(type, _fn);
+      fns.push(_fn);
 
-			listeners[uid] = listener;
-			self.store(_key + type + 'listeners', listeners);
-		}
-	};
+      listeners[uid] = listener;
+      self.store(_key + type + 'listeners', listeners);
+    }
+  };
 };
 
 var inputObserver = function(type){
-	return {
-		base: 'focusin',
-		listen: function(self, match, fn, event, target){
-			var events = {blur: function(){
-				this.removeEvents(events);
-			}};
-			events[type] = function(event){
-				bubbleUp(self, match, fn, event, target);
-			};
-			event.target.addEvents(events);
-		}
-	};
+  return {
+    base: 'focusin',
+    listen: function(self, match, fn, event, target){
+      var events = {blur: function(){
+        this.removeEvents(events);
+      }};
+      events[type] = function(event){
+        bubbleUp(self, match, fn, event, target);
+      };
+      event.target.addEvents(events);
+    }
+  };
 };
 
 if (!eventListenerSupport) Object.append(map, {
-	submit: formObserver('submit'),
-	reset: formObserver('reset'),
-	change: inputObserver('change'),
-	select: inputObserver('select')
+  submit: formObserver('submit'),
+  reset: formObserver('reset'),
+  change: inputObserver('change'),
+  select: inputObserver('select')
 });
 /*</ltIE9>*/
 
 var proto = Element.prototype,
-	addEvent = proto.addEvent,
-	removeEvent = proto.removeEvent;
+  addEvent = proto.addEvent,
+  removeEvent = proto.removeEvent;
 
 var relay = function(old, method){
-	return function(type, fn, useCapture){
-		if (type.indexOf(':relay') == -1) return old.call(this, type, fn, useCapture);
-		var parsed = Slick.parse(type).expressions[0][0];
-		if (parsed.pseudos[0].key != 'relay') return old.call(this, type, fn, useCapture);
-		var newType = parsed.tag;
-		parsed.pseudos.slice(1).each(function(pseudo){
-			newType += ':' + pseudo.key + (pseudo.value ? '(' + pseudo.value + ')' : '');
-		});
-		old.call(this, type, fn);
-		return method.call(this, newType, parsed.pseudos[0].value, fn);
-	};
+  return function(type, fn, useCapture){
+    if (type.indexOf(':relay') == -1) return old.call(this, type, fn, useCapture);
+    var parsed = Slick.parse(type).expressions[0][0];
+    if (parsed.pseudos[0].key != 'relay') return old.call(this, type, fn, useCapture);
+    var newType = parsed.tag;
+    parsed.pseudos.slice(1).each(function(pseudo){
+      newType += ':' + pseudo.key + (pseudo.value ? '(' + pseudo.value + ')' : '');
+    });
+    old.call(this, type, fn);
+    return method.call(this, newType, parsed.pseudos[0].value, fn);
+  };
 };
 
 var delegation = {
 
-	addEvent: function(type, match, fn){
-		var storage = this.retrieve('$delegates', {}), stored = storage[type];
-		if (stored) for (var _uid in stored){
-			if (stored[_uid].fn == fn && stored[_uid].match == match) return this;
-		}
-
-		var _type = type, _match = match, _fn = fn, _map = map[type] || {};
-		type = _map.base || _type;
-
-		match = function(target){
-			return Slick.match(target, _match);
-		};
-
-		var elementEvent = Element.Events[_type];
-		if (_map.condition || elementEvent && elementEvent.condition){
-			var __match = match, condition = _map.condition || elementEvent.condition;
-			match = function(target, event){
-				return __match(target, event) && condition.call(target, event, type);
-			};
-		}
-
-		var self = this, uid = String.uniqueID();
-		var delegator = _map.listen ? function(event, target){
-			if (!target && event && event.target) target = event.target;
-			if (target) _map.listen(self, match, fn, event, target, uid);
-		} : function(event, target){
-			if (!target && event && event.target) target = event.target;
-			if (target) bubbleUp(self, match, fn, event, target);
-		};
-
-		if (!stored) stored = {};
-		stored[uid] = {
-			match: _match,
-			fn: _fn,
-			delegator: delegator
-		};
-		storage[_type] = stored;
-		return addEvent.call(this, type, delegator, _map.capture);
-	},
-
-	removeEvent: function(type, match, fn, _uid){
-		var storage = this.retrieve('$delegates', {}), stored = storage[type];
-		if (!stored) return this;
-
-		if (_uid){
-			var _type = type, delegator = stored[_uid].delegator, _map = map[type] || {};
-			type = _map.base || _type;
-			if (_map.remove) _map.remove(this, _uid);
-			delete stored[_uid];
-			storage[_type] = stored;
-			return removeEvent.call(this, type, delegator, _map.capture);
-		}
-
-		var __uid, s;
-		if (fn) for (__uid in stored){
-			s = stored[__uid];
-			if (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid);
-		} else for (__uid in stored){
-			s = stored[__uid];
-			if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid);
-		}
-		return this;
-	}
+  addEvent: function(type, match, fn){
+    var storage = this.retrieve('$delegates', {}), stored = storage[type];
+    if (stored) for (var _uid in stored){
+      if (stored[_uid].fn == fn && stored[_uid].match == match) return this;
+    }
+
+    var _type = type, _match = match, _fn = fn, _map = map[type] || {};
+    type = _map.base || _type;
+
+    match = function(target){
+      return Slick.match(target, _match);
+    };
+
+    var elementEvent = Element.Events[_type];
+    if (_map.condition || elementEvent && elementEvent.condition){
+      var __match = match, condition = _map.condition || elementEvent.condition;
+      match = function(target, event){
+        return __match(target, event) && condition.call(target, event, type);
+      };
+    }
+
+    var self = this, uid = String.uniqueID();
+    var delegator = _map.listen ? function(event, target){
+      if (!target && event && event.target) target = event.target;
+      if (target) _map.listen(self, match, fn, event, target, uid);
+    } : function(event, target){
+      if (!target && event && event.target) target = event.target;
+      if (target) bubbleUp(self, match, fn, event, target);
+    };
+
+    if (!stored) stored = {};
+    stored[uid] = {
+      match: _match,
+      fn: _fn,
+      delegator: delegator
+    };
+    storage[_type] = stored;
+    return addEvent.call(this, type, delegator, _map.capture);
+  },
+
+  removeEvent: function(type, match, fn, _uid){
+    var storage = this.retrieve('$delegates', {}), stored = storage[type];
+    if (!stored) return this;
+
+    if (_uid){
+      var _type = type, delegator = stored[_uid].delegator, _map = map[type] || {};
+      type = _map.base || _type;
+      if (_map.remove) _map.remove(this, _uid);
+      delete stored[_uid];
+      storage[_type] = stored;
+      return removeEvent.call(this, type, delegator, _map.capture);
+    }
+
+    var __uid, s;
+    if (fn) for (__uid in stored){
+      s = stored[__uid];
+      if (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid);
+    } else for (__uid in stored){
+      s = stored[__uid];
+      if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid);
+    }
+    return this;
+  }
 
 };
 
 [Element, Window, Document].invoke('implement', {
-	addEvent: relay(addEvent, delegation.addEvent),
-	removeEvent: relay(removeEvent, delegation.removeEvent)
+  addEvent: relay(addEvent, delegation.addEvent),
+  removeEvent: relay(removeEvent, delegation.removeEvent)
 });
 
 })();
@@ -4387,177 +4387,177 @@ provides: [Element.Dimensions]
 (function(){
 
 var element = document.createElement('div'),
-	child = document.createElement('div');
+  child = document.createElement('div');
 element.style.height = '0';
 element.appendChild(child);
 var brokenOffsetParent = (child.offsetParent === element);
 element = child = null;
 
 var isOffset = function(el){
-	return styleString(el, 'position') != 'static' || isBody(el);
+  return styleString(el, 'position') != 'static' || isBody(el);
 };
 
 var isOffsetStatic = function(el){
-	return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
+  return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
 };
 
 Element.implement({
 
-	scrollTo: function(x, y){
-		if (isBody(this)){
-			this.getWindow().scrollTo(x, y);
-		} else {
-			this.scrollLeft = x;
-			this.scrollTop = y;
-		}
-		return this;
-	},
-
-	getSize: function(){
-		if (isBody(this)) return this.getWindow().getSize();
-		return {x: this.offsetWidth, y: this.offsetHeight};
-	},
-
-	getScrollSize: function(){
-		if (isBody(this)) return this.getWindow().getScrollSize();
-		return {x: this.scrollWidth, y: this.scrollHeight};
-	},
-
-	getScroll: function(){
-		if (isBody(this)) return this.getWindow().getScroll();
-		return {x: this.scrollLeft, y: this.scrollTop};
-	},
-
-	getScrolls: function(){
-		var element = this.parentNode, position = {x: 0, y: 0};
-		while (element && !isBody(element)){
-			position.x += element.scrollLeft;
-			position.y += element.scrollTop;
-			element = element.parentNode;
-		}
-		return position;
-	},
-
-	getOffsetParent: brokenOffsetParent ? function(){
-		var element = this;
-		if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
-
-		var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset;
-		while ((element = element.parentNode)){
-			if (isOffsetCheck(element)) return element;
-		}
-		return null;
-	} : function(){
-		var element = this;
-		if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
-
-		try {
-			return element.offsetParent;
-		} catch(e) {}
-		return null;
-	},
-
-	getOffsets: function(){
-		var hasGetBoundingClientRect = this.getBoundingClientRect;
-
-		if (hasGetBoundingClientRect){
-			var bound = this.getBoundingClientRect(),
-				html = document.id(this.getDocument().documentElement),
-				htmlScroll = html.getScroll(),
-				elemScrolls = this.getScrolls(),
-				isFixed = (styleString(this, 'position') == 'fixed');
-
-			return {
-				x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
-				y: bound.top.toInt()  + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
-			};
-		}
-
-		var element = this, position = {x: 0, y: 0};
-		if (isBody(this)) return position;
-
-		while (element && !isBody(element)){
-			position.x += element.offsetLeft;
-			position.y += element.offsetTop;
-
-			element = element.offsetParent;
-		}
-
-		return position;
-	},
-
-	getPosition: function(relative){
-		var offset = this.getOffsets(),
-			scroll = this.getScrolls();
-		var position = {
-			x: offset.x - scroll.x,
-			y: offset.y - scroll.y
-		};
-
-		if (relative && (relative = document.id(relative))){
-			var relativePosition = relative.getPosition();
-			return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};
-		}
-		return position;
-	},
-
-	getCoordinates: function(element){
-		if (isBody(this)) return this.getWindow().getCoordinates();
-		var position = this.getPosition(element),
-			size = this.getSize();
-		var obj = {
-			left: position.x,
-			top: position.y,
-			width: size.x,
-			height: size.y
-		};
-		obj.right = obj.left + obj.width;
-		obj.bottom = obj.top + obj.height;
-		return obj;
-	},
-
-	computePosition: function(obj){
-		return {
-			left: obj.x - styleNumber(this, 'margin-left'),
-			top: obj.y - styleNumber(this, 'margin-top')
-		};
-	},
-
-	setPosition: function(obj){
-		return this.setStyles(this.computePosition(obj));
-	}
+  scrollTo: function(x, y){
+    if (isBody(this)){
+      this.getWindow().scrollTo(x, y);
+    } else {
+      this.scrollLeft = x;
+      this.scrollTop = y;
+    }
+    return this;
+  },
+
+  getSize: function(){
+    if (isBody(this)) return this.getWindow().getSize();
+    return {x: this.offsetWidth, y: this.offsetHeight};
+  },
+
+  getScrollSize: function(){
+    if (isBody(this)) return this.getWindow().getScrollSize();
+    return {x: this.scrollWidth, y: this.scrollHeight};
+  },
+
+  getScroll: function(){
+    if (isBody(this)) return this.getWindow().getScroll();
+    return {x: this.scrollLeft, y: this.scrollTop};
+  },
+
+  getScrolls: function(){
+    var element = this.parentNode, position = {x: 0, y: 0};
+    while (element && !isBody(element)){
+      position.x += element.scrollLeft;
+      position.y += element.scrollTop;
+      element = element.parentNode;
+    }
+    return position;
+  },
+
+  getOffsetParent: brokenOffsetParent ? function(){
+    var element = this;
+    if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
+
+    var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset;
+    while ((element = element.parentNode)){
+      if (isOffsetCheck(element)) return element;
+    }
+    return null;
+  } : function(){
+    var element = this;
+    if (isBody(element) || styleString(element, 'position') == 'fixed') return null;
+
+    try {
+      return element.offsetParent;
+    } catch(e) {}
+    return null;
+  },
+
+  getOffsets: function(){
+    var hasGetBoundingClientRect = this.getBoundingClientRect;
+
+    if (hasGetBoundingClientRect){
+      var bound = this.getBoundingClientRect(),
+        html = document.id(this.getDocument().documentElement),
+        htmlScroll = html.getScroll(),
+        elemScrolls = this.getScrolls(),
+        isFixed = (styleString(this, 'position') == 'fixed');
+
+      return {
+        x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
+        y: bound.top.toInt()  + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
+      };
+    }
+
+    var element = this, position = {x: 0, y: 0};
+    if (isBody(this)) return position;
+
+    while (element && !isBody(element)){
+      position.x += element.offsetLeft;
+      position.y += element.offsetTop;
+
+      element = element.offsetParent;
+    }
+
+    return position;
+  },
+
+  getPosition: function(relative){
+    var offset = this.getOffsets(),
+      scroll = this.getScrolls();
+    var position = {
+      x: offset.x - scroll.x,
+      y: offset.y - scroll.y
+    };
+
+    if (relative && (relative = document.id(relative))){
+      var relativePosition = relative.getPosition();
+      return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)};
+    }
+    return position;
+  },
+
+  getCoordinates: function(element){
+    if (isBody(this)) return this.getWindow().getCoordinates();
+    var position = this.getPosition(element),
+      size = this.getSize();
+    var obj = {
+      left: position.x,
+      top: position.y,
+      width: size.x,
+      height: size.y
+    };
+    obj.right = obj.left + obj.width;
+    obj.bottom = obj.top + obj.height;
+    return obj;
+  },
+
+  computePosition: function(obj){
+    return {
+      left: obj.x - styleNumber(this, 'margin-left'),
+      top: obj.y - styleNumber(this, 'margin-top')
+    };
+  },
+
+  setPosition: function(obj){
+    return this.setStyles(this.computePosition(obj));
+  }
 
 });
 
 
 [Document, Window].invoke('implement', {
 
-	getSize: function(){
-		var doc = getCompatElement(this);
-		return {x: doc.clientWidth, y: doc.clientHeight};
-	},
+  getSize: function(){
+    var doc = getCompatElement(this);
+    return {x: doc.clientWidth, y: doc.clientHeight};
+  },
 
-	getScroll: function(){
-		var win = this.getWindow(), doc = getCompatElement(this);
-		return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
-	},
+  getScroll: function(){
+    var win = this.getWindow(), doc = getCompatElement(this);
+    return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
+  },
 
-	getScrollSize: function(){
-		var doc = getCompatElement(this),
-			min = this.getSize(),
-			body = this.getDocument().body;
+  getScrollSize: function(){
+    var doc = getCompatElement(this),
+      min = this.getSize(),
+      body = this.getDocument().body;
 
-		return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
-	},
+    return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
+  },
 
-	getPosition: function(){
-		return {x: 0, y: 0};
-	},
+  getPosition: function(){
+    return {x: 0, y: 0};
+  },
 
-	getCoordinates: function(){
-		var size = this.getSize();
-		return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
-	}
+  getCoordinates: function(){
+    var size = this.getSize();
+    return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
+  }
 
 });
 
@@ -4566,28 +4566,28 @@ Element.implement({
 var styleString = Element.getComputedStyle;
 
 function styleNumber(element, style){
-	return styleString(element, style).toInt() || 0;
+  return styleString(element, style).toInt() || 0;
 }
 
 function borderBox(element){
-	return styleString(element, '-moz-box-sizing') == 'border-box';
+  return styleString(element, '-moz-box-sizing') == 'border-box';
 }
 
 function topBorder(element){
-	return styleNumber(element, 'border-top-width');
+  return styleNumber(element, 'border-top-width');
 }
 
 function leftBorder(element){
-	return styleNumber(element, 'border-left-width');
+  return styleNumber(element, 'border-left-width');
 }
 
 function isBody(element){
-	return (/^(?:body|html)$/i).test(element.tagName);
+  return (/^(?:body|html)$/i).test(element.tagName);
 }
 
 function getCompatElement(element){
-	var doc = element.getDocument();
-	return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
+  var doc = element.getDocument();
+  return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
 }
 
 })();
@@ -4597,37 +4597,37 @@ Element.alias({position: 'setPosition'}); //compatability
 
 [Window, Document, Element].invoke('implement', {
 
-	getHeight: function(){
-		return this.getSize().y;
-	},
+  getHeight: function(){
+    return this.getSize().y;
+  },
 
-	getWidth: function(){
-		return this.getSize().x;
-	},
+  getWidth: function(){
+    return this.getSize().x;
+  },
 
-	getScrollTop: function(){
-		return this.getScroll().y;
-	},
+  getScrollTop: function(){
+    return this.getScroll().y;
+  },
 
-	getScrollLeft: function(){
-		return this.getScroll().x;
-	},
+  getScrollLeft: function(){
+    return this.getScroll().x;
+  },
 
-	getScrollHeight: function(){
-		return this.getScrollSize().y;
-	},
+  getScrollHeight: function(){
+    return this.getScrollSize().y;
+  },
 
-	getScrollWidth: function(){
-		return this.getScrollSize().x;
-	},
+  getScrollWidth: function(){
+    return this.getScrollSize().x;
+  },
 
-	getTop: function(){
-		return this.getPosition().y;
-	},
+  getTop: function(){
+    return this.getPosition().y;
+  },
 
-	getLeft: function(){
-		return this.getPosition().x;
-	}
+  getLeft: function(){
+    return this.getPosition().x;
+  }
 
 });
 
@@ -4652,135 +4652,135 @@ provides: Fx
 
 var Fx = this.Fx = new Class({
 
-	Implements: [Chain, Events, Options],
-
-	options: {
-		/*
-		onStart: nil,
-		onCancel: nil,
-		onComplete: nil,
-		*/
-		fps: 60,
-		unit: false,
-		duration: 500,
-		frames: null,
-		frameSkip: true,
-		link: 'ignore'
-	},
-
-	initialize: function(options){
-		this.subject = this.subject || this;
-		this.setOptions(options);
-	},
-
-	getTransition: function(){
-		return function(p){
-			return -(Math.cos(Math.PI * p) - 1) / 2;
-		};
-	},
-
-	step: function(now){
-		if (this.options.frameSkip){
-			var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;
-			this.time = now;
-			this.frame += frames;
-		} else {
-			this.frame++;
-		}
-
-		if (this.frame < this.frames){
-			var delta = this.transition(this.frame / this.frames);
-			this.set(this.compute(this.from, this.to, delta));
-		} else {
-			this.frame = this.frames;
-			this.set(this.compute(this.from, this.to, 1));
-			this.stop();
-		}
-	},
-
-	set: function(now){
-		return now;
-	},
-
-	compute: function(from, to, delta){
-		return Fx.compute(from, to, delta);
-	},
-
-	check: function(){
-		if (!this.isRunning()) return true;
-		switch (this.options.link){
-			case 'cancel': this.cancel(); return true;
-			case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
-		}
-		return false;
-	},
-
-	start: function(from, to){
-		if (!this.check(from, to)) return this;
-		this.from = from;
-		this.to = to;
-		this.frame = (this.options.frameSkip) ? 0 : -1;
-		this.time = null;
-		this.transition = this.getTransition();
-		var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration;
-		this.duration = Fx.Durations[duration] || duration.toInt();
-		this.frameInterval = 1000 / fps;
-		this.frames = frames || Math.round(this.duration / this.frameInterval);
-		this.fireEvent('start', this.subject);
-		pushInstance.call(this, fps);
-		return this;
-	},
-
-	stop: function(){
-		if (this.isRunning()){
-			this.time = null;
-			pullInstance.call(this, this.options.fps);
-			if (this.frames == this.frame){
-				this.fireEvent('complete', this.subject);
-				if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
-			} else {
-				this.fireEvent('stop', this.subject);
-			}
-		}
-		return this;
-	},
-
-	cancel: function(){
-		if (this.isRunning()){
-			this.time = null;
-			pullInstance.call(this, this.options.fps);
-			this.frame = this.frames;
-			this.fireEvent('cancel', this.subject).clearChain();
-		}
-		return this;
-	},
-
-	pause: function(){
-		if (this.isRunning()){
-			this.time = null;
-			pullInstance.call(this, this.options.fps);
-		}
-		return this;
-	},
-
-	resume: function(){
-		if (this.isPaused()) pushInstance.call(this, this.options.fps);
-		return this;
-	},
-
-	isRunning: function(){
-		var list = instances[this.options.fps];
-		return list && list.contains(this);
-	},
-
-	isPaused: function(){
-		return (this.frame < this.frames) && !this.isRunning();
-	}
+  Implements: [Chain, Events, Options],
+
+  options: {
+    /*
+    onStart: nil,
+    onCancel: nil,
+    onComplete: nil,
+    */
+    fps: 60,
+    unit: false,
+    duration: 500,
+    frames: null,
+    frameSkip: true,
+    link: 'ignore'
+  },
+
+  initialize: function(options){
+    this.subject = this.subject || this;
+    this.setOptions(options);
+  },
+
+  getTransition: function(){
+    return function(p){
+      return -(Math.cos(Math.PI * p) - 1) / 2;
+    };
+  },
+
+  step: function(now){
+    if (this.options.frameSkip){
+      var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;
+      this.time = now;
+      this.frame += frames;
+    } else {
+      this.frame++;
+    }
+
+    if (this.frame < this.frames){
+      var delta = this.transition(this.frame / this.frames);
+      this.set(this.compute(this.from, this.to, delta));
+    } else {
+      this.frame = this.frames;
+      this.set(this.compute(this.from, this.to, 1));
+      this.stop();
+    }
+  },
+
+  set: function(now){
+    return now;
+  },
+
+  compute: function(from, to, delta){
+    return Fx.compute(from, to, delta);
+  },
+
+  check: function(){
+    if (!this.isRunning()) return true;
+    switch (this.options.link){
+      case 'cancel': this.cancel(); return true;
+      case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
+    }
+    return false;
+  },
+
+  start: function(from, to){
+    if (!this.check(from, to)) return this;
+    this.from = from;
+    this.to = to;
+    this.frame = (this.options.frameSkip) ? 0 : -1;
+    this.time = null;
+    this.transition = this.getTransition();
+    var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration;
+    this.duration = Fx.Durations[duration] || duration.toInt();
+    this.frameInterval = 1000 / fps;
+    this.frames = frames || Math.round(this.duration / this.frameInterval);
+    this.fireEvent('start', this.subject);
+    pushInstance.call(this, fps);
+    return this;
+  },
+
+  stop: function(){
+    if (this.isRunning()){
+      this.time = null;
+      pullInstance.call(this, this.options.fps);
+      if (this.frames == this.frame){
+        this.fireEvent('complete', this.subject);
+        if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
+      } else {
+        this.fireEvent('stop', this.subject);
+      }
+    }
+    return this;
+  },
+
+  cancel: function(){
+    if (this.isRunning()){
+      this.time = null;
+      pullInstance.call(this, this.options.fps);
+      this.frame = this.frames;
+      this.fireEvent('cancel', this.subject).clearChain();
+    }
+    return this;
+  },
+
+  pause: function(){
+    if (this.isRunning()){
+      this.time = null;
+      pullInstance.call(this, this.options.fps);
+    }
+    return this;
+  },
+
+  resume: function(){
+    if (this.isPaused()) pushInstance.call(this, this.options.fps);
+    return this;
+  },
+
+  isRunning: function(){
+    var list = instances[this.options.fps];
+    return list && list.contains(this);
+  },
+
+  isPaused: function(){
+    return (this.frame < this.frames) && !this.isRunning();
+  }
 
 });
 
 Fx.compute = function(from, to, delta){
-	return (to - from) * delta + from;
+  return (to - from) * delta + from;
 };
 
 Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
@@ -4790,28 +4790,28 @@ Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
 var instances = {}, timers = {};
 
 var loop = function(){
-	var now = Date.now();
-	for (var i = this.length; i--;){
-		var instance = this[i];
-		if (instance) instance.step(now);
-	}
+  var now = Date.now();
+  for (var i = this.length; i--;){
+    var instance = this[i];
+    if (instance) instance.step(now);
+  }
 };
 
 var pushInstance = function(fps){
-	var list = instances[fps] || (instances[fps] = []);
-	list.push(this);
-	if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
+  var list = instances[fps] || (instances[fps] = []);
+  list.push(this);
+  if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
 };
 
 var pullInstance = function(fps){
-	var list = instances[fps];
-	if (list){
-		list.erase(this);
-		if (!list.length && timers[fps]){
-			delete instances[fps];
-			timers[fps] = clearInterval(timers[fps]);
-		}
-	}
+  var list = instances[fps];
+  if (list){
+    list.erase(this);
+    if (!list.length && timers[fps]){
+      delete instances[fps];
+      timers[fps] = clearInterval(timers[fps]);
+    }
+  }
 };
 
 })();
@@ -4835,118 +4835,118 @@ provides: Fx.CSS
 
 Fx.CSS = new Class({
 
-	Extends: Fx,
-
-	//prepares the base from/to object
-
-	prepare: function(element, property, values){
-		values = Array.from(values);
-		var from = values[0], to = values[1];
-		if (to == null){
-			to = from;
-			from = element.getStyle(property);
-			var unit = this.options.unit;
-			// adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299
-			if (unit && from && typeof from == 'string' && from.slice(-unit.length) != unit && parseFloat(from) != 0){
-				element.setStyle(property, to + unit);
-				var value = element.getComputedStyle(property);
-				// IE and Opera support pixelLeft or pixelWidth
-				if (!(/px$/.test(value))){
-					value = element.style[('pixel-' + property).camelCase()];
-					if (value == null){
-						// adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-						var left = element.style.left;
-						element.style.left = to + unit;
-						value = element.style.pixelLeft;
-						element.style.left = left;
-					}
-				}
-				from = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0);
-				element.setStyle(property, from + unit);
-			}
-		}
-		return {from: this.parse(from), to: this.parse(to)};
-	},
-
-	//parses a value into an array
-
-	parse: function(value){
-		value = Function.from(value)();
-		value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
-		return value.map(function(val){
-			val = String(val);
-			var found = false;
-			Object.each(Fx.CSS.Parsers, function(parser, key){
-				if (found) return;
-				var parsed = parser.parse(val);
-				if (parsed || parsed === 0) found = {value: parsed, parser: parser};
-			});
-			found = found || {value: val, parser: Fx.CSS.Parsers.String};
-			return found;
-		});
-	},
-
-	//computes by a from and to prepared objects, using their parsers.
-
-	compute: function(from, to, delta){
-		var computed = [];
-		(Math.min(from.length, to.length)).times(function(i){
-			computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
-		});
-		computed.$family = Function.from('fx:css:value');
-		return computed;
-	},
-
-	//serves the value as settable
-
-	serve: function(value, unit){
-		if (typeOf(value) != 'fx:css:value') value = this.parse(value);
-		var returned = [];
-		value.each(function(bit){
-			returned = returned.concat(bit.parser.serve(bit.value, unit));
-		});
-		return returned;
-	},
-
-	//renders the change to an element
-
-	render: function(element, property, value, unit){
-		element.setStyle(property, this.serve(value, unit));
-	},
-
-	//searches inside the page css to find the values for a selector
-
-	search: function(selector){
-		if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
-		var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
-
-		var searchStyles = function(rules){
-			Array.each(rules, function(rule, i){
-				if (rule.media){
-					searchStyles(rule.rules || rule.cssRules);
-					return;
-				}
-				if (!rule.style) return;
-				var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
-					return m.toLowerCase();
-				}) : null;
-				if (!selectorText || !selectorTest.test(selectorText)) return;
-				Object.each(Element.Styles, function(value, style){
-					if (!rule.style[style] || Element.ShortStyles[style]) return;
-					value = String(rule.style[style]);
-					to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
-				});
-			});
-		};
-
-		Array.each(document.styleSheets, function(sheet, j){
-			var href = sheet.href;
-			if (href && href.indexOf('://') > -1 && href.indexOf(document.domain) == -1) return;
-			var rules = sheet.rules || sheet.cssRules;
-			searchStyles(rules);
-		});
-		return Fx.CSS.Cache[selector] = to;
-	}
+  Extends: Fx,
+
+  //prepares the base from/to object
+
+  prepare: function(element, property, values){
+    values = Array.from(values);
+    var from = values[0], to = values[1];
+    if (to == null){
+      to = from;
+      from = element.getStyle(property);
+      var unit = this.options.unit;
+      // adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299
+      if (unit && from && typeof from == 'string' && from.slice(-unit.length) != unit && parseFloat(from) != 0){
+        element.setStyle(property, to + unit);
+        var value = element.getComputedStyle(property);
+        // IE and Opera support pixelLeft or pixelWidth
+        if (!(/px$/.test(value))){
+          value = element.style[('pixel-' + property).camelCase()];
+          if (value == null){
+            // adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+            var left = element.style.left;
+            element.style.left = to + unit;
+            value = element.style.pixelLeft;
+            element.style.left = left;
+          }
+        }
+        from = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0);
+        element.setStyle(property, from + unit);
+      }
+    }
+    return {from: this.parse(from), to: this.parse(to)};
+  },
+
+  //parses a value into an array
+
+  parse: function(value){
+    value = Function.from(value)();
+    value = (typeof value == 'string') ? value.split(' ') : Array.from(value);
+    return value.map(function(val){
+      val = String(val);
+      var found = false;
+      Object.each(Fx.CSS.Parsers, function(parser, key){
+        if (found) return;
+        var parsed = parser.parse(val);
+        if (parsed || parsed === 0) found = {value: parsed, parser: parser};
+      });
+      found = found || {value: val, parser: Fx.CSS.Parsers.String};
+      return found;
+    });
+  },
+
+  //computes by a from and to prepared objects, using their parsers.
+
+  compute: function(from, to, delta){
+    var computed = [];
+    (Math.min(from.length, to.length)).times(function(i){
+      computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser});
+    });
+    computed.$family = Function.from('fx:css:value');
+    return computed;
+  },
+
+  //serves the value as settable
+
+  serve: function(value, unit){
+    if (typeOf(value) != 'fx:css:value') value = this.parse(value);
+    var returned = [];
+    value.each(function(bit){
+      returned = returned.concat(bit.parser.serve(bit.value, unit));
+    });
+    return returned;
+  },
+
+  //renders the change to an element
+
+  render: function(element, property, value, unit){
+    element.setStyle(property, this.serve(value, unit));
+  },
+
+  //searches inside the page css to find the values for a selector
+
+  search: function(selector){
+    if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
+    var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$');
+
+    var searchStyles = function(rules){
+      Array.each(rules, function(rule, i){
+        if (rule.media){
+          searchStyles(rule.rules || rule.cssRules);
+          return;
+        }
+        if (!rule.style) return;
+        var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){
+          return m.toLowerCase();
+        }) : null;
+        if (!selectorText || !selectorTest.test(selectorText)) return;
+        Object.each(Element.Styles, function(value, style){
+          if (!rule.style[style] || Element.ShortStyles[style]) return;
+          value = String(rule.style[style]);
+          to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value;
+        });
+      });
+    };
+
+    Array.each(document.styleSheets, function(sheet, j){
+      var href = sheet.href;
+      if (href && href.indexOf('://') > -1 && href.indexOf(document.domain) == -1) return;
+      var rules = sheet.rules || sheet.cssRules;
+      searchStyles(rules);
+    });
+    return Fx.CSS.Cache[selector] = to;
+  }
 
 });
 
@@ -4954,38 +4954,38 @@ Fx.CSS.Cache = {};
 
 Fx.CSS.Parsers = {
 
-	Color: {
-		parse: function(value){
-			if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
-			return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
-		},
-		compute: function(from, to, delta){
-			return from.map(function(value, i){
-				return Math.round(Fx.compute(from[i], to[i], delta));
-			});
-		},
-		serve: function(value){
-			return value.map(Number);
-		}
-	},
-
-	Number: {
-		parse: parseFloat,
-		compute: Fx.compute,
-		serve: function(value, unit){
-			return (unit) ? value + unit : value;
-		}
-	},
-
-	String: {
-		parse: Function.from(false),
-		compute: function(zero, one){
-			return one;
-		},
-		serve: function(zero){
-			return zero;
-		}
-	}
+  Color: {
+    parse: function(value){
+      if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true);
+      return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false;
+    },
+    compute: function(from, to, delta){
+      return from.map(function(value, i){
+        return Math.round(Fx.compute(from[i], to[i], delta));
+      });
+    },
+    serve: function(value){
+      return value.map(Number);
+    }
+  },
+
+  Number: {
+    parse: parseFloat,
+    compute: Fx.compute,
+    serve: function(value, unit){
+      return (unit) ? value + unit : value;
+    }
+  },
+
+  String: {
+    parse: Function.from(false),
+    compute: function(zero, one){
+      return one;
+    },
+    serve: function(zero){
+      return zero;
+    }
+  }
 
 };
 
@@ -5010,97 +5010,97 @@ provides: [Fx.Tween, Element.fade, Element.highlight]
 
 Fx.Tween = new Class({
 
-	Extends: Fx.CSS,
-
-	initialize: function(element, options){
-		this.element = this.subject = document.id(element);
-		this.parent(options);
-	},
-
-	set: function(property, now){
-		if (arguments.length == 1){
-			now = property;
-			property = this.property || this.options.property;
-		}
-		this.render(this.element, property, now, this.options.unit);
-		return this;
-	},
-
-	start: function(property, from, to){
-		if (!this.check(property, from, to)) return this;
-		var args = Array.flatten(arguments);
-		this.property = this.options.property || args.shift();
-		var parsed = this.prepare(this.element, this.property, args);
-		return this.parent(parsed.from, parsed.to);
-	}
+  Extends: Fx.CSS,
+
+  initialize: function(element, options){
+    this.element = this.subject = document.id(element);
+    this.parent(options);
+  },
+
+  set: function(property, now){
+    if (arguments.length == 1){
+      now = property;
+      property = this.property || this.options.property;
+    }
+    this.render(this.element, property, now, this.options.unit);
+    return this;
+  },
+
+  start: function(property, from, to){
+    if (!this.check(property, from, to)) return this;
+    var args = Array.flatten(arguments);
+    this.property = this.options.property || args.shift();
+    var parsed = this.prepare(this.element, this.property, args);
+    return this.parent(parsed.from, parsed.to);
+  }
 
 });
 
 Element.Properties.tween = {
 
-	set: function(options){
-		this.get('tween').cancel().setOptions(options);
-		return this;
-	},
+  set: function(options){
+    this.get('tween').cancel().setOptions(options);
+    return this;
+  },
 
-	get: function(){
-		var tween = this.retrieve('tween');
-		if (!tween){
-			tween = new Fx.Tween(this, {link: 'cancel'});
-			this.store('tween', tween);
-		}
-		return tween;
-	}
+  get: function(){
+    var tween = this.retrieve('tween');
+    if (!tween){
+      tween = new Fx.Tween(this, {link: 'cancel'});
+      this.store('tween', tween);
+    }
+    return tween;
+  }
 
 };
 
 Element.implement({
 
-	tween: function(property, from, to){
-		this.get('tween').start(property, from, to);
-		return this;
-	},
-
-	fade: function(how){
-		var fade = this.get('tween'), method, args = ['opacity'].append(arguments), toggle;
-		if (args[1] == null) args[1] = 'toggle';
-		switch (args[1]){
-			case 'in': method = 'start'; args[1] = 1; break;
-			case 'out': method = 'start'; args[1] = 0; break;
-			case 'show': method = 'set'; args[1] = 1; break;
-			case 'hide': method = 'set'; args[1] = 0; break;
-			case 'toggle':
-				var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);
-				method = 'start';
-				args[1] = flag ? 0 : 1;
-				this.store('fade:flag', !flag);
-				toggle = true;
-			break;
-			default: method = 'start';
-		}
-		if (!toggle) this.eliminate('fade:flag');
-		fade[method].apply(fade, args);
-		var to = args[args.length - 1];
-		if (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
-		else fade.chain(function(){
-			this.element.setStyle('visibility', 'hidden');
-			this.callChain();
-		});
-		return this;
-	},
-
-	highlight: function(start, end){
-		if (!end){
-			end = this.retrieve('highlight:original', this.getStyle('background-color'));
-			end = (end == 'transparent') ? '#fff' : end;
-		}
-		var tween = this.get('tween');
-		tween.start('background-color', start || '#ffff88', end).chain(function(){
-			this.setStyle('background-color', this.retrieve('highlight:original'));
-			tween.callChain();
-		}.bind(this));
-		return this;
-	}
+  tween: function(property, from, to){
+    this.get('tween').start(property, from, to);
+    return this;
+  },
+
+  fade: function(how){
+    var fade = this.get('tween'), method, args = ['opacity'].append(arguments), toggle;
+    if (args[1] == null) args[1] = 'toggle';
+    switch (args[1]){
+      case 'in': method = 'start'; args[1] = 1; break;
+      case 'out': method = 'start'; args[1] = 0; break;
+      case 'show': method = 'set'; args[1] = 1; break;
+      case 'hide': method = 'set'; args[1] = 0; break;
+      case 'toggle':
+        var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1);
+        method = 'start';
+        args[1] = flag ? 0 : 1;
+        this.store('fade:flag', !flag);
+        toggle = true;
+      break;
+      default: method = 'start';
+    }
+    if (!toggle) this.eliminate('fade:flag');
+    fade[method].apply(fade, args);
+    var to = args[args.length - 1];
+    if (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible');
+    else fade.chain(function(){
+      this.element.setStyle('visibility', 'hidden');
+      this.callChain();
+    });
+    return this;
+  },
+
+  highlight: function(start, end){
+    if (!end){
+      end = this.retrieve('highlight:original', this.getStyle('background-color'));
+      end = (end == 'transparent') ? '#fff' : end;
+    }
+    var tween = this.get('tween');
+    tween.start('background-color', start || '#ffff88', end).chain(function(){
+      this.setStyle('background-color', this.retrieve('highlight:original'));
+      tween.callChain();
+    }.bind(this));
+    return this;
+  }
 
 });
 
@@ -5123,63 +5123,63 @@ provides: Fx.Morph
 
 Fx.Morph = new Class({
 
-	Extends: Fx.CSS,
-
-	initialize: function(element, options){
-		this.element = this.subject = document.id(element);
-		this.parent(options);
-	},
-
-	set: function(now){
-		if (typeof now == 'string') now = this.search(now);
-		for (var p in now) this.render(this.element, p, now[p], this.options.unit);
-		return this;
-	},
-
-	compute: function(from, to, delta){
-		var now = {};
-		for (var p in from) now[p] = this.parent(from[p], to[p], delta);
-		return now;
-	},
-
-	start: function(properties){
-		if (!this.check(properties)) return this;
-		if (typeof properties == 'string') properties = this.search(properties);
-		var from = {}, to = {};
-		for (var p in properties){
-			var parsed = this.prepare(this.element, p, properties[p]);
-			from[p] = parsed.from;
-			to[p] = parsed.to;
-		}
-		return this.parent(from, to);
-	}
+  Extends: Fx.CSS,
+
+  initialize: function(element, options){
+    this.element = this.subject = document.id(element);
+    this.parent(options);
+  },
+
+  set: function(now){
+    if (typeof now == 'string') now = this.search(now);
+    for (var p in now) this.render(this.element, p, now[p], this.options.unit);
+    return this;
+  },
+
+  compute: function(from, to, delta){
+    var now = {};
+    for (var p in from) now[p] = this.parent(from[p], to[p], delta);
+    return now;
+  },
+
+  start: function(properties){
+    if (!this.check(properties)) return this;
+    if (typeof properties == 'string') properties = this.search(properties);
+    var from = {}, to = {};
+    for (var p in properties){
+      var parsed = this.prepare(this.element, p, properties[p]);
+      from[p] = parsed.from;
+      to[p] = parsed.to;
+    }
+    return this.parent(from, to);
+  }
 
 });
 
 Element.Properties.morph = {
 
-	set: function(options){
-		this.get('morph').cancel().setOptions(options);
-		return this;
-	},
+  set: function(options){
+    this.get('morph').cancel().setOptions(options);
+    return this;
+  },
 
-	get: function(){
-		var morph = this.retrieve('morph');
-		if (!morph){
-			morph = new Fx.Morph(this, {link: 'cancel'});
-			this.store('morph', morph);
-		}
-		return morph;
-	}
+  get: function(){
+    var morph = this.retrieve('morph');
+    if (!morph){
+      morph = new Fx.Morph(this, {link: 'cancel'});
+      this.store('morph', morph);
+    }
+    return morph;
+  }
 
 };
 
 Element.implement({
 
-	morph: function(props){
-		this.get('morph').start(props);
-		return this;
-	}
+  morph: function(props){
+    this.get('morph').start(props);
+    return this;
+  }
 
 });
 
@@ -5205,93 +5205,93 @@ provides: Fx.Transitions
 
 Fx.implement({
 
-	getTransition: function(){
-		var trans = this.options.transition || Fx.Transitions.Sine.easeInOut;
-		if (typeof trans == 'string'){
-			var data = trans.split(':');
-			trans = Fx.Transitions;
-			trans = trans[data[0]] || trans[data[0].capitalize()];
-			if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
-		}
-		return trans;
-	}
+  getTransition: function(){
+    var trans = this.options.transition || Fx.Transitions.Sine.easeInOut;
+    if (typeof trans == 'string'){
+      var data = trans.split(':');
+      trans = Fx.Transitions;
+      trans = trans[data[0]] || trans[data[0].capitalize()];
+      if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
+    }
+    return trans;
+  }
 
 });
 
 Fx.Transition = function(transition, params){
-	params = Array.from(params);
-	var easeIn = function(pos){
-		return transition(pos, params);
-	};
-	return Object.append(easeIn, {
-		easeIn: easeIn,
-		easeOut: function(pos){
-			return 1 - transition(1 - pos, params);
-		},
-		easeInOut: function(pos){
-			return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;
-		}
-	});
+  params = Array.from(params);
+  var easeIn = function(pos){
+    return transition(pos, params);
+  };
+  return Object.append(easeIn, {
+    easeIn: easeIn,
+    easeOut: function(pos){
+      return 1 - transition(1 - pos, params);
+    },
+    easeInOut: function(pos){
+      return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;
+    }
+  });
 };
 
 Fx.Transitions = {
 
-	linear: function(zero){
-		return zero;
-	}
+  linear: function(zero){
+    return zero;
+  }
 
 };
 
 
 
 Fx.Transitions.extend = function(transitions){
-	for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
+  for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]);
 };
 
 Fx.Transitions.extend({
 
-	Pow: function(p, x){
-		return Math.pow(p, x && x[0] || 6);
-	},
-
-	Expo: function(p){
-		return Math.pow(2, 8 * (p - 1));
-	},
-
-	Circ: function(p){
-		return 1 - Math.sin(Math.acos(p));
-	},
-
-	Sine: function(p){
-		return 1 - Math.cos(p * Math.PI / 2);
-	},
-
-	Back: function(p, x){
-		x = x && x[0] || 1.618;
-		return Math.pow(p, 2) * ((x + 1) * p - x);
-	},
-
-	Bounce: function(p){
-		var value;
-		for (var a = 0, b = 1; 1; a += b, b /= 2){
-			if (p >= (7 - 4 * a) / 11){
-				value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
-				break;
-			}
-		}
-		return value;
-	},
-
-	Elastic: function(p, x){
-		return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
-	}
+  Pow: function(p, x){
+    return Math.pow(p, x && x[0] || 6);
+  },
+
+  Expo: function(p){
+    return Math.pow(2, 8 * (p - 1));
+  },
+
+  Circ: function(p){
+    return 1 - Math.sin(Math.acos(p));
+  },
+
+  Sine: function(p){
+    return 1 - Math.cos(p * Math.PI / 2);
+  },
+
+  Back: function(p, x){
+    x = x && x[0] || 1.618;
+    return Math.pow(p, 2) * ((x + 1) * p - x);
+  },
+
+  Bounce: function(p){
+    var value;
+    for (var a = 0, b = 1; 1; a += b, b /= 2){
+      if (p >= (7 - 4 * a) / 11){
+        value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
+        break;
+      }
+    }
+    return value;
+  },
+
+  Elastic: function(p, x){
+    return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
+  }
 
 });
 
 ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
-	Fx.Transitions[transition] = new Fx.Transition(function(p){
-		return Math.pow(p, i + 2);
-	});
+  Fx.Transitions[transition] = new Fx.Transition(function(p){
+    return Math.pow(p, i + 2);
+  });
 });
 
 
@@ -5314,261 +5314,261 @@ provides: Request
 (function(){
 
 var empty = function(){},
-	progressSupport = ('onprogress' in new Browser.Request);
+  progressSupport = ('onprogress' in new Browser.Request);
 
 var Request = this.Request = new Class({
 
-	Implements: [Chain, Events, Options],
-
-	options: {/*
-		onRequest: function(){},
-		onLoadstart: function(event, xhr){},
-		onProgress: function(event, xhr){},
-		onComplete: function(){},
-		onCancel: function(){},
-		onSuccess: function(responseText, responseXML){},
-		onFailure: function(xhr){},
-		onException: function(headerName, value){},
-		onTimeout: function(){},
-		user: '',
-		password: '',*/
-		url: '',
-		data: '',
-		headers: {
-			'X-Requested-With': 'XMLHttpRequest',
-			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
-		},
-		async: true,
-		format: false,
-		method: 'post',
-		link: 'ignore',
-		isSuccess: null,
-		emulation: true,
-		urlEncoded: true,
-		encoding: 'utf-8',
-		evalScripts: false,
-		evalResponse: false,
-		timeout: 0,
-		noCache: false
-	},
-
-	initialize: function(options){
-		this.xhr = new Browser.Request();
-		this.setOptions(options);
-		this.headers = this.options.headers;
-	},
-
-	onStateChange: function(){
-		var xhr = this.xhr;
-		if (xhr.readyState != 4 || !this.running) return;
-		this.running = false;
-		this.status = 0;
-		Function.attempt(function(){
-			var status = xhr.status;
-			this.status = (status == 1223) ? 204 : status;
-		}.bind(this));
-		xhr.onreadystatechange = empty;
-		if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
-		clearTimeout(this.timer);
-
-		this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
-		if (this.options.isSuccess.call(this, this.status))
-			this.success(this.response.text, this.response.xml);
-		else
-			this.failure();
-	},
-
-	isSuccess: function(){
-		var status = this.status;
-		return (status >= 200 && status < 300);
-	},
-
-	isRunning: function(){
-		return !!this.running;
-	},
-
-	processScripts: function(text){
-		if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
-		return text.stripScripts(this.options.evalScripts);
-	},
-
-	success: function(text, xml){
-		this.onSuccess(this.processScripts(text), xml);
-	},
-
-	onSuccess: function(){
-		this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
-	},
-
-	failure: function(){
-		this.onFailure();
-	},
-
-	onFailure: function(){
-		this.fireEvent('complete').fireEvent('failure', this.xhr);
-	},
-
-	loadstart: function(event){
-		this.fireEvent('loadstart', [event, this.xhr]);
-	},
-
-	progress: function(event){
-		this.fireEvent('progress', [event, this.xhr]);
-	},
-
-	timeout: function(){
-		this.fireEvent('timeout', this.xhr);
-	},
-
-	setHeader: function(name, value){
-		this.headers[name] = value;
-		return this;
-	},
-
-	getHeader: function(name){
-		return Function.attempt(function(){
-			return this.xhr.getResponseHeader(name);
-		}.bind(this));
-	},
-
-	check: function(){
-		if (!this.running) return true;
-		switch (this.options.link){
-			case 'cancel': this.cancel(); return true;
-			case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
-		}
-		return false;
-	},
-
-	send: function(options){
-		if (!this.check(options)) return this;
-
-		this.options.isSuccess = this.options.isSuccess || this.isSuccess;
-		this.running = true;
-
-		var type = typeOf(options);
-		if (type == 'string' || type == 'element') options = {data: options};
-
-		var old = this.options;
-		options = Object.append({data: old.data, url: old.url, method: old.method}, options);
-		var data = options.data, url = String(options.url), method = options.method.toLowerCase();
-
-		switch (typeOf(data)){
-			case 'element': data = document.id(data).toQueryString(); break;
-			case 'object': case 'hash': data = Object.toQueryString(data);
-		}
-
-		if (this.options.format){
-			var format = 'format=' + this.options.format;
-			data = (data) ? format + '&' + data : format;
-		}
-
-		if (this.options.emulation && !['get', 'post'].contains(method)){
-			var _method = '_method=' + method;
-			data = (data) ? _method + '&' + data : _method;
-			method = 'post';
-		}
-
-		if (this.options.urlEncoded && ['post', 'put'].contains(method)){
-			var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
-			this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
-		}
-
-		if (!url) url = document.location.pathname;
-
-		var trimPosition = url.lastIndexOf('/');
-		if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
-
-		if (this.options.noCache)
-			url += (url.indexOf('?') > -1 ? '&' : '?') + String.uniqueID();
-
-		if (data && (method == 'get' || method == 'delete')){
-			url += (url.indexOf('?') > -1 ? '&' : '?') + data;
-			data = null;
-		}
-
-		var xhr = this.xhr;
-		if (progressSupport){
-			xhr.onloadstart = this.loadstart.bind(this);
-			xhr.onprogress = this.progress.bind(this);
-		}
-
-		xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
-		if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
-
-		xhr.onreadystatechange = this.onStateChange.bind(this);
-
-		Object.each(this.headers, function(value, key){
-			try {
-				xhr.setRequestHeader(key, value);
-			} catch (e){
-				this.fireEvent('exception', [key, value]);
-			}
-		}, this);
-
-		this.fireEvent('request');
-		xhr.send(data);
-		if (!this.options.async) this.onStateChange();
-		else if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
-		return this;
-	},
-
-	cancel: function(){
-		if (!this.running) return this;
-		this.running = false;
-		var xhr = this.xhr;
-		xhr.abort();
-		clearTimeout(this.timer);
-		xhr.onreadystatechange = empty;
-		if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
-		this.xhr = new Browser.Request();
-		this.fireEvent('cancel');
-		return this;
-	}
+  Implements: [Chain, Events, Options],
+
+  options: {/*
+    onRequest: function(){},
+    onLoadstart: function(event, xhr){},
+    onProgress: function(event, xhr){},
+    onComplete: function(){},
+    onCancel: function(){},
+    onSuccess: function(responseText, responseXML){},
+    onFailure: function(xhr){},
+    onException: function(headerName, value){},
+    onTimeout: function(){},
+    user: '',
+    password: '',*/
+    url: '',
+    data: '',
+    headers: {
+      'X-Requested-With': 'XMLHttpRequest',
+      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
+    },
+    async: true,
+    format: false,
+    method: 'post',
+    link: 'ignore',
+    isSuccess: null,
+    emulation: true,
+    urlEncoded: true,
+    encoding: 'utf-8',
+    evalScripts: false,
+    evalResponse: false,
+    timeout: 0,
+    noCache: false
+  },
+
+  initialize: function(options){
+    this.xhr = new Browser.Request();
+    this.setOptions(options);
+    this.headers = this.options.headers;
+  },
+
+  onStateChange: function(){
+    var xhr = this.xhr;
+    if (xhr.readyState != 4 || !this.running) return;
+    this.running = false;
+    this.status = 0;
+    Function.attempt(function(){
+      var status = xhr.status;
+      this.status = (status == 1223) ? 204 : status;
+    }.bind(this));
+    xhr.onreadystatechange = empty;
+    if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
+    clearTimeout(this.timer);
+
+    this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML};
+    if (this.options.isSuccess.call(this, this.status))
+      this.success(this.response.text, this.response.xml);
+    else
+      this.failure();
+  },
+
+  isSuccess: function(){
+    var status = this.status;
+    return (status >= 200 && status < 300);
+  },
+
+  isRunning: function(){
+    return !!this.running;
+  },
+
+  processScripts: function(text){
+    if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text);
+    return text.stripScripts(this.options.evalScripts);
+  },
+
+  success: function(text, xml){
+    this.onSuccess(this.processScripts(text), xml);
+  },
+
+  onSuccess: function(){
+    this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain();
+  },
+
+  failure: function(){
+    this.onFailure();
+  },
+
+  onFailure: function(){
+    this.fireEvent('complete').fireEvent('failure', this.xhr);
+  },
+
+  loadstart: function(event){
+    this.fireEvent('loadstart', [event, this.xhr]);
+  },
+
+  progress: function(event){
+    this.fireEvent('progress', [event, this.xhr]);
+  },
+
+  timeout: function(){
+    this.fireEvent('timeout', this.xhr);
+  },
+
+  setHeader: function(name, value){
+    this.headers[name] = value;
+    return this;
+  },
+
+  getHeader: function(name){
+    return Function.attempt(function(){
+      return this.xhr.getResponseHeader(name);
+    }.bind(this));
+  },
+
+  check: function(){
+    if (!this.running) return true;
+    switch (this.options.link){
+      case 'cancel': this.cancel(); return true;
+      case 'chain': this.chain(this.caller.pass(arguments, this)); return false;
+    }
+    return false;
+  },
+
+  send: function(options){
+    if (!this.check(options)) return this;
+
+    this.options.isSuccess = this.options.isSuccess || this.isSuccess;
+    this.running = true;
+
+    var type = typeOf(options);
+    if (type == 'string' || type == 'element') options = {data: options};
+
+    var old = this.options;
+    options = Object.append({data: old.data, url: old.url, method: old.method}, options);
+    var data = options.data, url = String(options.url), method = options.method.toLowerCase();
+
+    switch (typeOf(data)){
+      case 'element': data = document.id(data).toQueryString(); break;
+      case 'object': case 'hash': data = Object.toQueryString(data);
+    }
+
+    if (this.options.format){
+      var format = 'format=' + this.options.format;
+      data = (data) ? format + '&' + data : format;
+    }
+
+    if (this.options.emulation && !['get', 'post'].contains(method)){
+      var _method = '_method=' + method;
+      data = (data) ? _method + '&' + data : _method;
+      method = 'post';
+    }
+
+    if (this.options.urlEncoded && ['post', 'put'].contains(method)){
+      var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
+      this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
+    }
+
+    if (!url) url = document.location.pathname;
+
+    var trimPosition = url.lastIndexOf('/');
+    if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
+
+    if (this.options.noCache)
+      url += (url.indexOf('?') > -1 ? '&' : '?') + String.uniqueID();
+
+    if (data && (method == 'get' || method == 'delete')){
+      url += (url.indexOf('?') > -1 ? '&' : '?') + data;
+      data = null;
+    }
+
+    var xhr = this.xhr;
+    if (progressSupport){
+      xhr.onloadstart = this.loadstart.bind(this);
+      xhr.onprogress = this.progress.bind(this);
+    }
+
+    xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
+    if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
+
+    xhr.onreadystatechange = this.onStateChange.bind(this);
+
+    Object.each(this.headers, function(value, key){
+      try {
+        xhr.setRequestHeader(key, value);
+      } catch (e){
+        this.fireEvent('exception', [key, value]);
+      }
+    }, this);
+
+    this.fireEvent('request');
+    xhr.send(data);
+    if (!this.options.async) this.onStateChange();
+    else if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
+    return this;
+  },
+
+  cancel: function(){
+    if (!this.running) return this;
+    this.running = false;
+    var xhr = this.xhr;
+    xhr.abort();
+    clearTimeout(this.timer);
+    xhr.onreadystatechange = empty;
+    if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
+    this.xhr = new Browser.Request();
+    this.fireEvent('cancel');
+    return this;
+  }
 
 });
 
 var methods = {};
 ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){
-	methods[method] = function(data){
-		var object = {
-			method: method
-		};
-		if (data != null) object.data = data;
-		return this.send(object);
-	};
+  methods[method] = function(data){
+    var object = {
+      method: method
+    };
+    if (data != null) object.data = data;
+    return this.send(object);
+  };
 });
 
 Request.implement(methods);
 
 Element.Properties.send = {
 
-	set: function(options){
-		var send = this.get('send').cancel();
-		send.setOptions(options);
-		return this;
-	},
-
-	get: function(){
-		var send = this.retrieve('send');
-		if (!send){
-			send = new Request({
-				data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
-			});
-			this.store('send', send);
-		}
-		return send;
-	}
+  set: function(options){
+    var send = this.get('send').cancel();
+    send.setOptions(options);
+    return this;
+  },
+
+  get: function(){
+    var send = this.retrieve('send');
+    if (!send){
+      send = new Request({
+        data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action')
+      });
+      this.store('send', send);
+    }
+    return send;
+  }
 
 };
 
 Element.implement({
 
-	send: function(url){
-		var sender = this.get('send');
-		sender.send({data: this, url: url || sender.options.url});
-		return this;
-	}
+  send: function(url){
+    var sender = this.get('send');
+    sender.send({data: this, url: url || sender.options.url});
+    return this;
+  }
 
 });
 
@@ -5593,74 +5593,74 @@ provides: Request.HTML
 
 Request.HTML = new Class({
 
-	Extends: Request,
-
-	options: {
-		update: false,
-		append: false,
-		evalScripts: true,
-		filter: false,
-		headers: {
-			Accept: 'text/html, application/xml, text/xml, */*'
-		}
-	},
-
-	success: function(text){
-		var options = this.options, response = this.response;
-
-		response.html = text.stripScripts(function(script){
-			response.javascript = script;
-		});
-
-		var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
-		if (match) response.html = match[1];
-		var temp = new Element('div').set('html', response.html);
-
-		response.tree = temp.childNodes;
-		response.elements = temp.getElements(options.filter || '*');
-
-		if (options.filter) response.tree = response.elements;
-		if (options.update){
-			var update = document.id(options.update).empty();
-			if (options.filter) update.adopt(response.elements);
-			else update.set('html', response.html);
-		} else if (options.append){
-			var append = document.id(options.append);
-			if (options.filter) response.elements.reverse().inject(append);
-			else append.adopt(temp.getChildren());
-		}
-		if (options.evalScripts) Browser.exec(response.javascript);
-
-		this.onSuccess(response.tree, response.elements, response.html, response.javascript);
-	}
+  Extends: Request,
+
+  options: {
+    update: false,
+    append: false,
+    evalScripts: true,
+    filter: false,
+    headers: {
+      Accept: 'text/html, application/xml, text/xml, */*'
+    }
+  },
+
+  success: function(text){
+    var options = this.options, response = this.response;
+
+    response.html = text.stripScripts(function(script){
+      response.javascript = script;
+    });
+
+    var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
+    if (match) response.html = match[1];
+    var temp = new Element('div').set('html', response.html);
+
+    response.tree = temp.childNodes;
+    response.elements = temp.getElements(options.filter || '*');
+
+    if (options.filter) response.tree = response.elements;
+    if (options.update){
+      var update = document.id(options.update).empty();
+      if (options.filter) update.adopt(response.elements);
+      else update.set('html', response.html);
+    } else if (options.append){
+      var append = document.id(options.append);
+      if (options.filter) response.elements.reverse().inject(append);
+      else append.adopt(temp.getChildren());
+    }
+    if (options.evalScripts) Browser.exec(response.javascript);
+
+    this.onSuccess(response.tree, response.elements, response.html, response.javascript);
+  }
 
 });
 
 Element.Properties.load = {
 
-	set: function(options){
-		var load = this.get('load').cancel();
-		load.setOptions(options);
-		return this;
-	},
-
-	get: function(){
-		var load = this.retrieve('load');
-		if (!load){
-			load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});
-			this.store('load', load);
-		}
-		return load;
-	}
+  set: function(options){
+    var load = this.get('load').cancel();
+    load.setOptions(options);
+    return this;
+  },
+
+  get: function(){
+    var load = this.retrieve('load');
+    if (!load){
+      load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'});
+      this.store('load', load);
+    }
+    return load;
+  }
 
 };
 
 Element.implement({
 
-	load: function(){
-		this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));
-		return this;
-	}
+  load: function(){
+    this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString}));
+    return this;
+  }
 
 });
 
@@ -5692,54 +5692,54 @@ if (typeof JSON == 'undefined') this.JSON = {};
 var special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
 
 var escape = function(chr){
-	return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
+  return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4);
 };
 
 JSON.validate = function(string){
-	string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
-					replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
-					replace(/(?:^|:|,)(?:\s*\[)+/g, '');
+  string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+          replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+          replace(/(?:^|:|,)(?:\s*\[)+/g, '');
 
-	return (/^[\],:{}\s]*$/).test(string);
+  return (/^[\],:{}\s]*$/).test(string);
 };
 
 JSON.encode = JSON.stringify ? function(obj){
-	return JSON.stringify(obj);
+  return JSON.stringify(obj);
 } : function(obj){
-	if (obj && obj.toJSON) obj = obj.toJSON();
-
-	switch (typeOf(obj)){
-		case 'string':
-			return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
-		case 'array':
-			return '[' + obj.map(JSON.encode).clean() + ']';
-		case 'object': case 'hash':
-			var string = [];
-			Object.each(obj, function(value, key){
-				var json = JSON.encode(value);
-				if (json) string.push(JSON.encode(key) + ':' + json);
-			});
-			return '{' + string + '}';
-		case 'number': case 'boolean': return '' + obj;
-		case 'null': return 'null';
-	}
-
-	return null;
+  if (obj && obj.toJSON) obj = obj.toJSON();
+
+  switch (typeOf(obj)){
+    case 'string':
+      return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"';
+    case 'array':
+      return '[' + obj.map(JSON.encode).clean() + ']';
+    case 'object': case 'hash':
+      var string = [];
+      Object.each(obj, function(value, key){
+        var json = JSON.encode(value);
+        if (json) string.push(JSON.encode(key) + ':' + json);
+      });
+      return '{' + string + '}';
+    case 'number': case 'boolean': return '' + obj;
+    case 'null': return 'null';
+  }
+
+  return null;
 };
 
 JSON.secure = true;
 
 
 JSON.decode = function(string, secure){
-	if (!string || typeOf(string) != 'string') return null;
+  if (!string || typeOf(string) != 'string') return null;
 
-	if (secure == null) secure = JSON.secure;
-	if (secure){
-		if (JSON.parse) return JSON.parse(string);
-		if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');
-	}
+  if (secure == null) secure = JSON.secure;
+  if (secure){
+    if (JSON.parse) return JSON.parse(string);
+    if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.');
+  }
 
-	return eval('(' + string + ')');
+  return eval('(' + string + ')');
 };
 
 })();
@@ -5763,32 +5763,32 @@ provides: Request.JSON
 
 Request.JSON = new Class({
 
-	Extends: Request,
-
-	options: {
-		/*onError: function(text, error){},*/
-		secure: true
-	},
-
-	initialize: function(options){
-		this.parent(options);
-		Object.append(this.headers, {
-			'Accept': 'application/json',
-			'X-Request': 'JSON'
-		});
-	},
-
-	success: function(text){
-		var json;
-		try {
-			json = this.response.json = JSON.decode(text, this.options.secure);
-		} catch (error){
-			this.fireEvent('error', [text, error]);
-			return;
-		}
-		if (json == null) this.onFailure();
-		else this.onSuccess(json, text);
-	}
+  Extends: Request,
+
+  options: {
+    /*onError: function(text, error){},*/
+    secure: true
+  },
+
+  initialize: function(options){
+    this.parent(options);
+    Object.append(this.headers, {
+      'Accept': 'application/json',
+      'X-Request': 'JSON'
+    });
+  },
+
+  success: function(text){
+    var json;
+    try {
+      json = this.response.json = JSON.decode(text, this.options.secure);
+    } catch (error){
+      this.fireEvent('error', [text, error]);
+      return;
+    }
+    if (json == null) this.onFailure();
+    else this.onSuccess(json, text);
+  }
 
 });
 
@@ -5814,58 +5814,58 @@ provides: Cookie
 
 var Cookie = new Class({
 
-	Implements: Options,
-
-	options: {
-		path: '/',
-		domain: false,
-		duration: false,
-		secure: false,
-		document: document,
-		encode: true
-	},
-
-	initialize: function(key, options){
-		this.key = key;
-		this.setOptions(options);
-	},
-
-	write: function(value){
-		if (this.options.encode) value = encodeURIComponent(value);
-		if (this.options.domain) value += '; domain=' + this.options.domain;
-		if (this.options.path) value += '; path=' + this.options.path;
-		if (this.options.duration){
-			var date = new Date();
-			date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
-			value += '; expires=' + date.toGMTString();
-		}
-		if (this.options.secure) value += '; secure';
-		this.options.document.cookie = this.key + '=' + value;
-		return this;
-	},
-
-	read: function(){
-		var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
-		return (value) ? decodeURIComponent(value[1]) : null;
-	},
-
-	dispose: function(){
-		new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');
-		return this;
-	}
+  Implements: Options,
+
+  options: {
+    path: '/',
+    domain: false,
+    duration: false,
+    secure: false,
+    document: document,
+    encode: true
+  },
+
+  initialize: function(key, options){
+    this.key = key;
+    this.setOptions(options);
+  },
+
+  write: function(value){
+    if (this.options.encode) value = encodeURIComponent(value);
+    if (this.options.domain) value += '; domain=' + this.options.domain;
+    if (this.options.path) value += '; path=' + this.options.path;
+    if (this.options.duration){
+      var date = new Date();
+      date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
+      value += '; expires=' + date.toGMTString();
+    }
+    if (this.options.secure) value += '; secure';
+    this.options.document.cookie = this.key + '=' + value;
+    return this;
+  },
+
+  read: function(){
+    var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)');
+    return (value) ? decodeURIComponent(value[1]) : null;
+  },
+
+  dispose: function(){
+    new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write('');
+    return this;
+  }
 
 });
 
 Cookie.write = function(key, value, options){
-	return new Cookie(key, options).write(value);
+  return new Cookie(key, options).write(value);
 };
 
 Cookie.read = function(key){
-	return new Cookie(key).read();
+  return new Cookie(key).read();
 };
 
 Cookie.dispose = function(key, options){
-	return new Cookie(key, options).dispose();
+  return new Cookie(key, options).dispose();
 };
 
 
@@ -5888,33 +5888,33 @@ provides: [DOMReady, DomReady]
 (function(window, document){
 
 var ready,
-	loaded,
-	checks = [],
-	shouldPoll,
-	timer,
-	testElement = document.createElement('div');
+  loaded,
+  checks = [],
+  shouldPoll,
+  timer,
+  testElement = document.createElement('div');
 
 var domready = function(){
-	clearTimeout(timer);
-	if (ready) return;
-	Browser.loaded = ready = true;
-	document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);
+  clearTimeout(timer);
+  if (ready) return;
+  Browser.loaded = ready = true;
+  document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check);
 
-	document.fireEvent('domready');
-	window.fireEvent('domready');
+  document.fireEvent('domready');
+  window.fireEvent('domready');
 };
 
 var check = function(){
-	for (var i = checks.length; i--;) if (checks[i]()){
-		domready();
-		return true;
-	}
-	return false;
+  for (var i = checks.length; i--;) if (checks[i]()){
+    domready();
+    return true;
+  }
+  return false;
 };
 
 var poll = function(){
-	clearTimeout(timer);
-	if (!check()) timer = setTimeout(poll, 10);
+  clearTimeout(timer);
+  if (!check()) timer = setTimeout(poll, 10);
 };
 
 document.addListener('DOMContentLoaded', domready);
@@ -5923,23 +5923,23 @@ document.addListener('DOMContentLoaded', domready);
 // doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/
 // testElement.doScroll() throws when the DOM is not ready, only in the top window
 var doScrollWorks = function(){
-	try {
-		testElement.doScroll();
-		return true;
-	} catch (e){}
-	return false;
+  try {
+    testElement.doScroll();
+    return true;
+  } catch (e){}
+  return false;
 };
 // If doScroll works already, it can't be used to determine domready
 //   e.g. in an iframe
 if (testElement.doScroll && !doScrollWorks()){
-	checks.push(doScrollWorks);
-	shouldPoll = true;
+  checks.push(doScrollWorks);
+  shouldPoll = true;
 }
 /*</ltIE8>*/
 
 if (document.readyState) checks.push(function(){
-	var state = document.readyState;
-	return (state == 'loaded' || state == 'complete');
+  var state = document.readyState;
+  return (state == 'loaded' || state == 'complete');
 });
 
 if ('onreadystatechange' in document) document.addListener('readystatechange', check);
@@ -5948,29 +5948,29 @@ else shouldPoll = true;
 if (shouldPoll) poll();
 
 Element.Events.domready = {
-	onAdd: function(fn){
-		if (ready) fn.call(this);
-	}
+  onAdd: function(fn){
+    if (ready) fn.call(this);
+  }
 };
 
 // Make sure that domready fires before load
 Element.Events.load = {
-	base: 'load',
-	onAdd: function(fn){
-		if (loaded && this == window) fn.call(this);
-	},
-	condition: function(){
-		if (this == window){
-			domready();
-			delete Element.Events.load;
-		}
-		return true;
-	}
+  base: 'load',
+  onAdd: function(fn){
+    if (loaded && this == window) fn.call(this);
+  },
+  condition: function(){
+    if (this == window){
+      domready();
+      delete Element.Events.load;
+    }
+    return true;
+  }
 };
 
 // This is based on the custom load event
 window.addEvent('load', function(){
-	loaded = true;
+  loaded = true;
 });
 
 })(window, document);
diff --git a/pyload/webui/themes/estate/js/static/mootools-more.js b/pyload/webui/themes/estate/js/static/mootools-more.js
index 160b7234e..3b63949a7 100644
--- a/pyload/webui/themes/estate/js/static/mootools-more.js
+++ b/pyload/webui/themes/estate/js/static/mootools-more.js
@@ -41,8 +41,8 @@ provides: [MooTools.More]
 */
 
 MooTools.More = {
-	version: '1.5.0',
-	build: '73db5e24e6e9c5c87b3a27aebef2248053f7db37'
+  version: '1.5.0',
+  build: '73db5e24e6e9c5c87b3a27aebef2248053f7db37'
 };
 
 
@@ -70,18 +70,18 @@ provides: [Class.Binds]
 */
 
 Class.Mutators.Binds = function(binds){
-	if (!this.prototype.initialize) this.implement('initialize', function(){});
-	return Array.from(binds).concat(this.prototype.Binds || []);
+  if (!this.prototype.initialize) this.implement('initialize', function(){});
+  return Array.from(binds).concat(this.prototype.Binds || []);
 };
 
 Class.Mutators.initialize = function(initialize){
-	return function(){
-		Array.from(this.Binds).each(function(name){
-			var original = this[name];
-			if (original) this[name] = original.bind(this);
-		}, this);
-		return initialize.apply(this, arguments);
-	};
+  return function(){
+    Array.from(this.Binds).each(function(name){
+      var original = this[name];
+      if (original) this[name] = original.bind(this);
+    }, this);
+    return initialize.apply(this, arguments);
+  };
 };
 
 
@@ -111,16 +111,16 @@ provides: [Class.Occlude]
 
 Class.Occlude = new Class({
 
-	occlude: function(property, element){
-		element = document.id(element || this.element);
-		var instance = element.retrieve(property || this.property);
-		if (instance && !this.occluded)
-			return (this.occluded = instance);
+  occlude: function(property, element){
+    element = document.id(element || this.element);
+    var instance = element.retrieve(property || this.property);
+    if (instance && !this.occluded)
+      return (this.occluded = instance);
 
-		this.occluded = false;
-		element.store(property || this.property, this);
-		return this.occluded;
-	}
+    this.occluded = false;
+    element.store(property || this.property, this);
+    return this.occluded;
+  }
 
 });
 
@@ -151,19 +151,19 @@ provides: [Class.refactor, Class.Refactor]
 
 Class.refactor = function(original, refactors){
 
-	Object.each(refactors, function(item, name){
-		var origin = original.prototype[name];
-		origin = (origin && origin.$origin) || origin || function(){};
-		original.implement(name, (typeof item == 'function') ? function(){
-			var old = this.previous;
-			this.previous = origin;
-			var value = item.apply(this, arguments);
-			this.previous = old;
-			return value;
-		} : item);
-	});
+  Object.each(refactors, function(item, name){
+    var origin = original.prototype[name];
+    origin = (origin && origin.$origin) || origin || function(){};
+    original.implement(name, (typeof item == 'function') ? function(){
+      var old = this.previous;
+      this.previous = origin;
+      var value = item.apply(this, arguments);
+      this.previous = old;
+      return value;
+    } : item);
+  });
 
-	return original;
+  return original;
 
 };
 
@@ -197,140 +197,140 @@ provides: [Element.Measure]
 (function(){
 
 var getStylesList = function(styles, planes){
-	var list = [];
-	Object.each(planes, function(directions){
-		Object.each(directions, function(edge){
-			styles.each(function(style){
-				list.push(style + '-' + edge + (style == 'border' ? '-width' : ''));
-			});
-		});
-	});
-	return list;
+  var list = [];
+  Object.each(planes, function(directions){
+    Object.each(directions, function(edge){
+      styles.each(function(style){
+        list.push(style + '-' + edge + (style == 'border' ? '-width' : ''));
+      });
+    });
+  });
+  return list;
 };
 
 var calculateEdgeSize = function(edge, styles){
-	var total = 0;
-	Object.each(styles, function(value, style){
-		if (style.test(edge)) total = total + value.toInt();
-	});
-	return total;
+  var total = 0;
+  Object.each(styles, function(value, style){
+    if (style.test(edge)) total = total + value.toInt();
+  });
+  return total;
 };
 
 var isVisible = function(el){
-	return !!(!el || el.offsetHeight || el.offsetWidth);
+  return !!(!el || el.offsetHeight || el.offsetWidth);
 };
 
 
 Element.implement({
 
-	measure: function(fn){
-		if (isVisible(this)) return fn.call(this);
-		var parent = this.getParent(),
-			toMeasure = [];
-		while (!isVisible(parent) && parent != document.body){
-			toMeasure.push(parent.expose());
-			parent = parent.getParent();
-		}
-		var restore = this.expose(),
-			result = fn.call(this);
-		restore();
-		toMeasure.each(function(restore){
-			restore();
-		});
-		return result;
-	},
-
-	expose: function(){
-		if (this.getStyle('display') != 'none') return function(){};
-		var before = this.style.cssText;
-		this.setStyles({
-			display: 'block',
-			position: 'absolute',
-			visibility: 'hidden'
-		});
-		return function(){
-			this.style.cssText = before;
-		}.bind(this);
-	},
-
-	getDimensions: function(options){
-		options = Object.merge({computeSize: false}, options);
-		var dim = {x: 0, y: 0};
-
-		var getSize = function(el, options){
-			return (options.computeSize) ? el.getComputedSize(options) : el.getSize();
-		};
-
-		var parent = this.getParent('body');
-
-		if (parent && this.getStyle('display') == 'none'){
-			dim = this.measure(function(){
-				return getSize(this, options);
-			});
-		} else if (parent){
-			try { //safari sometimes crashes here, so catch it
-				dim = getSize(this, options);
-			}catch(e){}
-		}
-
-		return Object.append(dim, (dim.x || dim.x === 0) ? {
-				width: dim.x,
-				height: dim.y
-			} : {
-				x: dim.width,
-				y: dim.height
-			}
-		);
-	},
-
-	getComputedSize: function(options){
-		
-
-		options = Object.merge({
-			styles: ['padding','border'],
-			planes: {
-				height: ['top','bottom'],
-				width: ['left','right']
-			},
-			mode: 'both'
-		}, options);
-
-		var styles = {},
-			size = {width: 0, height: 0},
-			dimensions;
-
-		if (options.mode == 'vertical'){
-			delete size.width;
-			delete options.planes.width;
-		} else if (options.mode == 'horizontal'){
-			delete size.height;
-			delete options.planes.height;
-		}
-
-		getStylesList(options.styles, options.planes).each(function(style){
-			styles[style] = this.getStyle(style).toInt();
-		}, this);
-
-		Object.each(options.planes, function(edges, plane){
-
-			var capitalized = plane.capitalize(),
-				style = this.getStyle(plane);
-
-			if (style == 'auto' && !dimensions) dimensions = this.getDimensions();
-
-			style = styles[plane] = (style == 'auto') ? dimensions[plane] : style.toInt();
-			size['total' + capitalized] = style;
-
-			edges.each(function(edge){
-				var edgesize = calculateEdgeSize(edge, styles);
-				size['computed' + edge.capitalize()] = edgesize;
-				size['total' + capitalized] += edgesize;
-			});
-
-		}, this);
-
-		return Object.append(size, styles);
-	}
+  measure: function(fn){
+    if (isVisible(this)) return fn.call(this);
+    var parent = this.getParent(),
+      toMeasure = [];
+    while (!isVisible(parent) && parent != document.body){
+      toMeasure.push(parent.expose());
+      parent = parent.getParent();
+    }
+    var restore = this.expose(),
+      result = fn.call(this);
+    restore();
+    toMeasure.each(function(restore){
+      restore();
+    });
+    return result;
+  },
+
+  expose: function(){
+    if (this.getStyle('display') != 'none') return function(){};
+    var before = this.style.cssText;
+    this.setStyles({
+      display: 'block',
+      position: 'absolute',
+      visibility: 'hidden'
+    });
+    return function(){
+      this.style.cssText = before;
+    }.bind(this);
+  },
+
+  getDimensions: function(options){
+    options = Object.merge({computeSize: false}, options);
+    var dim = {x: 0, y: 0};
+
+    var getSize = function(el, options){
+      return (options.computeSize) ? el.getComputedSize(options) : el.getSize();
+    };
+
+    var parent = this.getParent('body');
+
+    if (parent && this.getStyle('display') == 'none'){
+      dim = this.measure(function(){
+        return getSize(this, options);
+      });
+    } else if (parent){
+      try { //safari sometimes crashes here, so catch it
+        dim = getSize(this, options);
+      }catch(e){}
+    }
+
+    return Object.append(dim, (dim.x || dim.x === 0) ? {
+        width: dim.x,
+        height: dim.y
+      } : {
+        x: dim.width,
+        y: dim.height
+      }
+    );
+  },
+
+  getComputedSize: function(options){
+    
+
+    options = Object.merge({
+      styles: ['padding','border'],
+      planes: {
+        height: ['top','bottom'],
+        width: ['left','right']
+      },
+      mode: 'both'
+    }, options);
+
+    var styles = {},
+      size = {width: 0, height: 0},
+      dimensions;
+
+    if (options.mode == 'vertical'){
+      delete size.width;
+      delete options.planes.width;
+    } else if (options.mode == 'horizontal'){
+      delete size.height;
+      delete options.planes.height;
+    }
+
+    getStylesList(options.styles, options.planes).each(function(style){
+      styles[style] = this.getStyle(style).toInt();
+    }, this);
+
+    Object.each(options.planes, function(edges, plane){
+
+      var capitalized = plane.capitalize(),
+        style = this.getStyle(plane);
+
+      if (style == 'auto' && !dimensions) dimensions = this.getDimensions();
+
+      style = styles[plane] = (style == 'auto') ? dimensions[plane] : style.toInt();
+      size['total' + capitalized] = style;
+
+      edges.each(function(edge){
+        var edgesize = calculateEdgeSize(edge, styles);
+        size['computed' + edge.capitalize()] = edgesize;
+        size['total' + capitalized] += edgesize;
+      });
+
+    }, this);
+
+    return Object.append(size, styles);
+  }
 
 });
 
@@ -366,210 +366,210 @@ provides: [Element.Position]
 
 var local = Element.Position = {
 
-	options: {/*
-		edge: false,
-		returnPos: false,
-		minimum: {x: 0, y: 0},
-		maximum: {x: 0, y: 0},
-		relFixedPosition: false,
-		ignoreMargins: false,
-		ignoreScroll: false,
-		allowNegative: false,*/
-		relativeTo: document.body,
-		position: {
-			x: 'center', //left, center, right
-			y: 'center' //top, center, bottom
-		},
-		offset: {x: 0, y: 0}
-	},
-
-	getOptions: function(element, options){
-		options = Object.merge({}, local.options, options);
-		local.setPositionOption(options);
-		local.setEdgeOption(options);
-		local.setOffsetOption(element, options);
-		local.setDimensionsOption(element, options);
-		return options;
-	},
-
-	setPositionOption: function(options){
-		options.position = local.getCoordinateFromValue(options.position);
-	},
-
-	setEdgeOption: function(options){
-		var edgeOption = local.getCoordinateFromValue(options.edge);
-		options.edge = edgeOption ? edgeOption :
-			(options.position.x == 'center' && options.position.y == 'center') ? {x: 'center', y: 'center'} :
-			{x: 'left', y: 'top'};
-	},
-
-	setOffsetOption: function(element, options){
-		var parentOffset = {x: 0, y: 0};
-		var parentScroll = {x: 0, y: 0};
-		var offsetParent = element.measure(function(){
-			return document.id(this.getOffsetParent());
-		});
-
-		if (!offsetParent || offsetParent == element.getDocument().body) return;
-
-		parentScroll = offsetParent.getScroll();
-		parentOffset = offsetParent.measure(function(){
-			var position = this.getPosition();
-			if (this.getStyle('position') == 'fixed'){
-				var scroll = window.getScroll();
-				position.x += scroll.x;
-				position.y += scroll.y;
-			}
-			return position;
-		});
-
-		options.offset = {
-			parentPositioned: offsetParent != document.id(options.relativeTo),
-			x: options.offset.x - parentOffset.x + parentScroll.x,
-			y: options.offset.y - parentOffset.y + parentScroll.y
-		};
-	},
-
-	setDimensionsOption: function(element, options){
-		options.dimensions = element.getDimensions({
-			computeSize: true,
-			styles: ['padding', 'border', 'margin']
-		});
-	},
-
-	getPosition: function(element, options){
-		var position = {};
-		options = local.getOptions(element, options);
-		var relativeTo = document.id(options.relativeTo) || document.body;
-
-		local.setPositionCoordinates(options, position, relativeTo);
-		if (options.edge) local.toEdge(position, options);
-
-		var offset = options.offset;
-		position.left = ((position.x >= 0 || offset.parentPositioned || options.allowNegative) ? position.x : 0).toInt();
-		position.top = ((position.y >= 0 || offset.parentPositioned || options.allowNegative) ? position.y : 0).toInt();
-
-		local.toMinMax(position, options);
-
-		if (options.relFixedPosition || relativeTo.getStyle('position') == 'fixed') local.toRelFixedPosition(relativeTo, position);
-		if (options.ignoreScroll) local.toIgnoreScroll(relativeTo, position);
-		if (options.ignoreMargins) local.toIgnoreMargins(position, options);
-
-		position.left = Math.ceil(position.left);
-		position.top = Math.ceil(position.top);
-		delete position.x;
-		delete position.y;
-
-		return position;
-	},
-
-	setPositionCoordinates: function(options, position, relativeTo){
-		var offsetY = options.offset.y,
-			offsetX = options.offset.x,
-			calc = (relativeTo == document.body) ? window.getScroll() : relativeTo.getPosition(),
-			top = calc.y,
-			left = calc.x,
-			winSize = window.getSize();
-
-		switch(options.position.x){
-			case 'left': position.x = left + offsetX; break;
-			case 'right': position.x = left + offsetX + relativeTo.offsetWidth; break;
-			default: position.x = left + ((relativeTo == document.body ? winSize.x : relativeTo.offsetWidth) / 2) + offsetX; break;
-		}
-
-		switch(options.position.y){
-			case 'top': position.y = top + offsetY; break;
-			case 'bottom': position.y = top + offsetY + relativeTo.offsetHeight; break;
-			default: position.y = top + ((relativeTo == document.body ? winSize.y : relativeTo.offsetHeight) / 2) + offsetY; break;
-		}
-	},
-
-	toMinMax: function(position, options){
-		var xy = {left: 'x', top: 'y'}, value;
-		['minimum', 'maximum'].each(function(minmax){
-			['left', 'top'].each(function(lr){
-				value = options[minmax] ? options[minmax][xy[lr]] : null;
-				if (value != null && ((minmax == 'minimum') ? position[lr] < value : position[lr] > value)) position[lr] = value;
-			});
-		});
-	},
-
-	toRelFixedPosition: function(relativeTo, position){
-		var winScroll = window.getScroll();
-		position.top += winScroll.y;
-		position.left += winScroll.x;
-	},
-
-	toIgnoreScroll: function(relativeTo, position){
-		var relScroll = relativeTo.getScroll();
-		position.top -= relScroll.y;
-		position.left -= relScroll.x;
-	},
-
-	toIgnoreMargins: function(position, options){
-		position.left += options.edge.x == 'right'
-			? options.dimensions['margin-right']
-			: (options.edge.x != 'center'
-				? -options.dimensions['margin-left']
-				: -options.dimensions['margin-left'] + ((options.dimensions['margin-right'] + options.dimensions['margin-left']) / 2));
-
-		position.top += options.edge.y == 'bottom'
-			? options.dimensions['margin-bottom']
-			: (options.edge.y != 'center'
-				? -options.dimensions['margin-top']
-				: -options.dimensions['margin-top'] + ((options.dimensions['margin-bottom'] + options.dimensions['margin-top']) / 2));
-	},
-
-	toEdge: function(position, options){
-		var edgeOffset = {},
-			dimensions = options.dimensions,
-			edge = options.edge;
-
-		switch(edge.x){
-			case 'left': edgeOffset.x = 0; break;
-			case 'right': edgeOffset.x = -dimensions.x - dimensions.computedRight - dimensions.computedLeft; break;
-			// center
-			default: edgeOffset.x = -(Math.round(dimensions.totalWidth / 2)); break;
-		}
-
-		switch(edge.y){
-			case 'top': edgeOffset.y = 0; break;
-			case 'bottom': edgeOffset.y = -dimensions.y - dimensions.computedTop - dimensions.computedBottom; break;
-			// center
-			default: edgeOffset.y = -(Math.round(dimensions.totalHeight / 2)); break;
-		}
-
-		position.x += edgeOffset.x;
-		position.y += edgeOffset.y;
-	},
-
-	getCoordinateFromValue: function(option){
-		if (typeOf(option) != 'string') return option;
-		option = option.toLowerCase();
-
-		return {
-			x: option.test('left') ? 'left'
-				: (option.test('right') ? 'right' : 'center'),
-			y: option.test(/upper|top/) ? 'top'
-				: (option.test('bottom') ? 'bottom' : 'center')
-		};
-	}
+  options: {/*
+    edge: false,
+    returnPos: false,
+    minimum: {x: 0, y: 0},
+    maximum: {x: 0, y: 0},
+    relFixedPosition: false,
+    ignoreMargins: false,
+    ignoreScroll: false,
+    allowNegative: false,*/
+    relativeTo: document.body,
+    position: {
+      x: 'center', //left, center, right
+      y: 'center' //top, center, bottom
+    },
+    offset: {x: 0, y: 0}
+  },
+
+  getOptions: function(element, options){
+    options = Object.merge({}, local.options, options);
+    local.setPositionOption(options);
+    local.setEdgeOption(options);
+    local.setOffsetOption(element, options);
+    local.setDimensionsOption(element, options);
+    return options;
+  },
+
+  setPositionOption: function(options){
+    options.position = local.getCoordinateFromValue(options.position);
+  },
+
+  setEdgeOption: function(options){
+    var edgeOption = local.getCoordinateFromValue(options.edge);
+    options.edge = edgeOption ? edgeOption :
+      (options.position.x == 'center' && options.position.y == 'center') ? {x: 'center', y: 'center'} :
+      {x: 'left', y: 'top'};
+  },
+
+  setOffsetOption: function(element, options){
+    var parentOffset = {x: 0, y: 0};
+    var parentScroll = {x: 0, y: 0};
+    var offsetParent = element.measure(function(){
+      return document.id(this.getOffsetParent());
+    });
+
+    if (!offsetParent || offsetParent == element.getDocument().body) return;
+
+    parentScroll = offsetParent.getScroll();
+    parentOffset = offsetParent.measure(function(){
+      var position = this.getPosition();
+      if (this.getStyle('position') == 'fixed'){
+        var scroll = window.getScroll();
+        position.x += scroll.x;
+        position.y += scroll.y;
+      }
+      return position;
+    });
+
+    options.offset = {
+      parentPositioned: offsetParent != document.id(options.relativeTo),
+      x: options.offset.x - parentOffset.x + parentScroll.x,
+      y: options.offset.y - parentOffset.y + parentScroll.y
+    };
+  },
+
+  setDimensionsOption: function(element, options){
+    options.dimensions = element.getDimensions({
+      computeSize: true,
+      styles: ['padding', 'border', 'margin']
+    });
+  },
+
+  getPosition: function(element, options){
+    var position = {};
+    options = local.getOptions(element, options);
+    var relativeTo = document.id(options.relativeTo) || document.body;
+
+    local.setPositionCoordinates(options, position, relativeTo);
+    if (options.edge) local.toEdge(position, options);
+
+    var offset = options.offset;
+    position.left = ((position.x >= 0 || offset.parentPositioned || options.allowNegative) ? position.x : 0).toInt();
+    position.top = ((position.y >= 0 || offset.parentPositioned || options.allowNegative) ? position.y : 0).toInt();
+
+    local.toMinMax(position, options);
+
+    if (options.relFixedPosition || relativeTo.getStyle('position') == 'fixed') local.toRelFixedPosition(relativeTo, position);
+    if (options.ignoreScroll) local.toIgnoreScroll(relativeTo, position);
+    if (options.ignoreMargins) local.toIgnoreMargins(position, options);
+
+    position.left = Math.ceil(position.left);
+    position.top = Math.ceil(position.top);
+    delete position.x;
+    delete position.y;
+
+    return position;
+  },
+
+  setPositionCoordinates: function(options, position, relativeTo){
+    var offsetY = options.offset.y,
+      offsetX = options.offset.x,
+      calc = (relativeTo == document.body) ? window.getScroll() : relativeTo.getPosition(),
+      top = calc.y,
+      left = calc.x,
+      winSize = window.getSize();
+
+    switch(options.position.x){
+      case 'left': position.x = left + offsetX; break;
+      case 'right': position.x = left + offsetX + relativeTo.offsetWidth; break;
+      default: position.x = left + ((relativeTo == document.body ? winSize.x : relativeTo.offsetWidth) / 2) + offsetX; break;
+    }
+
+    switch(options.position.y){
+      case 'top': position.y = top + offsetY; break;
+      case 'bottom': position.y = top + offsetY + relativeTo.offsetHeight; break;
+      default: position.y = top + ((relativeTo == document.body ? winSize.y : relativeTo.offsetHeight) / 2) + offsetY; break;
+    }
+  },
+
+  toMinMax: function(position, options){
+    var xy = {left: 'x', top: 'y'}, value;
+    ['minimum', 'maximum'].each(function(minmax){
+      ['left', 'top'].each(function(lr){
+        value = options[minmax] ? options[minmax][xy[lr]] : null;
+        if (value != null && ((minmax == 'minimum') ? position[lr] < value : position[lr] > value)) position[lr] = value;
+      });
+    });
+  },
+
+  toRelFixedPosition: function(relativeTo, position){
+    var winScroll = window.getScroll();
+    position.top += winScroll.y;
+    position.left += winScroll.x;
+  },
+
+  toIgnoreScroll: function(relativeTo, position){
+    var relScroll = relativeTo.getScroll();
+    position.top -= relScroll.y;
+    position.left -= relScroll.x;
+  },
+
+  toIgnoreMargins: function(position, options){
+    position.left += options.edge.x == 'right'
+      ? options.dimensions['margin-right']
+      : (options.edge.x != 'center'
+        ? -options.dimensions['margin-left']
+        : -options.dimensions['margin-left'] + ((options.dimensions['margin-right'] + options.dimensions['margin-left']) / 2));
+
+    position.top += options.edge.y == 'bottom'
+      ? options.dimensions['margin-bottom']
+      : (options.edge.y != 'center'
+        ? -options.dimensions['margin-top']
+        : -options.dimensions['margin-top'] + ((options.dimensions['margin-bottom'] + options.dimensions['margin-top']) / 2));
+  },
+
+  toEdge: function(position, options){
+    var edgeOffset = {},
+      dimensions = options.dimensions,
+      edge = options.edge;
+
+    switch(edge.x){
+      case 'left': edgeOffset.x = 0; break;
+      case 'right': edgeOffset.x = -dimensions.x - dimensions.computedRight - dimensions.computedLeft; break;
+      // center
+      default: edgeOffset.x = -(Math.round(dimensions.totalWidth / 2)); break;
+    }
+
+    switch(edge.y){
+      case 'top': edgeOffset.y = 0; break;
+      case 'bottom': edgeOffset.y = -dimensions.y - dimensions.computedTop - dimensions.computedBottom; break;
+      // center
+      default: edgeOffset.y = -(Math.round(dimensions.totalHeight / 2)); break;
+    }
+
+    position.x += edgeOffset.x;
+    position.y += edgeOffset.y;
+  },
+
+  getCoordinateFromValue: function(option){
+    if (typeOf(option) != 'string') return option;
+    option = option.toLowerCase();
+
+    return {
+      x: option.test('left') ? 'left'
+        : (option.test('right') ? 'right' : 'center'),
+      y: option.test(/upper|top/) ? 'top'
+        : (option.test('bottom') ? 'bottom' : 'center')
+    };
+  }
 
 };
 
 Element.implement({
 
-	position: function(options){
-		if (options && (options.x != null || options.y != null)){
-			return (original ? original.apply(this, arguments) : this);
-		}
-		var position = this.setStyle('position', 'absolute').calculatePosition(options);
-		return (options && options.returnPos) ? position : this.setStyles(position);
-	},
+  position: function(options){
+    if (options && (options.x != null || options.y != null)){
+      return (original ? original.apply(this, arguments) : this);
+    }
+    var position = this.setStyle('position', 'absolute').calculatePosition(options);
+    return (options && options.returnPos) ? position : this.setStyles(position);
+  },
 
-	calculatePosition: function(options){
-		return local.getPosition(this, options);
-	}
+  calculatePosition: function(options){
+    return local.getPosition(this, options);
+  }
 
 });
 
@@ -610,108 +610,108 @@ var browsers = false;
 
 this.IframeShim = new Class({
 
-	Implements: [Options, Events, Class.Occlude],
-
-	options: {
-		className: 'iframeShim',
-		src: 'javascript:false;document.write("");',
-		display: false,
-		zIndex: null,
-		margin: 0,
-		offset: {x: 0, y: 0},
-		browsers: browsers
-	},
-
-	property: 'IframeShim',
-
-	initialize: function(element, options){
-		this.element = document.id(element);
-		if (this.occlude()) return this.occluded;
-		this.setOptions(options);
-		this.makeShim();
-		return this;
-	},
-
-	makeShim: function(){
-		if (this.options.browsers){
-			var zIndex = this.element.getStyle('zIndex').toInt();
-
-			if (!zIndex){
-				zIndex = 1;
-				var pos = this.element.getStyle('position');
-				if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
-				this.element.setStyle('zIndex', zIndex);
-			}
-			zIndex = ((this.options.zIndex != null || this.options.zIndex === 0) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
-			if (zIndex < 0) zIndex = 1;
-			this.shim = new Element('iframe', {
-				src: this.options.src,
-				scrolling: 'no',
-				frameborder: 0,
-				styles: {
-					zIndex: zIndex,
-					position: 'absolute',
-					border: 'none',
-					filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
-				},
-				'class': this.options.className
-			}).store('IframeShim', this);
-			var inject = (function(){
-				this.shim.inject(this.element, 'after');
-				this[this.options.display ? 'show' : 'hide']();
-				this.fireEvent('inject');
-			}).bind(this);
-			if (!IframeShim.ready) window.addEvent('load', inject);
-			else inject();
-		} else {
-			this.position = this.hide = this.show = this.dispose = Function.from(this);
-		}
-	},
-
-	position: function(){
-		if (!IframeShim.ready || !this.shim) return this;
-		var size = this.element.measure(function(){
-			return this.getSize();
-		});
-		if (this.options.margin != undefined){
-			size.x = size.x - (this.options.margin * 2);
-			size.y = size.y - (this.options.margin * 2);
-			this.options.offset.x += this.options.margin;
-			this.options.offset.y += this.options.margin;
-		}
-		this.shim.set({width: size.x, height: size.y}).position({
-			relativeTo: this.element,
-			offset: this.options.offset
-		});
-		return this;
-	},
-
-	hide: function(){
-		if (this.shim) this.shim.setStyle('display', 'none');
-		return this;
-	},
-
-	show: function(){
-		if (this.shim) this.shim.setStyle('display', 'block');
-		return this.position();
-	},
-
-	dispose: function(){
-		if (this.shim) this.shim.dispose();
-		return this;
-	},
-
-	destroy: function(){
-		if (this.shim) this.shim.destroy();
-		return this;
-	}
+  Implements: [Options, Events, Class.Occlude],
+
+  options: {
+    className: 'iframeShim',
+    src: 'javascript:false;document.write("");',
+    display: false,
+    zIndex: null,
+    margin: 0,
+    offset: {x: 0, y: 0},
+    browsers: browsers
+  },
+
+  property: 'IframeShim',
+
+  initialize: function(element, options){
+    this.element = document.id(element);
+    if (this.occlude()) return this.occluded;
+    this.setOptions(options);
+    this.makeShim();
+    return this;
+  },
+
+  makeShim: function(){
+    if (this.options.browsers){
+      var zIndex = this.element.getStyle('zIndex').toInt();
+
+      if (!zIndex){
+        zIndex = 1;
+        var pos = this.element.getStyle('position');
+        if (pos == 'static' || !pos) this.element.setStyle('position', 'relative');
+        this.element.setStyle('zIndex', zIndex);
+      }
+      zIndex = ((this.options.zIndex != null || this.options.zIndex === 0) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1;
+      if (zIndex < 0) zIndex = 1;
+      this.shim = new Element('iframe', {
+        src: this.options.src,
+        scrolling: 'no',
+        frameborder: 0,
+        styles: {
+          zIndex: zIndex,
+          position: 'absolute',
+          border: 'none',
+          filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)'
+        },
+        'class': this.options.className
+      }).store('IframeShim', this);
+      var inject = (function(){
+        this.shim.inject(this.element, 'after');
+        this[this.options.display ? 'show' : 'hide']();
+        this.fireEvent('inject');
+      }).bind(this);
+      if (!IframeShim.ready) window.addEvent('load', inject);
+      else inject();
+    } else {
+      this.position = this.hide = this.show = this.dispose = Function.from(this);
+    }
+  },
+
+  position: function(){
+    if (!IframeShim.ready || !this.shim) return this;
+    var size = this.element.measure(function(){
+      return this.getSize();
+    });
+    if (this.options.margin != undefined){
+      size.x = size.x - (this.options.margin * 2);
+      size.y = size.y - (this.options.margin * 2);
+      this.options.offset.x += this.options.margin;
+      this.options.offset.y += this.options.margin;
+    }
+    this.shim.set({width: size.x, height: size.y}).position({
+      relativeTo: this.element,
+      offset: this.options.offset
+    });
+    return this;
+  },
+
+  hide: function(){
+    if (this.shim) this.shim.setStyle('display', 'none');
+    return this;
+  },
+
+  show: function(){
+    if (this.shim) this.shim.setStyle('display', 'block');
+    return this.position();
+  },
+
+  dispose: function(){
+    if (this.shim) this.shim.dispose();
+    return this;
+  },
+
+  destroy: function(){
+    if (this.shim) this.shim.destroy();
+    return this;
+  }
 
 });
 
 })();
 
 window.addEvent('load', function(){
-	IframeShim.ready = true;
+  IframeShim.ready = true;
 });
 
 
@@ -744,186 +744,186 @@ provides: [Mask]
 
 var Mask = new Class({
 
-	Implements: [Options, Events],
-
-	Binds: ['position'],
-
-	options: {/*
-		onShow: function(){},
-		onHide: function(){},
-		onDestroy: function(){},
-		onClick: function(event){},
-		inject: {
-			where: 'after',
-			target: null,
-		},
-		hideOnClick: false,
-		id: null,
-		destroyOnHide: false,*/
-		style: {},
-		'class': 'mask',
-		maskMargins: false,
-		useIframeShim: true,
-		iframeShimOptions: {}
-	},
-
-	initialize: function(target, options){
-		this.target = document.id(target) || document.id(document.body);
-		this.target.store('mask', this);
-		this.setOptions(options);
-		this.render();
-		this.inject();
-	},
-
-	render: function(){
-		this.element = new Element('div', {
-			'class': this.options['class'],
-			id: this.options.id || 'mask-' + String.uniqueID(),
-			styles: Object.merge({}, this.options.style, {
-				display: 'none'
-			}),
-			events: {
-				click: function(event){
-					this.fireEvent('click', event);
-					if (this.options.hideOnClick) this.hide();
-				}.bind(this)
-			}
-		});
-
-		this.hidden = true;
-	},
-
-	toElement: function(){
-		return this.element;
-	},
-
-	inject: function(target, where){
-		where = where || (this.options.inject ? this.options.inject.where : '') || (this.target == document.body ? 'inside' : 'after');
-		target = target || (this.options.inject && this.options.inject.target) || this.target;
-
-		this.element.inject(target, where);
-
-		if (this.options.useIframeShim){
-			this.shim = new IframeShim(this.element, this.options.iframeShimOptions);
-
-			this.addEvents({
-				show: this.shim.show.bind(this.shim),
-				hide: this.shim.hide.bind(this.shim),
-				destroy: this.shim.destroy.bind(this.shim)
-			});
-		}
-	},
-
-	position: function(){
-		this.resize(this.options.width, this.options.height);
-
-		this.element.position({
-			relativeTo: this.target,
-			position: 'topLeft',
-			ignoreMargins: !this.options.maskMargins,
-			ignoreScroll: this.target == document.body
-		});
-
-		return this;
-	},
-
-	resize: function(x, y){
-		var opt = {
-			styles: ['padding', 'border']
-		};
-		if (this.options.maskMargins) opt.styles.push('margin');
-
-		var dim = this.target.getComputedSize(opt);
-		if (this.target == document.body){
-			this.element.setStyles({width: 0, height: 0});
-			var win = window.getScrollSize();
-			if (dim.totalHeight < win.y) dim.totalHeight = win.y;
-			if (dim.totalWidth < win.x) dim.totalWidth = win.x;
-		}
-		this.element.setStyles({
-			width: Array.pick([x, dim.totalWidth, dim.x]),
-			height: Array.pick([y, dim.totalHeight, dim.y])
-		});
-
-		return this;
-	},
-
-	show: function(){
-		if (!this.hidden) return this;
-
-		window.addEvent('resize', this.position);
-		this.position();
-		this.showMask.apply(this, arguments);
-
-		return this;
-	},
-
-	showMask: function(){
-		this.element.setStyle('display', 'block');
-		this.hidden = false;
-		this.fireEvent('show');
-	},
-
-	hide: function(){
-		if (this.hidden) return this;
-
-		window.removeEvent('resize', this.position);
-		this.hideMask.apply(this, arguments);
-		if (this.options.destroyOnHide) return this.destroy();
-
-		return this;
-	},
-
-	hideMask: function(){
-		this.element.setStyle('display', 'none');
-		this.hidden = true;
-		this.fireEvent('hide');
-	},
-
-	toggle: function(){
-		this[this.hidden ? 'show' : 'hide']();
-	},
-
-	destroy: function(){
-		this.hide();
-		this.element.destroy();
-		this.fireEvent('destroy');
-		this.target.eliminate('mask');
-	}
+  Implements: [Options, Events],
+
+  Binds: ['position'],
+
+  options: {/*
+    onShow: function(){},
+    onHide: function(){},
+    onDestroy: function(){},
+    onClick: function(event){},
+    inject: {
+      where: 'after',
+      target: null,
+    },
+    hideOnClick: false,
+    id: null,
+    destroyOnHide: false,*/
+    style: {},
+    'class': 'mask',
+    maskMargins: false,
+    useIframeShim: true,
+    iframeShimOptions: {}
+  },
+
+  initialize: function(target, options){
+    this.target = document.id(target) || document.id(document.body);
+    this.target.store('mask', this);
+    this.setOptions(options);
+    this.render();
+    this.inject();
+  },
+
+  render: function(){
+    this.element = new Element('div', {
+      'class': this.options['class'],
+      id: this.options.id || 'mask-' + String.uniqueID(),
+      styles: Object.merge({}, this.options.style, {
+        display: 'none'
+      }),
+      events: {
+        click: function(event){
+          this.fireEvent('click', event);
+          if (this.options.hideOnClick) this.hide();
+        }.bind(this)
+      }
+    });
+
+    this.hidden = true;
+  },
+
+  toElement: function(){
+    return this.element;
+  },
+
+  inject: function(target, where){
+    where = where || (this.options.inject ? this.options.inject.where : '') || (this.target == document.body ? 'inside' : 'after');
+    target = target || (this.options.inject && this.options.inject.target) || this.target;
+
+    this.element.inject(target, where);
+
+    if (this.options.useIframeShim){
+      this.shim = new IframeShim(this.element, this.options.iframeShimOptions);
+
+      this.addEvents({
+        show: this.shim.show.bind(this.shim),
+        hide: this.shim.hide.bind(this.shim),
+        destroy: this.shim.destroy.bind(this.shim)
+      });
+    }
+  },
+
+  position: function(){
+    this.resize(this.options.width, this.options.height);
+
+    this.element.position({
+      relativeTo: this.target,
+      position: 'topLeft',
+      ignoreMargins: !this.options.maskMargins,
+      ignoreScroll: this.target == document.body
+    });
+
+    return this;
+  },
+
+  resize: function(x, y){
+    var opt = {
+      styles: ['padding', 'border']
+    };
+    if (this.options.maskMargins) opt.styles.push('margin');
+
+    var dim = this.target.getComputedSize(opt);
+    if (this.target == document.body){
+      this.element.setStyles({width: 0, height: 0});
+      var win = window.getScrollSize();
+      if (dim.totalHeight < win.y) dim.totalHeight = win.y;
+      if (dim.totalWidth < win.x) dim.totalWidth = win.x;
+    }
+    this.element.setStyles({
+      width: Array.pick([x, dim.totalWidth, dim.x]),
+      height: Array.pick([y, dim.totalHeight, dim.y])
+    });
+
+    return this;
+  },
+
+  show: function(){
+    if (!this.hidden) return this;
+
+    window.addEvent('resize', this.position);
+    this.position();
+    this.showMask.apply(this, arguments);
+
+    return this;
+  },
+
+  showMask: function(){
+    this.element.setStyle('display', 'block');
+    this.hidden = false;
+    this.fireEvent('show');
+  },
+
+  hide: function(){
+    if (this.hidden) return this;
+
+    window.removeEvent('resize', this.position);
+    this.hideMask.apply(this, arguments);
+    if (this.options.destroyOnHide) return this.destroy();
+
+    return this;
+  },
+
+  hideMask: function(){
+    this.element.setStyle('display', 'none');
+    this.hidden = true;
+    this.fireEvent('hide');
+  },
+
+  toggle: function(){
+    this[this.hidden ? 'show' : 'hide']();
+  },
+
+  destroy: function(){
+    this.hide();
+    this.element.destroy();
+    this.fireEvent('destroy');
+    this.target.eliminate('mask');
+  }
 
 });
 
 Element.Properties.mask = {
 
-	set: function(options){
-		var mask = this.retrieve('mask');
-		if (mask) mask.destroy();
-		return this.eliminate('mask').store('mask:options', options);
-	},
-
-	get: function(){
-		var mask = this.retrieve('mask');
-		if (!mask){
-			mask = new Mask(this, this.retrieve('mask:options'));
-			this.store('mask', mask);
-		}
-		return mask;
-	}
+  set: function(options){
+    var mask = this.retrieve('mask');
+    if (mask) mask.destroy();
+    return this.eliminate('mask').store('mask:options', options);
+  },
+
+  get: function(){
+    var mask = this.retrieve('mask');
+    if (!mask){
+      mask = new Mask(this, this.retrieve('mask:options'));
+      this.store('mask', mask);
+    }
+    return mask;
+  }
 
 };
 
 Element.implement({
 
-	mask: function(options){
-		if (options) this.set('mask', options);
-		this.get('mask').show();
-		return this;
-	},
+  mask: function(options){
+    if (options) this.set('mask', options);
+    this.get('mask').show();
+    return this;
+  },
 
-	unmask: function(){
-		this.get('mask').hide();
-		return this;
-	}
+  unmask: function(){
+    this.get('mask').hide();
+    return this;
+  }
 
 });
 
@@ -955,197 +955,197 @@ provides: [Spinner]
 
 var Spinner = new Class({
 
-	Extends: Mask,
-
-	Implements: Chain,
-
-	options: {/*
-		message: false,*/
-		'class': 'spinner',
-		containerPosition: {},
-		content: {
-			'class': 'spinner-content'
-		},
-		messageContainer: {
-			'class': 'spinner-msg'
-		},
-		img: {
-			'class': 'spinner-img'
-		},
-		fxOptions: {
-			link: 'chain'
-		}
-	},
-
-	initialize: function(target, options){
-		this.target = document.id(target) || document.id(document.body);
-		this.target.store('spinner', this);
-		this.setOptions(options);
-		this.render();
-		this.inject();
-
-		// Add this to events for when noFx is true; parent methods handle hide/show.
-		var deactivate = function(){ this.active = false; }.bind(this);
-		this.addEvents({
-			hide: deactivate,
-			show: deactivate
-		});
-	},
-
-	render: function(){
-		this.parent();
-
-		this.element.set('id', this.options.id || 'spinner-' + String.uniqueID());
-
-		this.content = document.id(this.options.content) || new Element('div', this.options.content);
-		this.content.inject(this.element);
-
-		if (this.options.message){
-			this.msg = document.id(this.options.message) || new Element('p', this.options.messageContainer).appendText(this.options.message);
-			this.msg.inject(this.content);
-		}
-
-		if (this.options.img){
-			this.img = document.id(this.options.img) || new Element('div', this.options.img);
-			this.img.inject(this.content);
-		}
-
-		this.element.set('tween', this.options.fxOptions);
-	},
-
-	show: function(noFx){
-		if (this.active) return this.chain(this.show.bind(this));
-		if (!this.hidden){
-			this.callChain.delay(20, this);
-			return this;
-		}
-
-		this.target.set('aria-busy', 'true');
-		this.active = true;
-
-		return this.parent(noFx);
-	},
-
-	showMask: function(noFx){
-		var pos = function(){
-			this.content.position(Object.merge({
-				relativeTo: this.element
-			}, this.options.containerPosition));
-		}.bind(this);
-
-		if (noFx){
-			this.parent();
-			pos();
-		} else {
-			if (!this.options.style.opacity) this.options.style.opacity = this.element.getStyle('opacity').toFloat();
-			this.element.setStyles({
-				display: 'block',
-				opacity: 0
-			}).tween('opacity', this.options.style.opacity);
-			pos();
-			this.hidden = false;
-			this.fireEvent('show');
-			this.callChain();
-		}
-	},
-
-	hide: function(noFx){
-		if (this.active) return this.chain(this.hide.bind(this));
-		if (this.hidden){
-			this.callChain.delay(20, this);
-			return this;
-		}
-
-		this.target.set('aria-busy', 'false');
-		this.active = true;
-
-		return this.parent(noFx);
-	},
-
-	hideMask: function(noFx){
-		if (noFx) return this.parent();
-		this.element.tween('opacity', 0).get('tween').chain(function(){
-			this.element.setStyle('display', 'none');
-			this.hidden = true;
-			this.fireEvent('hide');
-			this.callChain();
-		}.bind(this));
-	},
-
-	destroy: function(){
-		this.content.destroy();
-		this.parent();
-		this.target.eliminate('spinner');
-	}
+  Extends: Mask,
+
+  Implements: Chain,
+
+  options: {/*
+    message: false,*/
+    'class': 'spinner',
+    containerPosition: {},
+    content: {
+      'class': 'spinner-content'
+    },
+    messageContainer: {
+      'class': 'spinner-msg'
+    },
+    img: {
+      'class': 'spinner-img'
+    },
+    fxOptions: {
+      link: 'chain'
+    }
+  },
+
+  initialize: function(target, options){
+    this.target = document.id(target) || document.id(document.body);
+    this.target.store('spinner', this);
+    this.setOptions(options);
+    this.render();
+    this.inject();
+
+    // Add this to events for when noFx is true; parent methods handle hide/show.
+    var deactivate = function(){ this.active = false; }.bind(this);
+    this.addEvents({
+      hide: deactivate,
+      show: deactivate
+    });
+  },
+
+  render: function(){
+    this.parent();
+
+    this.element.set('id', this.options.id || 'spinner-' + String.uniqueID());
+
+    this.content = document.id(this.options.content) || new Element('div', this.options.content);
+    this.content.inject(this.element);
+
+    if (this.options.message){
+      this.msg = document.id(this.options.message) || new Element('p', this.options.messageContainer).appendText(this.options.message);
+      this.msg.inject(this.content);
+    }
+
+    if (this.options.img){
+      this.img = document.id(this.options.img) || new Element('div', this.options.img);
+      this.img.inject(this.content);
+    }
+
+    this.element.set('tween', this.options.fxOptions);
+  },
+
+  show: function(noFx){
+    if (this.active) return this.chain(this.show.bind(this));
+    if (!this.hidden){
+      this.callChain.delay(20, this);
+      return this;
+    }
+
+    this.target.set('aria-busy', 'true');
+    this.active = true;
+
+    return this.parent(noFx);
+  },
+
+  showMask: function(noFx){
+    var pos = function(){
+      this.content.position(Object.merge({
+        relativeTo: this.element
+      }, this.options.containerPosition));
+    }.bind(this);
+
+    if (noFx){
+      this.parent();
+      pos();
+    } else {
+      if (!this.options.style.opacity) this.options.style.opacity = this.element.getStyle('opacity').toFloat();
+      this.element.setStyles({
+        display: 'block',
+        opacity: 0
+      }).tween('opacity', this.options.style.opacity);
+      pos();
+      this.hidden = false;
+      this.fireEvent('show');
+      this.callChain();
+    }
+  },
+
+  hide: function(noFx){
+    if (this.active) return this.chain(this.hide.bind(this));
+    if (this.hidden){
+      this.callChain.delay(20, this);
+      return this;
+    }
+
+    this.target.set('aria-busy', 'false');
+    this.active = true;
+
+    return this.parent(noFx);
+  },
+
+  hideMask: function(noFx){
+    if (noFx) return this.parent();
+    this.element.tween('opacity', 0).get('tween').chain(function(){
+      this.element.setStyle('display', 'none');
+      this.hidden = true;
+      this.fireEvent('hide');
+      this.callChain();
+    }.bind(this));
+  },
+
+  destroy: function(){
+    this.content.destroy();
+    this.parent();
+    this.target.eliminate('spinner');
+  }
 
 });
 
 Request = Class.refactor(Request, {
 
-	options: {
-		useSpinner: false,
-		spinnerOptions: {},
-		spinnerTarget: false
-	},
-
-	initialize: function(options){
-		this._send = this.send;
-		this.send = function(options){
-			var spinner = this.getSpinner();
-			if (spinner) spinner.chain(this._send.pass(options, this)).show();
-			else this._send(options);
-			return this;
-		};
-		this.previous(options);
-	},
-
-	getSpinner: function(){
-		if (!this.spinner){
-			var update = document.id(this.options.spinnerTarget) || document.id(this.options.update);
-			if (this.options.useSpinner && update){
-				update.set('spinner', this.options.spinnerOptions);
-				var spinner = this.spinner = update.get('spinner');
-				['complete', 'exception', 'cancel'].each(function(event){
-					this.addEvent(event, spinner.hide.bind(spinner));
-				}, this);
-			}
-		}
-		return this.spinner;
-	}
+  options: {
+    useSpinner: false,
+    spinnerOptions: {},
+    spinnerTarget: false
+  },
+
+  initialize: function(options){
+    this._send = this.send;
+    this.send = function(options){
+      var spinner = this.getSpinner();
+      if (spinner) spinner.chain(this._send.pass(options, this)).show();
+      else this._send(options);
+      return this;
+    };
+    this.previous(options);
+  },
+
+  getSpinner: function(){
+    if (!this.spinner){
+      var update = document.id(this.options.spinnerTarget) || document.id(this.options.update);
+      if (this.options.useSpinner && update){
+        update.set('spinner', this.options.spinnerOptions);
+        var spinner = this.spinner = update.get('spinner');
+        ['complete', 'exception', 'cancel'].each(function(event){
+          this.addEvent(event, spinner.hide.bind(spinner));
+        }, this);
+      }
+    }
+    return this.spinner;
+  }
 
 });
 
 Element.Properties.spinner = {
 
-	set: function(options){
-		var spinner = this.retrieve('spinner');
-		if (spinner) spinner.destroy();
-		return this.eliminate('spinner').store('spinner:options', options);
-	},
-
-	get: function(){
-		var spinner = this.retrieve('spinner');
-		if (!spinner){
-			spinner = new Spinner(this, this.retrieve('spinner:options'));
-			this.store('spinner', spinner);
-		}
-		return spinner;
-	}
+  set: function(options){
+    var spinner = this.retrieve('spinner');
+    if (spinner) spinner.destroy();
+    return this.eliminate('spinner').store('spinner:options', options);
+  },
+
+  get: function(){
+    var spinner = this.retrieve('spinner');
+    if (!spinner){
+      spinner = new Spinner(this, this.retrieve('spinner:options'));
+      this.store('spinner', spinner);
+    }
+    return spinner;
+  }
 
 };
 
 Element.implement({
 
-	spin: function(options){
-		if (options) this.set('spinner', options);
-		this.get('spinner').show();
-		return this;
-	},
+  spin: function(options){
+    if (options) this.set('spinner', options);
+    this.get('spinner').show();
+    return this;
+  },
 
-	unspin: function(){
-		this.get('spinner').hide();
-		return this;
-	}
+  unspin: function(){
+    this.get('spinner').hide();
+    return this;
+  }
 
 });
 
@@ -1179,43 +1179,43 @@ provides: [String.QueryString]
 
 String.implement({
 
-	parseQueryString: function(decodeKeys, decodeValues){
-		if (decodeKeys == null) decodeKeys = true;
-		if (decodeValues == null) decodeValues = true;
-
-		var vars = this.split(/[&;]/),
-			object = {};
-		if (!vars.length) return object;
-
-		vars.each(function(val){
-			var index = val.indexOf('=') + 1,
-				value = index ? val.substr(index) : '',
-				keys = index ? val.substr(0, index - 1).match(/([^\]\[]+|(\B)(?=\]))/g) : [val],
-				obj = object;
-			if (!keys) return;
-			if (decodeValues) value = decodeURIComponent(value);
-			keys.each(function(key, i){
-				if (decodeKeys) key = decodeURIComponent(key);
-				var current = obj[key];
-
-				if (i < keys.length - 1) obj = obj[key] = current || {};
-				else if (typeOf(current) == 'array') current.push(value);
-				else obj[key] = current != null ? [current, value] : value;
-			});
-		});
-
-		return object;
-	},
-
-	cleanQueryString: function(method){
-		return this.split('&').filter(function(val){
-			var index = val.indexOf('='),
-				key = index < 0 ? '' : val.substr(0, index),
-				value = val.substr(index + 1);
-
-			return method ? method.call(null, key, value) : (value || value === 0);
-		}).join('&');
-	}
+  parseQueryString: function(decodeKeys, decodeValues){
+    if (decodeKeys == null) decodeKeys = true;
+    if (decodeValues == null) decodeValues = true;
+
+    var vars = this.split(/[&;]/),
+      object = {};
+    if (!vars.length) return object;
+
+    vars.each(function(val){
+      var index = val.indexOf('=') + 1,
+        value = index ? val.substr(index) : '',
+        keys = index ? val.substr(0, index - 1).match(/([^\]\[]+|(\B)(?=\]))/g) : [val],
+        obj = object;
+      if (!keys) return;
+      if (decodeValues) value = decodeURIComponent(value);
+      keys.each(function(key, i){
+        if (decodeKeys) key = decodeURIComponent(key);
+        var current = obj[key];
+
+        if (i < keys.length - 1) obj = obj[key] = current || {};
+        else if (typeOf(current) == 'array') current.push(value);
+        else obj[key] = current != null ? [current, value] : value;
+      });
+    });
+
+    return object;
+  },
+
+  cleanQueryString: function(method){
+    return this.split('&').filter(function(val){
+      var index = val.indexOf('='),
+        key = index < 0 ? '' : val.substr(0, index),
+        value = val.substr(index + 1);
+
+      return method ? method.call(null, key, value) : (value || value === 0);
+    }).join('&');
+  }
 
 });
 
@@ -1243,137 +1243,137 @@ provides: [Events.Pseudos]
 
 Events.Pseudos = function(pseudos, addEvent, removeEvent){
 
-	var storeKey = '_monitorEvents:';
-
-	var storageOf = function(object){
-		return {
-			store: object.store ? function(key, value){
-				object.store(storeKey + key, value);
-			} : function(key, value){
-				(object._monitorEvents || (object._monitorEvents = {}))[key] = value;
-			},
-			retrieve: object.retrieve ? function(key, dflt){
-				return object.retrieve(storeKey + key, dflt);
-			} : function(key, dflt){
-				if (!object._monitorEvents) return dflt;
-				return object._monitorEvents[key] || dflt;
-			}
-		};
-	};
-
-	var splitType = function(type){
-		if (type.indexOf(':') == -1 || !pseudos) return null;
-
-		var parsed = Slick.parse(type).expressions[0][0],
-			parsedPseudos = parsed.pseudos,
-			l = parsedPseudos.length,
-			splits = [];
-
-		while (l--){
-			var pseudo = parsedPseudos[l].key,
-				listener = pseudos[pseudo];
-			if (listener != null) splits.push({
-				event: parsed.tag,
-				value: parsedPseudos[l].value,
-				pseudo: pseudo,
-				original: type,
-				listener: listener
-			});
-		}
-		return splits.length ? splits : null;
-	};
-
-	return {
-
-		addEvent: function(type, fn, internal){
-			var split = splitType(type);
-			if (!split) return addEvent.call(this, type, fn, internal);
-
-			var storage = storageOf(this),
-				events = storage.retrieve(type, []),
-				eventType = split[0].event,
-				args = Array.slice(arguments, 2),
-				stack = fn,
-				self = this;
-
-			split.each(function(item){
-				var listener = item.listener,
-					stackFn = stack;
-				if (listener == false) eventType += ':' + item.pseudo + '(' + item.value + ')';
-				else stack = function(){
-					listener.call(self, item, stackFn, arguments, stack);
-				};
-			});
-
-			events.include({type: eventType, event: fn, monitor: stack});
-			storage.store(type, events);
-
-			if (type != eventType) addEvent.apply(this, [type, fn].concat(args));
-			return addEvent.apply(this, [eventType, stack].concat(args));
-		},
-
-		removeEvent: function(type, fn){
-			var split = splitType(type);
-			if (!split) return removeEvent.call(this, type, fn);
-
-			var storage = storageOf(this),
-				events = storage.retrieve(type);
-			if (!events) return this;
-
-			var args = Array.slice(arguments, 2);
-
-			removeEvent.apply(this, [type, fn].concat(args));
-			events.each(function(monitor, i){
-				if (!fn || monitor.event == fn) removeEvent.apply(this, [monitor.type, monitor.monitor].concat(args));
-				delete events[i];
-			}, this);
-
-			storage.store(type, events);
-			return this;
-		}
-
-	};
+  var storeKey = '_monitorEvents:';
+
+  var storageOf = function(object){
+    return {
+      store: object.store ? function(key, value){
+        object.store(storeKey + key, value);
+      } : function(key, value){
+        (object._monitorEvents || (object._monitorEvents = {}))[key] = value;
+      },
+      retrieve: object.retrieve ? function(key, dflt){
+        return object.retrieve(storeKey + key, dflt);
+      } : function(key, dflt){
+        if (!object._monitorEvents) return dflt;
+        return object._monitorEvents[key] || dflt;
+      }
+    };
+  };
+
+  var splitType = function(type){
+    if (type.indexOf(':') == -1 || !pseudos) return null;
+
+    var parsed = Slick.parse(type).expressions[0][0],
+      parsedPseudos = parsed.pseudos,
+      l = parsedPseudos.length,
+      splits = [];
+
+    while (l--){
+      var pseudo = parsedPseudos[l].key,
+        listener = pseudos[pseudo];
+      if (listener != null) splits.push({
+        event: parsed.tag,
+        value: parsedPseudos[l].value,
+        pseudo: pseudo,
+        original: type,
+        listener: listener
+      });
+    }
+    return splits.length ? splits : null;
+  };
+
+  return {
+
+    addEvent: function(type, fn, internal){
+      var split = splitType(type);
+      if (!split) return addEvent.call(this, type, fn, internal);
+
+      var storage = storageOf(this),
+        events = storage.retrieve(type, []),
+        eventType = split[0].event,
+        args = Array.slice(arguments, 2),
+        stack = fn,
+        self = this;
+
+      split.each(function(item){
+        var listener = item.listener,
+          stackFn = stack;
+        if (listener == false) eventType += ':' + item.pseudo + '(' + item.value + ')';
+        else stack = function(){
+          listener.call(self, item, stackFn, arguments, stack);
+        };
+      });
+
+      events.include({type: eventType, event: fn, monitor: stack});
+      storage.store(type, events);
+
+      if (type != eventType) addEvent.apply(this, [type, fn].concat(args));
+      return addEvent.apply(this, [eventType, stack].concat(args));
+    },
+
+    removeEvent: function(type, fn){
+      var split = splitType(type);
+      if (!split) return removeEvent.call(this, type, fn);
+
+      var storage = storageOf(this),
+        events = storage.retrieve(type);
+      if (!events) return this;
+
+      var args = Array.slice(arguments, 2);
+
+      removeEvent.apply(this, [type, fn].concat(args));
+      events.each(function(monitor, i){
+        if (!fn || monitor.event == fn) removeEvent.apply(this, [monitor.type, monitor.monitor].concat(args));
+        delete events[i];
+      }, this);
+
+      storage.store(type, events);
+      return this;
+    }
+
+  };
 
 };
 
 var pseudos = {
 
-	once: function(split, fn, args, monitor){
-		fn.apply(this, args);
-		this.removeEvent(split.event, monitor)
-			.removeEvent(split.original, fn);
-	},
-
-	throttle: function(split, fn, args){
-		if (!fn._throttled){
-			fn.apply(this, args);
-			fn._throttled = setTimeout(function(){
-				fn._throttled = false;
-			}, split.value || 250);
-		}
-	},
-
-	pause: function(split, fn, args){
-		clearTimeout(fn._pause);
-		fn._pause = fn.delay(split.value || 250, this, args);
-	}
+  once: function(split, fn, args, monitor){
+    fn.apply(this, args);
+    this.removeEvent(split.event, monitor)
+      .removeEvent(split.original, fn);
+  },
+
+  throttle: function(split, fn, args){
+    if (!fn._throttled){
+      fn.apply(this, args);
+      fn._throttled = setTimeout(function(){
+        fn._throttled = false;
+      }, split.value || 250);
+    }
+  },
+
+  pause: function(split, fn, args){
+    clearTimeout(fn._pause);
+    fn._pause = fn.delay(split.value || 250, this, args);
+  }
 
 };
 
 Events.definePseudo = function(key, listener){
-	pseudos[key] = listener;
-	return this;
+  pseudos[key] = listener;
+  return this;
 };
 
 Events.lookupPseudo = function(key){
-	return pseudos[key];
+  return pseudos[key];
 };
 
 var proto = Events.prototype;
 Events.implement(Events.Pseudos(pseudos, proto.addEvent, proto.removeEvent));
 
 ['Request', 'Fx'].each(function(klass){
-	if (this[klass]) this[klass].implement(Events.prototype);
+  if (this[klass]) this[klass].implement(Events.prototype);
 });
 
 })();
@@ -1401,14 +1401,14 @@ provides: [Element.Event.Pseudos, Element.Delegation.Pseudo]
 (function(){
 
 var pseudos = {relay: false},
-	copyFromEvents = ['once', 'throttle', 'pause'],
-	count = copyFromEvents.length;
+  copyFromEvents = ['once', 'throttle', 'pause'],
+  count = copyFromEvents.length;
 
 while (count--) pseudos[copyFromEvents[count]] = Events.lookupPseudo(copyFromEvents[count]);
 
 DOMEvent.definePseudo = function(key, listener){
-	pseudos[key] = listener;
-	return this;
+  pseudos[key] = listener;
+  return this;
 };
 
 var proto = Element.prototype;
@@ -1448,176 +1448,176 @@ if (!window.Form) window.Form = {};
 
 (function(){
 
-	Form.Request = new Class({
-
-		Binds: ['onSubmit', 'onFormValidate'],
-
-		Implements: [Options, Events, Class.Occlude],
-
-		options: {/*
-			onFailure: function(){},
-			onSuccess: function(){}, // aliased to onComplete,
-			onSend: function(){}*/
-			requestOptions: {
-				evalScripts: true,
-				useSpinner: true,
-				emulation: false,
-				link: 'ignore'
-			},
-			sendButtonClicked: true,
-			extraData: {},
-			resetForm: true
-		},
-
-		property: 'form.request',
-
-		initialize: function(form, target, options){
-			this.element = document.id(form);
-			if (this.occlude()) return this.occluded;
-			this.setOptions(options)
-				.setTarget(target)
-				.attach();
-		},
-
-		setTarget: function(target){
-			this.target = document.id(target);
-			if (!this.request){
-				this.makeRequest();
-			} else {
-				this.request.setOptions({
-					update: this.target
-				});
-			}
-			return this;
-		},
-
-		toElement: function(){
-			return this.element;
-		},
-
-		makeRequest: function(){
-			var self = this;
-			this.request = new Request.HTML(Object.merge({
-					update: this.target,
-					emulation: false,
-					spinnerTarget: this.element,
-					method: this.element.get('method') || 'post'
-			}, this.options.requestOptions)).addEvents({
-				success: function(tree, elements, html, javascript){
-					['complete', 'success'].each(function(evt){
-						self.fireEvent(evt, [self.target, tree, elements, html, javascript]);
-					});
-				},
-				failure: function(){
-					self.fireEvent('complete', arguments).fireEvent('failure', arguments);
-				},
-				exception: function(){
-					self.fireEvent('failure', arguments);
-				}
-			});
-			return this.attachReset();
-		},
-
-		attachReset: function(){
-			if (!this.options.resetForm) return this;
-			this.request.addEvent('success', function(){
-				Function.attempt(function(){
-					this.element.reset();
-				}.bind(this));
-				if (window.OverText) OverText.update();
-			}.bind(this));
-			return this;
-		},
-
-		attach: function(attach){
-			var method = (attach != false) ? 'addEvent' : 'removeEvent';
-			this.element[method]('click:relay(button, input[type=submit])', this.saveClickedButton.bind(this));
-
-			var fv = this.element.retrieve('validator');
-			if (fv) fv[method]('onFormValidate', this.onFormValidate);
-			else this.element[method]('submit', this.onSubmit);
-
-			return this;
-		},
-
-		detach: function(){
-			return this.attach(false);
-		},
-
-		//public method
-		enable: function(){
-			return this.attach();
-		},
-
-		//public method
-		disable: function(){
-			return this.detach();
-		},
-
-		onFormValidate: function(valid, form, event){
-			//if there's no event, then this wasn't a submit event
-			if (!event) return;
-			var fv = this.element.retrieve('validator');
-			if (valid || (fv && !fv.options.stopOnFailure)){
-				event.stop();
-				this.send();
-			}
-		},
-
-		onSubmit: function(event){
-			var fv = this.element.retrieve('validator');
-			if (fv){
-				//form validator was created after Form.Request
-				this.element.removeEvent('submit', this.onSubmit);
-				fv.addEvent('onFormValidate', this.onFormValidate);
-				fv.validate(event);
-				return;
-			}
-			if (event) event.stop();
-			this.send();
-		},
-
-		saveClickedButton: function(event, target){
-			var targetName = target.get('name');
-			if (!targetName || !this.options.sendButtonClicked) return;
-			this.options.extraData[targetName] = target.get('value') || true;
-			this.clickedCleaner = function(){
-				delete this.options.extraData[targetName];
-				this.clickedCleaner = function(){};
-			}.bind(this);
-		},
-
-		clickedCleaner: function(){},
-
-		send: function(){
-			var str = this.element.toQueryString().trim(),
-				data = Object.toQueryString(this.options.extraData);
-
-			if (str) str += "&" + data;
-			else str = data;
-
-			this.fireEvent('send', [this.element, str.parseQueryString()]);
-			this.request.send({
-				data: str,
-				url: this.options.requestOptions.url || this.element.get('action')
-			});
-			this.clickedCleaner();
-			return this;
-		}
-
-	});
-
-	Element.implement('formUpdate', function(update, options){
-		var fq = this.retrieve('form.request');
-		if (!fq){
-			fq = new Form.Request(this, update, options);
-		} else {
-			if (update) fq.setTarget(update);
-			if (options) fq.setOptions(options).makeRequest();
-		}
-		fq.send();
-		return this;
-	});
+  Form.Request = new Class({
+
+    Binds: ['onSubmit', 'onFormValidate'],
+
+    Implements: [Options, Events, Class.Occlude],
+
+    options: {/*
+      onFailure: function(){},
+      onSuccess: function(){}, // aliased to onComplete,
+      onSend: function(){}*/
+      requestOptions: {
+        evalScripts: true,
+        useSpinner: true,
+        emulation: false,
+        link: 'ignore'
+      },
+      sendButtonClicked: true,
+      extraData: {},
+      resetForm: true
+    },
+
+    property: 'form.request',
+
+    initialize: function(form, target, options){
+      this.element = document.id(form);
+      if (this.occlude()) return this.occluded;
+      this.setOptions(options)
+        .setTarget(target)
+        .attach();
+    },
+
+    setTarget: function(target){
+      this.target = document.id(target);
+      if (!this.request){
+        this.makeRequest();
+      } else {
+        this.request.setOptions({
+          update: this.target
+        });
+      }
+      return this;
+    },
+
+    toElement: function(){
+      return this.element;
+    },
+
+    makeRequest: function(){
+      var self = this;
+      this.request = new Request.HTML(Object.merge({
+          update: this.target,
+          emulation: false,
+          spinnerTarget: this.element,
+          method: this.element.get('method') || 'post'
+      }, this.options.requestOptions)).addEvents({
+        success: function(tree, elements, html, javascript){
+          ['complete', 'success'].each(function(evt){
+            self.fireEvent(evt, [self.target, tree, elements, html, javascript]);
+          });
+        },
+        failure: function(){
+          self.fireEvent('complete', arguments).fireEvent('failure', arguments);
+        },
+        exception: function(){
+          self.fireEvent('failure', arguments);
+        }
+      });
+      return this.attachReset();
+    },
+
+    attachReset: function(){
+      if (!this.options.resetForm) return this;
+      this.request.addEvent('success', function(){
+        Function.attempt(function(){
+          this.element.reset();
+        }.bind(this));
+        if (window.OverText) OverText.update();
+      }.bind(this));
+      return this;
+    },
+
+    attach: function(attach){
+      var method = (attach != false) ? 'addEvent' : 'removeEvent';
+      this.element[method]('click:relay(button, input[type=submit])', this.saveClickedButton.bind(this));
+
+      var fv = this.element.retrieve('validator');
+      if (fv) fv[method]('onFormValidate', this.onFormValidate);
+      else this.element[method]('submit', this.onSubmit);
+
+      return this;
+    },
+
+    detach: function(){
+      return this.attach(false);
+    },
+
+    //public method
+    enable: function(){
+      return this.attach();
+    },
+
+    //public method
+    disable: function(){
+      return this.detach();
+    },
+
+    onFormValidate: function(valid, form, event){
+      //if there's no event, then this wasn't a submit event
+      if (!event) return;
+      var fv = this.element.retrieve('validator');
+      if (valid || (fv && !fv.options.stopOnFailure)){
+        event.stop();
+        this.send();
+      }
+    },
+
+    onSubmit: function(event){
+      var fv = this.element.retrieve('validator');
+      if (fv){
+        //form validator was created after Form.Request
+        this.element.removeEvent('submit', this.onSubmit);
+        fv.addEvent('onFormValidate', this.onFormValidate);
+        fv.validate(event);
+        return;
+      }
+      if (event) event.stop();
+      this.send();
+    },
+
+    saveClickedButton: function(event, target){
+      var targetName = target.get('name');
+      if (!targetName || !this.options.sendButtonClicked) return;
+      this.options.extraData[targetName] = target.get('value') || true;
+      this.clickedCleaner = function(){
+        delete this.options.extraData[targetName];
+        this.clickedCleaner = function(){};
+      }.bind(this);
+    },
+
+    clickedCleaner: function(){},
+
+    send: function(){
+      var str = this.element.toQueryString().trim(),
+        data = Object.toQueryString(this.options.extraData);
+
+      if (str) str += "&" + data;
+      else str = data;
+
+      this.fireEvent('send', [this.element, str.parseQueryString()]);
+      this.request.send({
+        data: str,
+        url: this.options.requestOptions.url || this.element.get('action')
+      });
+      this.clickedCleaner();
+      return this;
+    }
+
+  });
+
+  Element.implement('formUpdate', function(update, options){
+    var fq = this.retrieve('form.request');
+    if (!fq){
+      fq = new Form.Request(this, update, options);
+    } else {
+      if (update) fq.setTarget(update);
+      if (options) fq.setOptions(options).makeRequest();
+    }
+    fq.send();
+    return this;
+  });
 
 })();
 
@@ -1647,55 +1647,55 @@ provides: [Element.Shortcuts]
 
 Element.implement({
 
-	isDisplayed: function(){
-		return this.getStyle('display') != 'none';
-	},
-
-	isVisible: function(){
-		var w = this.offsetWidth,
-			h = this.offsetHeight;
-		return (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : this.style.display != 'none';
-	},
-
-	toggle: function(){
-		return this[this.isDisplayed() ? 'hide' : 'show']();
-	},
-
-	hide: function(){
-		var d;
-		try {
-			//IE fails here if the element is not in the dom
-			d = this.getStyle('display');
-		} catch(e){}
-		if (d == 'none') return this;
-		return this.store('element:_originalDisplay', d || '').setStyle('display', 'none');
-	},
-
-	show: function(display){
-		if (!display && this.isDisplayed()) return this;
-		display = display || this.retrieve('element:_originalDisplay') || 'block';
-		return this.setStyle('display', (display == 'none') ? 'block' : display);
-	},
-
-	swapClass: function(remove, add){
-		return this.removeClass(remove).addClass(add);
-	}
+  isDisplayed: function(){
+    return this.getStyle('display') != 'none';
+  },
+
+  isVisible: function(){
+    var w = this.offsetWidth,
+      h = this.offsetHeight;
+    return (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : this.style.display != 'none';
+  },
+
+  toggle: function(){
+    return this[this.isDisplayed() ? 'hide' : 'show']();
+  },
+
+  hide: function(){
+    var d;
+    try {
+      //IE fails here if the element is not in the dom
+      d = this.getStyle('display');
+    } catch(e){}
+    if (d == 'none') return this;
+    return this.store('element:_originalDisplay', d || '').setStyle('display', 'none');
+  },
+
+  show: function(display){
+    if (!display && this.isDisplayed()) return this;
+    display = display || this.retrieve('element:_originalDisplay') || 'block';
+    return this.setStyle('display', (display == 'none') ? 'block' : display);
+  },
+
+  swapClass: function(remove, add){
+    return this.removeClass(remove).addClass(add);
+  }
 
 });
 
 Document.implement({
 
-	clearSelection: function(){
-		if (window.getSelection){
-			var selection = window.getSelection();
-			if (selection && selection.removeAllRanges) selection.removeAllRanges();
-		} else if (document.selection && document.selection.empty){
-			try {
-				//IE fails here if selected element is not in dom
-				document.selection.empty();
-			} catch(e){}
-		}
-	}
+  clearSelection: function(){
+    if (window.getSelection){
+      var selection = window.getSelection();
+      if (selection && selection.removeAllRanges) selection.removeAllRanges();
+    } else if (document.selection && document.selection.empty){
+      try {
+        //IE fails here if selected element is not in dom
+        document.selection.empty();
+      } catch(e){}
+    }
+  }
 
 });
 
@@ -1728,186 +1728,186 @@ provides: [Fx.Reveal]
 
 
 var hideTheseOf = function(object){
-	var hideThese = object.options.hideInputs;
-	if (window.OverText){
-		var otClasses = [null];
-		OverText.each(function(ot){
-			otClasses.include('.' + ot.options.labelClass);
-		});
-		if (otClasses) hideThese += otClasses.join(', ');
-	}
-	return (hideThese) ? object.element.getElements(hideThese) : null;
+  var hideThese = object.options.hideInputs;
+  if (window.OverText){
+    var otClasses = [null];
+    OverText.each(function(ot){
+      otClasses.include('.' + ot.options.labelClass);
+    });
+    if (otClasses) hideThese += otClasses.join(', ');
+  }
+  return (hideThese) ? object.element.getElements(hideThese) : null;
 };
 
 
 Fx.Reveal = new Class({
 
-	Extends: Fx.Morph,
-
-	options: {/*
-		onShow: function(thisElement){},
-		onHide: function(thisElement){},
-		onComplete: function(thisElement){},
-		heightOverride: null,
-		widthOverride: null,*/
-		link: 'cancel',
-		styles: ['padding', 'border', 'margin'],
-		transitionOpacity: 'opacity' in document.documentElement,
-		mode: 'vertical',
-		display: function(){
-			return this.element.get('tag') != 'tr' ? 'block' : 'table-row';
-		},
-		opacity: 1,
-		hideInputs: !('opacity' in document.documentElement) ? 'select, input, textarea, object, embed' : null
-	},
-
-	dissolve: function(){
-		if (!this.hiding && !this.showing){
-			if (this.element.getStyle('display') != 'none'){
-				this.hiding = true;
-				this.showing = false;
-				this.hidden = true;
-				this.cssText = this.element.style.cssText;
-
-				var startStyles = this.element.getComputedSize({
-					styles: this.options.styles,
-					mode: this.options.mode
-				});
-				if (this.options.transitionOpacity) startStyles.opacity = this.options.opacity;
-
-				var zero = {};
-				Object.each(startStyles, function(style, name){
-					zero[name] = [style, 0];
-				});
-
-				this.element.setStyles({
-					display: Function.from(this.options.display).call(this),
-					overflow: 'hidden'
-				});
-
-				var hideThese = hideTheseOf(this);
-				if (hideThese) hideThese.setStyle('visibility', 'hidden');
-
-				this.$chain.unshift(function(){
-					if (this.hidden){
-						this.hiding = false;
-						this.element.style.cssText = this.cssText;
-						this.element.setStyle('display', 'none');
-						if (hideThese) hideThese.setStyle('visibility', 'visible');
-					}
-					this.fireEvent('hide', this.element);
-					this.callChain();
-				}.bind(this));
-
-				this.start(zero);
-			} else {
-				this.callChain.delay(10, this);
-				this.fireEvent('complete', this.element);
-				this.fireEvent('hide', this.element);
-			}
-		} else if (this.options.link == 'chain'){
-			this.chain(this.dissolve.bind(this));
-		} else if (this.options.link == 'cancel' && !this.hiding){
-			this.cancel();
-			this.dissolve();
-		}
-		return this;
-	},
-
-	reveal: function(){
-		if (!this.showing && !this.hiding){
-			if (this.element.getStyle('display') == 'none'){
-				this.hiding = false;
-				this.showing = true;
-				this.hidden = false;
-				this.cssText = this.element.style.cssText;
-
-				var startStyles;
-				this.element.measure(function(){
-					startStyles = this.element.getComputedSize({
-						styles: this.options.styles,
-						mode: this.options.mode
-					});
-				}.bind(this));
-				if (this.options.heightOverride != null) startStyles.height = this.options.heightOverride.toInt();
-				if (this.options.widthOverride != null) startStyles.width = this.options.widthOverride.toInt();
-				if (this.options.transitionOpacity){
-					this.element.setStyle('opacity', 0);
-					startStyles.opacity = this.options.opacity;
-				}
-
-				var zero = {
-					height: 0,
-					display: Function.from(this.options.display).call(this)
-				};
-				Object.each(startStyles, function(style, name){
-					zero[name] = 0;
-				});
-				zero.overflow = 'hidden';
-
-				this.element.setStyles(zero);
-
-				var hideThese = hideTheseOf(this);
-				if (hideThese) hideThese.setStyle('visibility', 'hidden');
-
-				this.$chain.unshift(function(){
-					this.element.style.cssText = this.cssText;
-					this.element.setStyle('display', Function.from(this.options.display).call(this));
-					if (!this.hidden) this.showing = false;
-					if (hideThese) hideThese.setStyle('visibility', 'visible');
-					this.callChain();
-					this.fireEvent('show', this.element);
-				}.bind(this));
-
-				this.start(startStyles);
-			} else {
-				this.callChain();
-				this.fireEvent('complete', this.element);
-				this.fireEvent('show', this.element);
-			}
-		} else if (this.options.link == 'chain'){
-			this.chain(this.reveal.bind(this));
-		} else if (this.options.link == 'cancel' && !this.showing){
-			this.cancel();
-			this.reveal();
-		}
-		return this;
-	},
-
-	toggle: function(){
-		if (this.element.getStyle('display') == 'none'){
-			this.reveal();
-		} else {
-			this.dissolve();
-		}
-		return this;
-	},
-
-	cancel: function(){
-		this.parent.apply(this, arguments);
-		if (this.cssText != null) this.element.style.cssText = this.cssText;
-		this.hiding = false;
-		this.showing = false;
-		return this;
-	}
+  Extends: Fx.Morph,
+
+  options: {/*
+    onShow: function(thisElement){},
+    onHide: function(thisElement){},
+    onComplete: function(thisElement){},
+    heightOverride: null,
+    widthOverride: null,*/
+    link: 'cancel',
+    styles: ['padding', 'border', 'margin'],
+    transitionOpacity: 'opacity' in document.documentElement,
+    mode: 'vertical',
+    display: function(){
+      return this.element.get('tag') != 'tr' ? 'block' : 'table-row';
+    },
+    opacity: 1,
+    hideInputs: !('opacity' in document.documentElement) ? 'select, input, textarea, object, embed' : null
+  },
+
+  dissolve: function(){
+    if (!this.hiding && !this.showing){
+      if (this.element.getStyle('display') != 'none'){
+        this.hiding = true;
+        this.showing = false;
+        this.hidden = true;
+        this.cssText = this.element.style.cssText;
+
+        var startStyles = this.element.getComputedSize({
+          styles: this.options.styles,
+          mode: this.options.mode
+        });
+        if (this.options.transitionOpacity) startStyles.opacity = this.options.opacity;
+
+        var zero = {};
+        Object.each(startStyles, function(style, name){
+          zero[name] = [style, 0];
+        });
+
+        this.element.setStyles({
+          display: Function.from(this.options.display).call(this),
+          overflow: 'hidden'
+        });
+
+        var hideThese = hideTheseOf(this);
+        if (hideThese) hideThese.setStyle('visibility', 'hidden');
+
+        this.$chain.unshift(function(){
+          if (this.hidden){
+            this.hiding = false;
+            this.element.style.cssText = this.cssText;
+            this.element.setStyle('display', 'none');
+            if (hideThese) hideThese.setStyle('visibility', 'visible');
+          }
+          this.fireEvent('hide', this.element);
+          this.callChain();
+        }.bind(this));
+
+        this.start(zero);
+      } else {
+        this.callChain.delay(10, this);
+        this.fireEvent('complete', this.element);
+        this.fireEvent('hide', this.element);
+      }
+    } else if (this.options.link == 'chain'){
+      this.chain(this.dissolve.bind(this));
+    } else if (this.options.link == 'cancel' && !this.hiding){
+      this.cancel();
+      this.dissolve();
+    }
+    return this;
+  },
+
+  reveal: function(){
+    if (!this.showing && !this.hiding){
+      if (this.element.getStyle('display') == 'none'){
+        this.hiding = false;
+        this.showing = true;
+        this.hidden = false;
+        this.cssText = this.element.style.cssText;
+
+        var startStyles;
+        this.element.measure(function(){
+          startStyles = this.element.getComputedSize({
+            styles: this.options.styles,
+            mode: this.options.mode
+          });
+        }.bind(this));
+        if (this.options.heightOverride != null) startStyles.height = this.options.heightOverride.toInt();
+        if (this.options.widthOverride != null) startStyles.width = this.options.widthOverride.toInt();
+        if (this.options.transitionOpacity){
+          this.element.setStyle('opacity', 0);
+          startStyles.opacity = this.options.opacity;
+        }
+
+        var zero = {
+          height: 0,
+          display: Function.from(this.options.display).call(this)
+        };
+        Object.each(startStyles, function(style, name){
+          zero[name] = 0;
+        });
+        zero.overflow = 'hidden';
+
+        this.element.setStyles(zero);
+
+        var hideThese = hideTheseOf(this);
+        if (hideThese) hideThese.setStyle('visibility', 'hidden');
+
+        this.$chain.unshift(function(){
+          this.element.style.cssText = this.cssText;
+          this.element.setStyle('display', Function.from(this.options.display).call(this));
+          if (!this.hidden) this.showing = false;
+          if (hideThese) hideThese.setStyle('visibility', 'visible');
+          this.callChain();
+          this.fireEvent('show', this.element);
+        }.bind(this));
+
+        this.start(startStyles);
+      } else {
+        this.callChain();
+        this.fireEvent('complete', this.element);
+        this.fireEvent('show', this.element);
+      }
+    } else if (this.options.link == 'chain'){
+      this.chain(this.reveal.bind(this));
+    } else if (this.options.link == 'cancel' && !this.showing){
+      this.cancel();
+      this.reveal();
+    }
+    return this;
+  },
+
+  toggle: function(){
+    if (this.element.getStyle('display') == 'none'){
+      this.reveal();
+    } else {
+      this.dissolve();
+    }
+    return this;
+  },
+
+  cancel: function(){
+    this.parent.apply(this, arguments);
+    if (this.cssText != null) this.element.style.cssText = this.cssText;
+    this.hiding = false;
+    this.showing = false;
+    return this;
+  }
 
 });
 
 Element.Properties.reveal = {
 
-	set: function(options){
-		this.get('reveal').cancel().setOptions(options);
-		return this;
-	},
+  set: function(options){
+    this.get('reveal').cancel().setOptions(options);
+    return this;
+  },
 
-	get: function(){
-		var reveal = this.retrieve('reveal');
-		if (!reveal){
-			reveal = new Fx.Reveal(this);
-			this.store('reveal', reveal);
-		}
-		return reveal;
-	}
+  get: function(){
+    var reveal = this.retrieve('reveal');
+    if (!reveal){
+      reveal = new Fx.Reveal(this);
+      this.store('reveal', reveal);
+    }
+    return reveal;
+  }
 
 };
 
@@ -1915,33 +1915,33 @@ Element.Properties.dissolve = Element.Properties.reveal;
 
 Element.implement({
 
-	reveal: function(options){
-		this.get('reveal').setOptions(options).reveal();
-		return this;
-	},
-
-	dissolve: function(options){
-		this.get('reveal').setOptions(options).dissolve();
-		return this;
-	},
-
-	nix: function(options){
-		var params = Array.link(arguments, {destroy: Type.isBoolean, options: Type.isObject});
-		this.get('reveal').setOptions(options).dissolve().chain(function(){
-			this[params.destroy ? 'destroy' : 'dispose']();
-		}.bind(this));
-		return this;
-	},
-
-	wink: function(){
-		var params = Array.link(arguments, {duration: Type.isNumber, options: Type.isObject});
-		var reveal = this.get('reveal').setOptions(params.options);
-		reveal.reveal().chain(function(){
-			(function(){
-				reveal.dissolve();
-			}).delay(params.duration || 2000);
-		});
-	}
+  reveal: function(options){
+    this.get('reveal').setOptions(options).reveal();
+    return this;
+  },
+
+  dissolve: function(options){
+    this.get('reveal').setOptions(options).dissolve();
+    return this;
+  },
+
+  nix: function(options){
+    var params = Array.link(arguments, {destroy: Type.isBoolean, options: Type.isObject});
+    this.get('reveal').setOptions(options).dissolve().chain(function(){
+      this[params.destroy ? 'destroy' : 'dispose']();
+    }.bind(this));
+    return this;
+  },
+
+  wink: function(){
+    var params = Array.link(arguments, {duration: Type.isNumber, options: Type.isObject});
+    var reveal = this.get('reveal').setOptions(params.options);
+    reveal.reveal().chain(function(){
+      (function(){
+        reveal.dissolve();
+      }).delay(params.duration || 2000);
+    });
+  }
 
 });
 
@@ -1979,207 +1979,207 @@ provides: [Drag]
 
 var Drag = new Class({
 
-	Implements: [Events, Options],
-
-	options: {/*
-		onBeforeStart: function(thisElement){},
-		onStart: function(thisElement, event){},
-		onSnap: function(thisElement){},
-		onDrag: function(thisElement, event){},
-		onCancel: function(thisElement){},
-		onComplete: function(thisElement, event){},*/
-		snap: 6,
-		unit: 'px',
-		grid: false,
-		style: true,
-		limit: false,
-		handle: false,
-		invert: false,
-		preventDefault: false,
-		stopPropagation: false,
-		modifiers: {x: 'left', y: 'top'}
-	},
-
-	initialize: function(){
-		var params = Array.link(arguments, {
-			'options': Type.isObject,
-			'element': function(obj){
-				return obj != null;
-			}
-		});
-
-		this.element = document.id(params.element);
-		this.document = this.element.getDocument();
-		this.setOptions(params.options || {});
-		var htype = typeOf(this.options.handle);
-		this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
-		this.mouse = {'now': {}, 'pos': {}};
-		this.value = {'start': {}, 'now': {}};
-
-		this.selection = 'selectstart' in document ? 'selectstart' : 'mousedown';
-
-
-		if ('ondragstart' in document && !('FileReader' in window) && !Drag.ondragstartFixed){
-			document.ondragstart = Function.from(false);
-			Drag.ondragstartFixed = true;
-		}
-
-		this.bound = {
-			start: this.start.bind(this),
-			check: this.check.bind(this),
-			drag: this.drag.bind(this),
-			stop: this.stop.bind(this),
-			cancel: this.cancel.bind(this),
-			eventStop: Function.from(false)
-		};
-		this.attach();
-	},
-
-	attach: function(){
-		this.handles.addEvent('mousedown', this.bound.start);
-		return this;
-	},
-
-	detach: function(){
-		this.handles.removeEvent('mousedown', this.bound.start);
-		return this;
-	},
-
-	start: function(event){
-		var options = this.options;
-
-		if (event.rightClick) return;
-
-		if (options.preventDefault) event.preventDefault();
-		if (options.stopPropagation) event.stopPropagation();
-		this.mouse.start = event.page;
-
-		this.fireEvent('beforeStart', this.element);
-
-		var limit = options.limit;
-		this.limit = {x: [], y: []};
-
-		var z, coordinates;
-		for (z in options.modifiers){
-			if (!options.modifiers[z]) continue;
-
-			var style = this.element.getStyle(options.modifiers[z]);
-
-			// Some browsers (IE and Opera) don't always return pixels.
-			if (style && !style.match(/px$/)){
-				if (!coordinates) coordinates = this.element.getCoordinates(this.element.getOffsetParent());
-				style = coordinates[options.modifiers[z]];
-			}
-
-			if (options.style) this.value.now[z] = (style || 0).toInt();
-			else this.value.now[z] = this.element[options.modifiers[z]];
-
-			if (options.invert) this.value.now[z] *= -1;
-
-			this.mouse.pos[z] = event.page[z] - this.value.now[z];
-
-			if (limit && limit[z]){
-				var i = 2;
-				while (i--){
-					var limitZI = limit[z][i];
-					if (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI;
-				}
-			}
-		}
-
-		if (typeOf(this.options.grid) == 'number') this.options.grid = {
-			x: this.options.grid,
-			y: this.options.grid
-		};
-
-		var events = {
-			mousemove: this.bound.check,
-			mouseup: this.bound.cancel
-		};
-		events[this.selection] = this.bound.eventStop;
-		this.document.addEvents(events);
-	},
-
-	check: function(event){
-		if (this.options.preventDefault) event.preventDefault();
-		var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
-		if (distance > this.options.snap){
-			this.cancel();
-			this.document.addEvents({
-				mousemove: this.bound.drag,
-				mouseup: this.bound.stop
-			});
-			this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
-		}
-	},
-
-	drag: function(event){
-		var options = this.options;
-
-		if (options.preventDefault) event.preventDefault();
-		this.mouse.now = event.page;
-
-		for (var z in options.modifiers){
-			if (!options.modifiers[z]) continue;
-			this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
-
-			if (options.invert) this.value.now[z] *= -1;
-
-			if (options.limit && this.limit[z]){
-				if ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){
-					this.value.now[z] = this.limit[z][1];
-				} else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){
-					this.value.now[z] = this.limit[z][0];
-				}
-			}
-
-			if (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]);
-
-			if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit);
-			else this.element[options.modifiers[z]] = this.value.now[z];
-		}
-
-		this.fireEvent('drag', [this.element, event]);
-	},
-
-	cancel: function(event){
-		this.document.removeEvents({
-			mousemove: this.bound.check,
-			mouseup: this.bound.cancel
-		});
-		if (event){
-			this.document.removeEvent(this.selection, this.bound.eventStop);
-			this.fireEvent('cancel', this.element);
-		}
-	},
-
-	stop: function(event){
-		var events = {
-			mousemove: this.bound.drag,
-			mouseup: this.bound.stop
-		};
-		events[this.selection] = this.bound.eventStop;
-		this.document.removeEvents(events);
-		if (event) this.fireEvent('complete', [this.element, event]);
-	}
+  Implements: [Events, Options],
+
+  options: {/*
+    onBeforeStart: function(thisElement){},
+    onStart: function(thisElement, event){},
+    onSnap: function(thisElement){},
+    onDrag: function(thisElement, event){},
+    onCancel: function(thisElement){},
+    onComplete: function(thisElement, event){},*/
+    snap: 6,
+    unit: 'px',
+    grid: false,
+    style: true,
+    limit: false,
+    handle: false,
+    invert: false,
+    preventDefault: false,
+    stopPropagation: false,
+    modifiers: {x: 'left', y: 'top'}
+  },
+
+  initialize: function(){
+    var params = Array.link(arguments, {
+      'options': Type.isObject,
+      'element': function(obj){
+        return obj != null;
+      }
+    });
+
+    this.element = document.id(params.element);
+    this.document = this.element.getDocument();
+    this.setOptions(params.options || {});
+    var htype = typeOf(this.options.handle);
+    this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element;
+    this.mouse = {'now': {}, 'pos': {}};
+    this.value = {'start': {}, 'now': {}};
+
+    this.selection = 'selectstart' in document ? 'selectstart' : 'mousedown';
+
+
+    if ('ondragstart' in document && !('FileReader' in window) && !Drag.ondragstartFixed){
+      document.ondragstart = Function.from(false);
+      Drag.ondragstartFixed = true;
+    }
+
+    this.bound = {
+      start: this.start.bind(this),
+      check: this.check.bind(this),
+      drag: this.drag.bind(this),
+      stop: this.stop.bind(this),
+      cancel: this.cancel.bind(this),
+      eventStop: Function.from(false)
+    };
+    this.attach();
+  },
+
+  attach: function(){
+    this.handles.addEvent('mousedown', this.bound.start);
+    return this;
+  },
+
+  detach: function(){
+    this.handles.removeEvent('mousedown', this.bound.start);
+    return this;
+  },
+
+  start: function(event){
+    var options = this.options;
+
+    if (event.rightClick) return;
+
+    if (options.preventDefault) event.preventDefault();
+    if (options.stopPropagation) event.stopPropagation();
+    this.mouse.start = event.page;
+
+    this.fireEvent('beforeStart', this.element);
+
+    var limit = options.limit;
+    this.limit = {x: [], y: []};
+
+    var z, coordinates;
+    for (z in options.modifiers){
+      if (!options.modifiers[z]) continue;
+
+      var style = this.element.getStyle(options.modifiers[z]);
+
+      // Some browsers (IE and Opera) don't always return pixels.
+      if (style && !style.match(/px$/)){
+        if (!coordinates) coordinates = this.element.getCoordinates(this.element.getOffsetParent());
+        style = coordinates[options.modifiers[z]];
+      }
+
+      if (options.style) this.value.now[z] = (style || 0).toInt();
+      else this.value.now[z] = this.element[options.modifiers[z]];
+
+      if (options.invert) this.value.now[z] *= -1;
+
+      this.mouse.pos[z] = event.page[z] - this.value.now[z];
+
+      if (limit && limit[z]){
+        var i = 2;
+        while (i--){
+          var limitZI = limit[z][i];
+          if (limitZI || limitZI === 0) this.limit[z][i] = (typeof limitZI == 'function') ? limitZI() : limitZI;
+        }
+      }
+    }
+
+    if (typeOf(this.options.grid) == 'number') this.options.grid = {
+      x: this.options.grid,
+      y: this.options.grid
+    };
+
+    var events = {
+      mousemove: this.bound.check,
+      mouseup: this.bound.cancel
+    };
+    events[this.selection] = this.bound.eventStop;
+    this.document.addEvents(events);
+  },
+
+  check: function(event){
+    if (this.options.preventDefault) event.preventDefault();
+    var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
+    if (distance > this.options.snap){
+      this.cancel();
+      this.document.addEvents({
+        mousemove: this.bound.drag,
+        mouseup: this.bound.stop
+      });
+      this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element);
+    }
+  },
+
+  drag: function(event){
+    var options = this.options;
+
+    if (options.preventDefault) event.preventDefault();
+    this.mouse.now = event.page;
+
+    for (var z in options.modifiers){
+      if (!options.modifiers[z]) continue;
+      this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
+
+      if (options.invert) this.value.now[z] *= -1;
+
+      if (options.limit && this.limit[z]){
+        if ((this.limit[z][1] || this.limit[z][1] === 0) && (this.value.now[z] > this.limit[z][1])){
+          this.value.now[z] = this.limit[z][1];
+        } else if ((this.limit[z][0] || this.limit[z][0] === 0) && (this.value.now[z] < this.limit[z][0])){
+          this.value.now[z] = this.limit[z][0];
+        }
+      }
+
+      if (options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % options.grid[z]);
+
+      if (options.style) this.element.setStyle(options.modifiers[z], this.value.now[z] + options.unit);
+      else this.element[options.modifiers[z]] = this.value.now[z];
+    }
+
+    this.fireEvent('drag', [this.element, event]);
+  },
+
+  cancel: function(event){
+    this.document.removeEvents({
+      mousemove: this.bound.check,
+      mouseup: this.bound.cancel
+    });
+    if (event){
+      this.document.removeEvent(this.selection, this.bound.eventStop);
+      this.fireEvent('cancel', this.element);
+    }
+  },
+
+  stop: function(event){
+    var events = {
+      mousemove: this.bound.drag,
+      mouseup: this.bound.stop
+    };
+    events[this.selection] = this.bound.eventStop;
+    this.document.removeEvents(events);
+    if (event) this.fireEvent('complete', [this.element, event]);
+  }
 
 });
 
 Element.implement({
 
-	makeResizable: function(options){
-		var drag = new Drag(this, Object.merge({
-			modifiers: {
-				x: 'width',
-				y: 'height'
-			}
-		}, options));
+  makeResizable: function(options){
+    var drag = new Drag(this, Object.merge({
+      modifiers: {
+        x: 'width',
+        y: 'height'
+      }
+    }, options));
 
-		this.store('resizer', drag);
-		return drag.addEvent('drag', function(){
-			this.fireEvent('resize', drag);
-		}.bind(this));
-	}
+    this.store('resizer', drag);
+    return drag.addEvent('drag', function(){
+      this.fireEvent('resize', drag);
+    }.bind(this));
+  }
 
 });
 
@@ -2213,178 +2213,178 @@ provides: [Drag.Move]
 
 Drag.Move = new Class({
 
-	Extends: Drag,
-
-	options: {/*
-		onEnter: function(thisElement, overed){},
-		onLeave: function(thisElement, overed){},
-		onDrop: function(thisElement, overed, event){},*/
-		droppables: [],
-		container: false,
-		precalculate: false,
-		includeMargins: true,
-		checkDroppables: true
-	},
-
-	initialize: function(element, options){
-		this.parent(element, options);
-		element = this.element;
-
-		this.droppables = $$(this.options.droppables);
-		this.setContainer(this.options.container);
-
-		if (this.options.style){
-			if (this.options.modifiers.x == 'left' && this.options.modifiers.y == 'top'){
-				var parent = element.getOffsetParent(),
-					styles = element.getStyles('left', 'top');
-				if (parent && (styles.left == 'auto' || styles.top == 'auto')){
-					element.setPosition(element.getPosition(parent));
-				}
-			}
-
-			if (element.getStyle('position') == 'static') element.setStyle('position', 'absolute');
-		}
-
-		this.addEvent('start', this.checkDroppables, true);
-		this.overed = null;
-	},
-	
-	setContainer: function(container) {
-		this.container = document.id(container);
-		if (this.container && typeOf(this.container) != 'element'){
-			this.container = document.id(this.container.getDocument().body);
-		}
-	},
-
-	start: function(event){
-		if (this.container) this.options.limit = this.calculateLimit();
-
-		if (this.options.precalculate){
-			this.positions = this.droppables.map(function(el){
-				return el.getCoordinates();
-			});
-		}
-
-		this.parent(event);
-	},
-
-	calculateLimit: function(){
-		var element = this.element,
-			container = this.container,
-
-			offsetParent = document.id(element.getOffsetParent()) || document.body,
-			containerCoordinates = container.getCoordinates(offsetParent),
-			elementMargin = {},
-			elementBorder = {},
-			containerMargin = {},
-			containerBorder = {},
-			offsetParentPadding = {};
-
-		['top', 'right', 'bottom', 'left'].each(function(pad){
-			elementMargin[pad] = element.getStyle('margin-' + pad).toInt();
-			elementBorder[pad] = element.getStyle('border-' + pad).toInt();
-			containerMargin[pad] = container.getStyle('margin-' + pad).toInt();
-			containerBorder[pad] = container.getStyle('border-' + pad).toInt();
-			offsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt();
-		}, this);
-
-		var width = element.offsetWidth + elementMargin.left + elementMargin.right,
-			height = element.offsetHeight + elementMargin.top + elementMargin.bottom,
-			left = 0,
-			top = 0,
-			right = containerCoordinates.right - containerBorder.right - width,
-			bottom = containerCoordinates.bottom - containerBorder.bottom - height;
-
-		if (this.options.includeMargins){
-			left += elementMargin.left;
-			top += elementMargin.top;
-		} else {
-			right += elementMargin.right;
-			bottom += elementMargin.bottom;
-		}
-
-		if (element.getStyle('position') == 'relative'){
-			var coords = element.getCoordinates(offsetParent);
-			coords.left -= element.getStyle('left').toInt();
-			coords.top -= element.getStyle('top').toInt();
-
-			left -= coords.left;
-			top -= coords.top;
-			if (container.getStyle('position') != 'relative'){
-				left += containerBorder.left;
-				top += containerBorder.top;
-			}
-			right += elementMargin.left - coords.left;
-			bottom += elementMargin.top - coords.top;
-
-			if (container != offsetParent){
-				left += containerMargin.left + offsetParentPadding.left;
-				if (!offsetParentPadding.left && left < 0) left = 0;
-				top += offsetParent == document.body ? 0 : containerMargin.top + offsetParentPadding.top;
-				if (!offsetParentPadding.top && top < 0) top = 0;
-			}
-		} else {
-			left -= elementMargin.left;
-			top -= elementMargin.top;
-			if (container != offsetParent){
-				left += containerCoordinates.left + containerBorder.left;
-				top += containerCoordinates.top + containerBorder.top;
-			}
-		}
-
-		return {
-			x: [left, right],
-			y: [top, bottom]
-		};
-	},
-
-	getDroppableCoordinates: function(element){
-		var position = element.getCoordinates();
-		if (element.getStyle('position') == 'fixed'){
-			var scroll = window.getScroll();
-			position.left += scroll.x;
-			position.right += scroll.x;
-			position.top += scroll.y;
-			position.bottom += scroll.y;
-		}
-		return position;
-	},
-
-	checkDroppables: function(){
-		var overed = this.droppables.filter(function(el, i){
-			el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);
-			var now = this.mouse.now;
-			return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
-		}, this).getLast();
-
-		if (this.overed != overed){
-			if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
-			if (overed) this.fireEvent('enter', [this.element, overed]);
-			this.overed = overed;
-		}
-	},
-
-	drag: function(event){
-		this.parent(event);
-		if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
-	},
-
-	stop: function(event){
-		this.checkDroppables();
-		this.fireEvent('drop', [this.element, this.overed, event]);
-		this.overed = null;
-		return this.parent(event);
-	}
+  Extends: Drag,
+
+  options: {/*
+    onEnter: function(thisElement, overed){},
+    onLeave: function(thisElement, overed){},
+    onDrop: function(thisElement, overed, event){},*/
+    droppables: [],
+    container: false,
+    precalculate: false,
+    includeMargins: true,
+    checkDroppables: true
+  },
+
+  initialize: function(element, options){
+    this.parent(element, options);
+    element = this.element;
+
+    this.droppables = $$(this.options.droppables);
+    this.setContainer(this.options.container);
+
+    if (this.options.style){
+      if (this.options.modifiers.x == 'left' && this.options.modifiers.y == 'top'){
+        var parent = element.getOffsetParent(),
+          styles = element.getStyles('left', 'top');
+        if (parent && (styles.left == 'auto' || styles.top == 'auto')){
+          element.setPosition(element.getPosition(parent));
+        }
+      }
+
+      if (element.getStyle('position') == 'static') element.setStyle('position', 'absolute');
+    }
+
+    this.addEvent('start', this.checkDroppables, true);
+    this.overed = null;
+  },
+  
+  setContainer: function(container) {
+    this.container = document.id(container);
+    if (this.container && typeOf(this.container) != 'element'){
+      this.container = document.id(this.container.getDocument().body);
+    }
+  },
+
+  start: function(event){
+    if (this.container) this.options.limit = this.calculateLimit();
+
+    if (this.options.precalculate){
+      this.positions = this.droppables.map(function(el){
+        return el.getCoordinates();
+      });
+    }
+
+    this.parent(event);
+  },
+
+  calculateLimit: function(){
+    var element = this.element,
+      container = this.container,
+
+      offsetParent = document.id(element.getOffsetParent()) || document.body,
+      containerCoordinates = container.getCoordinates(offsetParent),
+      elementMargin = {},
+      elementBorder = {},
+      containerMargin = {},
+      containerBorder = {},
+      offsetParentPadding = {};
+
+    ['top', 'right', 'bottom', 'left'].each(function(pad){
+      elementMargin[pad] = element.getStyle('margin-' + pad).toInt();
+      elementBorder[pad] = element.getStyle('border-' + pad).toInt();
+      containerMargin[pad] = container.getStyle('margin-' + pad).toInt();
+      containerBorder[pad] = container.getStyle('border-' + pad).toInt();
+      offsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt();
+    }, this);
+
+    var width = element.offsetWidth + elementMargin.left + elementMargin.right,
+      height = element.offsetHeight + elementMargin.top + elementMargin.bottom,
+      left = 0,
+      top = 0,
+      right = containerCoordinates.right - containerBorder.right - width,
+      bottom = containerCoordinates.bottom - containerBorder.bottom - height;
+
+    if (this.options.includeMargins){
+      left += elementMargin.left;
+      top += elementMargin.top;
+    } else {
+      right += elementMargin.right;
+      bottom += elementMargin.bottom;
+    }
+
+    if (element.getStyle('position') == 'relative'){
+      var coords = element.getCoordinates(offsetParent);
+      coords.left -= element.getStyle('left').toInt();
+      coords.top -= element.getStyle('top').toInt();
+
+      left -= coords.left;
+      top -= coords.top;
+      if (container.getStyle('position') != 'relative'){
+        left += containerBorder.left;
+        top += containerBorder.top;
+      }
+      right += elementMargin.left - coords.left;
+      bottom += elementMargin.top - coords.top;
+
+      if (container != offsetParent){
+        left += containerMargin.left + offsetParentPadding.left;
+        if (!offsetParentPadding.left && left < 0) left = 0;
+        top += offsetParent == document.body ? 0 : containerMargin.top + offsetParentPadding.top;
+        if (!offsetParentPadding.top && top < 0) top = 0;
+      }
+    } else {
+      left -= elementMargin.left;
+      top -= elementMargin.top;
+      if (container != offsetParent){
+        left += containerCoordinates.left + containerBorder.left;
+        top += containerCoordinates.top + containerBorder.top;
+      }
+    }
+
+    return {
+      x: [left, right],
+      y: [top, bottom]
+    };
+  },
+
+  getDroppableCoordinates: function(element){
+    var position = element.getCoordinates();
+    if (element.getStyle('position') == 'fixed'){
+      var scroll = window.getScroll();
+      position.left += scroll.x;
+      position.right += scroll.x;
+      position.top += scroll.y;
+      position.bottom += scroll.y;
+    }
+    return position;
+  },
+
+  checkDroppables: function(){
+    var overed = this.droppables.filter(function(el, i){
+      el = this.positions ? this.positions[i] : this.getDroppableCoordinates(el);
+      var now = this.mouse.now;
+      return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
+    }, this).getLast();
+
+    if (this.overed != overed){
+      if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
+      if (overed) this.fireEvent('enter', [this.element, overed]);
+      this.overed = overed;
+    }
+  },
+
+  drag: function(event){
+    this.parent(event);
+    if (this.options.checkDroppables && this.droppables.length) this.checkDroppables();
+  },
+
+  stop: function(event){
+    this.checkDroppables();
+    this.fireEvent('drop', [this.element, this.overed, event]);
+    this.overed = null;
+    return this.parent(event);
+  }
 
 });
 
 Element.implement({
 
-	makeDraggable: function(options){
-		var drag = new Drag.Move(this, options);
-		this.store('dragger', drag);
-		return drag;
-	}
+  makeDraggable: function(options){
+    var drag = new Drag.Move(this, options);
+    this.store('dragger', drag);
+    return drag;
+  }
 
 });
 
@@ -2414,226 +2414,226 @@ provides: [Sortables]
 
 var Sortables = new Class({
 
-	Implements: [Events, Options],
-
-	options: {/*
-		onSort: function(element, clone){},
-		onStart: function(element, clone){},
-		onComplete: function(element){},*/
-		opacity: 1,
-		clone: false,
-		revert: false,
-		handle: false,
-		dragOptions: {},
-		unDraggableTags: ['button', 'input', 'a', 'textarea', 'select', 'option']
-	},
-
-	initialize: function(lists, options){
-		this.setOptions(options);
-
-		this.elements = [];
-		this.lists = [];
-		this.idle = true;
-
-		this.addLists($$(document.id(lists) || lists));
-
-		if (!this.options.clone) this.options.revert = false;
-		if (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({
-			duration: 250,
-			link: 'cancel'
-		}, this.options.revert));
-	},
-
-	attach: function(){
-		this.addLists(this.lists);
-		return this;
-	},
-
-	detach: function(){
-		this.lists = this.removeLists(this.lists);
-		return this;
-	},
-
-	addItems: function(){
-		Array.flatten(arguments).each(function(element){
-			this.elements.push(element);
-			var start = element.retrieve('sortables:start', function(event){
-				this.start.call(this, event, element);
-			}.bind(this));
-			(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
-		}, this);
-		return this;
-	},
-
-	addLists: function(){
-		Array.flatten(arguments).each(function(list){
-			this.lists.include(list);
-			this.addItems(list.getChildren());
-		}, this);
-		return this;
-	},
-
-	removeItems: function(){
-		return $$(Array.flatten(arguments).map(function(element){
-			this.elements.erase(element);
-			var start = element.retrieve('sortables:start');
-			(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
-
-			return element;
-		}, this));
-	},
-
-	removeLists: function(){
-		return $$(Array.flatten(arguments).map(function(list){
-			this.lists.erase(list);
-			this.removeItems(list.getChildren());
-
-			return list;
-		}, this));
-	},
-
-	getDroppableCoordinates: function (element){
-		var offsetParent = element.getOffsetParent();
-		var position = element.getPosition(offsetParent);
-		var scroll = {
-			w: window.getScroll(),
-			offsetParent: offsetParent.getScroll()
-		};
-		position.x += scroll.offsetParent.x;
-		position.y += scroll.offsetParent.y;
-
-		if (offsetParent.getStyle('position') == 'fixed'){
-			position.x -= scroll.w.x;
-			position.y -= scroll.w.y;
-		}
+  Implements: [Events, Options],
+
+  options: {/*
+    onSort: function(element, clone){},
+    onStart: function(element, clone){},
+    onComplete: function(element){},*/
+    opacity: 1,
+    clone: false,
+    revert: false,
+    handle: false,
+    dragOptions: {},
+    unDraggableTags: ['button', 'input', 'a', 'textarea', 'select', 'option']
+  },
+
+  initialize: function(lists, options){
+    this.setOptions(options);
+
+    this.elements = [];
+    this.lists = [];
+    this.idle = true;
+
+    this.addLists($$(document.id(lists) || lists));
+
+    if (!this.options.clone) this.options.revert = false;
+    if (this.options.revert) this.effect = new Fx.Morph(null, Object.merge({
+      duration: 250,
+      link: 'cancel'
+    }, this.options.revert));
+  },
+
+  attach: function(){
+    this.addLists(this.lists);
+    return this;
+  },
+
+  detach: function(){
+    this.lists = this.removeLists(this.lists);
+    return this;
+  },
+
+  addItems: function(){
+    Array.flatten(arguments).each(function(element){
+      this.elements.push(element);
+      var start = element.retrieve('sortables:start', function(event){
+        this.start.call(this, event, element);
+      }.bind(this));
+      (this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
+    }, this);
+    return this;
+  },
+
+  addLists: function(){
+    Array.flatten(arguments).each(function(list){
+      this.lists.include(list);
+      this.addItems(list.getChildren());
+    }, this);
+    return this;
+  },
+
+  removeItems: function(){
+    return $$(Array.flatten(arguments).map(function(element){
+      this.elements.erase(element);
+      var start = element.retrieve('sortables:start');
+      (this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
+
+      return element;
+    }, this));
+  },
+
+  removeLists: function(){
+    return $$(Array.flatten(arguments).map(function(list){
+      this.lists.erase(list);
+      this.removeItems(list.getChildren());
+
+      return list;
+    }, this));
+  },
+
+  getDroppableCoordinates: function (element){
+    var offsetParent = element.getOffsetParent();
+    var position = element.getPosition(offsetParent);
+    var scroll = {
+      w: window.getScroll(),
+      offsetParent: offsetParent.getScroll()
+    };
+    position.x += scroll.offsetParent.x;
+    position.y += scroll.offsetParent.y;
+
+    if (offsetParent.getStyle('position') == 'fixed'){
+      position.x -= scroll.w.x;
+      position.y -= scroll.w.y;
+    }
 
         return position;
-	},
-
-	getClone: function(event, element){
-		if (!this.options.clone) return new Element(element.tagName).inject(document.body);
-		if (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
-		var clone = element.clone(true).setStyles({
-			margin: 0,
-			position: 'absolute',
-			visibility: 'hidden',
-			width: element.getStyle('width')
-		}).addEvent('mousedown', function(event){
-			element.fireEvent('mousedown', event);
-		});
-		//prevent the duplicated radio inputs from unchecking the real one
-		if (clone.get('html').test('radio')){
-			clone.getElements('input[type=radio]').each(function(input, i){
-				input.set('name', 'clone_' + i);
-				if (input.get('checked')) element.getElements('input[type=radio]')[i].set('checked', true);
-			});
-		}
-
-		return clone.inject(this.list).setPosition(this.getDroppableCoordinates(this.element));
-	},
-
-	getDroppables: function(){
-		var droppables = this.list.getChildren().erase(this.clone).erase(this.element);
-		if (!this.options.constrain) droppables.append(this.lists).erase(this.list);
-		return droppables;
-	},
-
-	insert: function(dragging, element){
-		var where = 'inside';
-		if (this.lists.contains(element)){
-			this.list = element;
-			this.drag.droppables = this.getDroppables();
-		} else {
-			where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
-		}
-		this.element.inject(element, where);
-		this.fireEvent('sort', [this.element, this.clone]);
-	},
-
-	start: function(event, element){
-		if (
-			!this.idle ||
-			event.rightClick ||
-			(!this.options.handle && this.options.unDraggableTags.contains(event.target.get('tag')))
-		) return;
-
-		this.idle = false;
-		this.element = element;
-		this.opacity = element.getStyle('opacity');
-		this.list = element.getParent();
-		this.clone = this.getClone(event, element);
-
-		this.drag = new Drag.Move(this.clone, Object.merge({
-			
-			droppables: this.getDroppables()
-		}, this.options.dragOptions)).addEvents({
-			onSnap: function(){
-				event.stop();
-				this.clone.setStyle('visibility', 'visible');
-				this.element.setStyle('opacity', this.options.opacity || 0);
-				this.fireEvent('start', [this.element, this.clone]);
-			}.bind(this),
-			onEnter: this.insert.bind(this),
-			onCancel: this.end.bind(this),
-			onComplete: this.end.bind(this)
-		});
-
-		this.clone.inject(this.element, 'before');
-		this.drag.start(event);
-	},
-
-	end: function(){
-		this.drag.detach();
-		this.element.setStyle('opacity', this.opacity);
-		var self = this;
-		if (this.effect){
-			var dim = this.element.getStyles('width', 'height'),
-				clone = this.clone,
-				pos = clone.computePosition(this.getDroppableCoordinates(clone));
-
-			var destroy = function(){
-				this.removeEvent('cancel', destroy);
-				clone.destroy();
-				self.reset();
-			};
-
-			this.effect.element = clone;
-			this.effect.start({
-				top: pos.top,
-				left: pos.left,
-				width: dim.width,
-				height: dim.height,
-				opacity: 0.25
-			}).addEvent('cancel', destroy).chain(destroy);
-		} else {
-			this.clone.destroy();
-			self.reset();
-		}
-		
-	},
-
-	reset: function(){
-		this.idle = true;
-		this.fireEvent('complete', this.element);
-	},
-
-	serialize: function(){
-		var params = Array.link(arguments, {
-			modifier: Type.isFunction,
-			index: function(obj){
-				return obj != null;
-			}
-		});
-		var serial = this.lists.map(function(list){
-			return list.getChildren().map(params.modifier || function(element){
-				return element.get('id');
-			}, this);
-		}, this);
-
-		var index = params.index;
-		if (this.lists.length == 1) index = 0;
-		return (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;
-	}
+  },
+
+  getClone: function(event, element){
+    if (!this.options.clone) return new Element(element.tagName).inject(document.body);
+    if (typeOf(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
+    var clone = element.clone(true).setStyles({
+      margin: 0,
+      position: 'absolute',
+      visibility: 'hidden',
+      width: element.getStyle('width')
+    }).addEvent('mousedown', function(event){
+      element.fireEvent('mousedown', event);
+    });
+    //prevent the duplicated radio inputs from unchecking the real one
+    if (clone.get('html').test('radio')){
+      clone.getElements('input[type=radio]').each(function(input, i){
+        input.set('name', 'clone_' + i);
+        if (input.get('checked')) element.getElements('input[type=radio]')[i].set('checked', true);
+      });
+    }
+
+    return clone.inject(this.list).setPosition(this.getDroppableCoordinates(this.element));
+  },
+
+  getDroppables: function(){
+    var droppables = this.list.getChildren().erase(this.clone).erase(this.element);
+    if (!this.options.constrain) droppables.append(this.lists).erase(this.list);
+    return droppables;
+  },
+
+  insert: function(dragging, element){
+    var where = 'inside';
+    if (this.lists.contains(element)){
+      this.list = element;
+      this.drag.droppables = this.getDroppables();
+    } else {
+      where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
+    }
+    this.element.inject(element, where);
+    this.fireEvent('sort', [this.element, this.clone]);
+  },
+
+  start: function(event, element){
+    if (
+      !this.idle ||
+      event.rightClick ||
+      (!this.options.handle && this.options.unDraggableTags.contains(event.target.get('tag')))
+    ) return;
+
+    this.idle = false;
+    this.element = element;
+    this.opacity = element.getStyle('opacity');
+    this.list = element.getParent();
+    this.clone = this.getClone(event, element);
+
+    this.drag = new Drag.Move(this.clone, Object.merge({
+      
+      droppables: this.getDroppables()
+    }, this.options.dragOptions)).addEvents({
+      onSnap: function(){
+        event.stop();
+        this.clone.setStyle('visibility', 'visible');
+        this.element.setStyle('opacity', this.options.opacity || 0);
+        this.fireEvent('start', [this.element, this.clone]);
+      }.bind(this),
+      onEnter: this.insert.bind(this),
+      onCancel: this.end.bind(this),
+      onComplete: this.end.bind(this)
+    });
+
+    this.clone.inject(this.element, 'before');
+    this.drag.start(event);
+  },
+
+  end: function(){
+    this.drag.detach();
+    this.element.setStyle('opacity', this.opacity);
+    var self = this;
+    if (this.effect){
+      var dim = this.element.getStyles('width', 'height'),
+        clone = this.clone,
+        pos = clone.computePosition(this.getDroppableCoordinates(clone));
+
+      var destroy = function(){
+        this.removeEvent('cancel', destroy);
+        clone.destroy();
+        self.reset();
+      };
+
+      this.effect.element = clone;
+      this.effect.start({
+        top: pos.top,
+        left: pos.left,
+        width: dim.width,
+        height: dim.height,
+        opacity: 0.25
+      }).addEvent('cancel', destroy).chain(destroy);
+    } else {
+      this.clone.destroy();
+      self.reset();
+    }
+    
+  },
+
+  reset: function(){
+    this.idle = true;
+    this.fireEvent('complete', this.element);
+  },
+
+  serialize: function(){
+    var params = Array.link(arguments, {
+      modifier: Type.isFunction,
+      index: function(obj){
+        return obj != null;
+      }
+    });
+    var serial = this.lists.map(function(list){
+      return list.getChildren().map(params.modifier || function(element){
+        return element.get('id');
+      }, this);
+    }, this);
+
+    var index = params.index;
+    if (this.lists.length == 1) index = 0;
+    return (index || index === 0) && index >= 0 && index < this.lists.length ? serial[index] : serial;
+  }
 
 });
 
@@ -2663,30 +2663,30 @@ provides: [Request.Periodical]
 
 Request.implement({
 
-	options: {
-		initialDelay: 5000,
-		delay: 5000,
-		limit: 60000
-	},
-
-	startTimer: function(data){
-		var fn = function(){
-			if (!this.running) this.send({data: data});
-		};
-		this.lastDelay = this.options.initialDelay;
-		this.timer = fn.delay(this.lastDelay, this);
-		this.completeCheck = function(response){
-			clearTimeout(this.timer);
-			this.lastDelay = (response) ? this.options.delay : (this.lastDelay + this.options.delay).min(this.options.limit);
-			this.timer = fn.delay(this.lastDelay, this);
-		};
-		return this.addEvent('complete', this.completeCheck);
-	},
-
-	stopTimer: function(){
-		clearTimeout(this.timer);
-		return this.removeEvent('complete', this.completeCheck);
-	}
+  options: {
+    initialDelay: 5000,
+    delay: 5000,
+    limit: 60000
+  },
+
+  startTimer: function(data){
+    var fn = function(){
+      if (!this.running) this.send({data: data});
+    };
+    this.lastDelay = this.options.initialDelay;
+    this.timer = fn.delay(this.lastDelay, this);
+    this.completeCheck = function(response){
+      clearTimeout(this.timer);
+      this.lastDelay = (response) ? this.options.delay : (this.lastDelay + this.options.delay).min(this.options.limit);
+      this.timer = fn.delay(this.lastDelay, this);
+    };
+    return this.addEvent('complete', this.completeCheck);
+  },
+
+  stopTimer: function(){
+    clearTimeout(this.timer);
+    return this.removeEvent('complete', this.completeCheck);
+  }
 
 });
 
@@ -2721,133 +2721,133 @@ provides: [Color]
 (function(){
 
 var Color = this.Color = new Type('Color', function(color, type){
-	if (arguments.length >= 3){
-		type = 'rgb'; color = Array.slice(arguments, 0, 3);
-	} else if (typeof color == 'string'){
-		if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);
-		else if (color.match(/hsb/)) color = color.hsbToRgb();
-		else color = color.hexToRgb(true);
-	}
-	type = type || 'rgb';
-	switch (type){
-		case 'hsb':
-			var old = color;
-			color = color.hsbToRgb();
-			color.hsb = old;
-		break;
-		case 'hex': color = color.hexToRgb(true); break;
-	}
-	color.rgb = color.slice(0, 3);
-	color.hsb = color.hsb || color.rgbToHsb();
-	color.hex = color.rgbToHex();
-	return Object.append(color, this);
+  if (arguments.length >= 3){
+    type = 'rgb'; color = Array.slice(arguments, 0, 3);
+  } else if (typeof color == 'string'){
+    if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);
+    else if (color.match(/hsb/)) color = color.hsbToRgb();
+    else color = color.hexToRgb(true);
+  }
+  type = type || 'rgb';
+  switch (type){
+    case 'hsb':
+      var old = color;
+      color = color.hsbToRgb();
+      color.hsb = old;
+    break;
+    case 'hex': color = color.hexToRgb(true); break;
+  }
+  color.rgb = color.slice(0, 3);
+  color.hsb = color.hsb || color.rgbToHsb();
+  color.hex = color.rgbToHex();
+  return Object.append(color, this);
 });
 
 Color.implement({
 
-	mix: function(){
-		var colors = Array.slice(arguments);
-		var alpha = (typeOf(colors.getLast()) == 'number') ? colors.pop() : 50;
-		var rgb = this.slice();
-		colors.each(function(color){
-			color = new Color(color);
-			for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
-		});
-		return new Color(rgb, 'rgb');
-	},
-
-	invert: function(){
-		return new Color(this.map(function(value){
-			return 255 - value;
-		}));
-	},
-
-	setHue: function(value){
-		return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
-	},
-
-	setSaturation: function(percent){
-		return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
-	},
-
-	setBrightness: function(percent){
-		return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
-	}
+  mix: function(){
+    var colors = Array.slice(arguments);
+    var alpha = (typeOf(colors.getLast()) == 'number') ? colors.pop() : 50;
+    var rgb = this.slice();
+    colors.each(function(color){
+      color = new Color(color);
+      for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
+    });
+    return new Color(rgb, 'rgb');
+  },
+
+  invert: function(){
+    return new Color(this.map(function(value){
+      return 255 - value;
+    }));
+  },
+
+  setHue: function(value){
+    return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
+  },
+
+  setSaturation: function(percent){
+    return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
+  },
+
+  setBrightness: function(percent){
+    return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
+  }
 
 });
 
 this.$RGB = function(r, g, b){
-	return new Color([r, g, b], 'rgb');
+  return new Color([r, g, b], 'rgb');
 };
 
 this.$HSB = function(h, s, b){
-	return new Color([h, s, b], 'hsb');
+  return new Color([h, s, b], 'hsb');
 };
 
 this.$HEX = function(hex){
-	return new Color(hex, 'hex');
+  return new Color(hex, 'hex');
 };
 
 Array.implement({
 
-	rgbToHsb: function(){
-		var red = this[0],
-				green = this[1],
-				blue = this[2],
-				hue = 0;
-		var max = Math.max(red, green, blue),
-				min = Math.min(red, green, blue);
-		var delta = max - min;
-		var brightness = max / 255,
-				saturation = (max != 0) ? delta / max : 0;
-		if (saturation != 0){
-			var rr = (max - red) / delta;
-			var gr = (max - green) / delta;
-			var br = (max - blue) / delta;
-			if (red == max) hue = br - gr;
-			else if (green == max) hue = 2 + rr - br;
-			else hue = 4 + gr - rr;
-			hue /= 6;
-			if (hue < 0) hue++;
-		}
-		return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
-	},
-
-	hsbToRgb: function(){
-		var br = Math.round(this[2] / 100 * 255);
-		if (this[1] == 0){
-			return [br, br, br];
-		} else {
-			var hue = this[0] % 360;
-			var f = hue % 60;
-			var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
-			var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
-			var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
-			switch (Math.floor(hue / 60)){
-				case 0: return [br, t, p];
-				case 1: return [q, br, p];
-				case 2: return [p, br, t];
-				case 3: return [p, q, br];
-				case 4: return [t, p, br];
-				case 5: return [br, p, q];
-			}
-		}
-		return false;
-	}
+  rgbToHsb: function(){
+    var red = this[0],
+        green = this[1],
+        blue = this[2],
+        hue = 0;
+    var max = Math.max(red, green, blue),
+        min = Math.min(red, green, blue);
+    var delta = max - min;
+    var brightness = max / 255,
+        saturation = (max != 0) ? delta / max : 0;
+    if (saturation != 0){
+      var rr = (max - red) / delta;
+      var gr = (max - green) / delta;
+      var br = (max - blue) / delta;
+      if (red == max) hue = br - gr;
+      else if (green == max) hue = 2 + rr - br;
+      else hue = 4 + gr - rr;
+      hue /= 6;
+      if (hue < 0) hue++;
+    }
+    return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
+  },
+
+  hsbToRgb: function(){
+    var br = Math.round(this[2] / 100 * 255);
+    if (this[1] == 0){
+      return [br, br, br];
+    } else {
+      var hue = this[0] % 360;
+      var f = hue % 60;
+      var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
+      var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
+      var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
+      switch (Math.floor(hue / 60)){
+        case 0: return [br, t, p];
+        case 1: return [q, br, p];
+        case 2: return [p, br, t];
+        case 3: return [p, q, br];
+        case 4: return [t, p, br];
+        case 5: return [br, p, q];
+      }
+    }
+    return false;
+  }
 
 });
 
 String.implement({
 
-	rgbToHsb: function(){
-		var rgb = this.match(/\d{1,3}/g);
-		return (rgb) ? rgb.rgbToHsb() : null;
-	},
+  rgbToHsb: function(){
+    var rgb = this.match(/\d{1,3}/g);
+    return (rgb) ? rgb.rgbToHsb() : null;
+  },
 
-	hsbToRgb: function(){
-		var hsb = this.match(/\d{1,3}/g);
-		return (hsb) ? hsb.hsbToRgb() : null;
-	}
+  hsbToRgb: function(){
+    var hsb = this.match(/\d{1,3}/g);
+    return (hsb) ? hsb.hsbToRgb() : null;
+  }
 
 });
 
diff --git a/pyload/webui/themes/estate/js/static/purr.js b/pyload/webui/themes/estate/js/static/purr.js
index 9cbc503d9..be365c367 100644
--- a/pyload/webui/themes/estate/js/static/purr.js
+++ b/pyload/webui/themes/estate/js/static/purr.js
@@ -18,292 +18,292 @@ provides: [Purr, Element.alert]
 
 var Purr = new Class({
 
-	'options': {
-		'mode': 'top',
-		'position': 'left',
-		'elementAlertClass': 'purr-element-alert',
-		'elements': {
-			'wrapper': 'div',
-			'alert': 'div',
-			'buttonWrapper': 'div',
-			'button': 'button'
-		},
-		'elementOptions': {
-			'wrapper': {
-				'styles': {
-					'position': 'fixed',
-					'z-index': '9999'
-				},
-				'class': 'purr-wrapper'
-			},
-			'alert': {
-				'class': 'purr-alert',
-				'styles': {
-					'opacity': '.85'
-				}
-			},
-			'buttonWrapper': {
-				'class': 'purr-button-wrapper'
-			},
-			'button': {
-				'class': 'purr-button'
-			}
-		},
-		'alert': {
-			'buttons': [],
-			'clickDismiss': true,
-			'hoverWait': true,
-			'hideAfter': 5000,
-			'fx': {
-				'duration': 500
-			},
-			'highlight': false,
-			'highlightRepeat': false,
-			'highlight': {
-				'start': '#FF0',
-				'end': false
-			}
-		}
-	},
-
-	'Implements': [Options, Events, Chain],
-
-	'initialize': function(options){
-		this.setOptions(options);
-		this.createWrapper();
-		return this;
-	},
-
-	'bindAlert': function(){
-		return this.alert.bind(this);
-	},
-
-	'createWrapper': function(){
-		this.wrapper = new Element(this.options.elements.wrapper, this.options.elementOptions.wrapper);
-		if(this.options.mode == 'top')
-		{
-			this.wrapper.setStyle('top', 0);
-		}
-		else
-		{
-			this.wrapper.setStyle('bottom', 0);
-		}
-		document.id(document.body).grab(this.wrapper);
-		this.positionWrapper(this.options.position);
-	},
-
-	'positionWrapper': function(position){
-		if(typeOf(position) == 'object')
-		{
-
-			var wrapperCoords = this.getWrapperCoords();
-
-			this.wrapper.setStyles({
-				'bottom': '',
-				'left': position.x,
-				'top': position.y - wrapperCoords.height,
-				'position': 'absolute'
-			});
-		}
-		else if(position == 'left')
-		{
-			this.wrapper.setStyle('left', 0);
-		}
-		else if(position == 'right')
-		{
-			this.wrapper.setStyle('right', 0);
-		}
-		else
-		{
-			this.wrapper.setStyle('left', (window.innerWidth / 2) - (this.getWrapperCoords().width / 2));
-		}
-		return this;
-	},
-
-	'getWrapperCoords': function(){
-		this.wrapper.setStyle('visibility', 'hidden');
-		var measurer = this.alert('need something in here to measure');
-		var coords = this.wrapper.getCoordinates();
-		measurer.destroy();
-		this.wrapper.setStyle('visibility','');
-		return coords;
-	},
-
-	'alert': function(msg, options){
-
-		options = Object.merge({}, this.options.alert, options || {});
-
-		var alert = new Element(this.options.elements.alert, this.options.elementOptions.alert);
-
-		if(typeOf(msg) == 'string')
-		{
-			alert.set('html', msg);
-		}
-		else if(typeOf(msg) == 'element')
-		{
-			alert.grab(msg);
-		}
-		else if(typeOf(msg) == 'array')
-		{
-			var alerts = [];
-			msg.each(function(m){
-				alerts.push(this.alert(m, options));
-			}, this);
-			return alerts;
-		}
-
-		alert.store('options', options);
-
-		if(options.buttons.length > 0)
-		{
-			options.clickDismiss = false;
-			options.hideAfter = false;
-			options.hoverWait = false;
-			var buttonWrapper = new Element(this.options.elements.buttonWrapper, this.options.elementOptions.buttonWrapper);
-			alert.grab(buttonWrapper);
-			options.buttons.each(function(button){
-				if(button.text != undefined)
-				{
-					var callbackButton = new Element(this.options.elements.button, this.options.elementOptions.button);
-					callbackButton.set('html', button.text);
-					if(button.callback != undefined)
-					{
-						callbackButton.addEvent('click', button.callback.pass(alert));
-					}
-					if(button.dismiss != undefined && button.dismiss)
-					{
-						callbackButton.addEvent('click', this.dismiss.pass(alert, this));
-					}
-					buttonWrapper.grab(callbackButton);
-				}
-			}, this);
-		}
-		if(options.className != undefined)
-		{
-			alert.addClass(options.className);
-		}
-
-		this.wrapper.grab(alert, (this.options.mode == 'top') ? 'bottom' : 'top');
-
-		var fx = Object.merge(this.options.alert.fx, options.fx);
-		var alertFx = new Fx.Morph(alert, fx);
-		alert.store('fx', alertFx);
-		this.fadeIn(alert);
-
-		if(options.highlight)
-		{
-			alertFx.addEvent('complete', function(){
-				alert.highlight(options.highlight.start, options.highlight.end);
-				if(options.highlightRepeat)
-				{
-					alert.highlight.periodical(options.highlightRepeat, alert, [options.highlight.start, options.highlight.end]);
-				}
-			});
-		}
-		if(options.hideAfter)
-		{
-			this.dismiss(alert);
-		}
-
-		if(options.clickDismiss)
-		{
-			alert.addEvent('click', function(){
-				this.holdUp = false;
-				this.dismiss(alert, true);
-			}.bind(this));
-		}
-
-		if(options.hoverWait)
-		{
-			alert.addEvents({
-				'mouseenter': function(){
-					this.holdUp = true;
-				}.bind(this),
-				'mouseleave': function(){
-					this.holdUp = false;
-				}.bind(this)
-			});
-		}
-
-		return alert;
-	},
-
-	'fadeIn': function(alert){
-		var alertFx = alert.retrieve('fx');
-		alertFx.set({
-			'opacity': 0
-		});
-		alertFx.start({
-			'opacity': [this.options.elementOptions.alert.styles.opacity, .9].pick(),
-		});
-	},
-
-	'dismiss': function(alert, now){
-		now = now || false;
-		var options = alert.retrieve('options');
-		if(now)
-		{
-			this.fadeOut(alert);
-		}
-		else
-		{
-			this.fadeOut.delay(options.hideAfter, this, alert);
-		}
-	},
-
-	'fadeOut': function(alert){
-		if(this.holdUp)
-		{
-			this.dismiss.delay(100, this, [alert, true])
-			return null;
-		}
-		var alertFx = alert.retrieve('fx');
-		if(!alertFx)
-		{
-			return null;
-		}
-		var to = {
-			'opacity': 0
-		}
-		if(this.options.mode == 'top')
-		{
-			to['margin-top'] = '-'+alert.offsetHeight+'px';
-		}
-		else
-		{
-			to['margin-bottom'] = '-'+alert.offsetHeight+'px';
-		}
-		alertFx.start(to);
-		alertFx.addEvent('complete', function(){
-			alert.destroy();
-		});
-	}
+    'options': {
+        'mode': 'top',
+        'position': 'left',
+        'elementAlertClass': 'purr-element-alert',
+        'elements': {
+            'wrapper': 'div',
+            'alert': 'div',
+            'buttonWrapper': 'div',
+            'button': 'button'
+        },
+        'elementOptions': {
+            'wrapper': {
+                'styles': {
+                    'position': 'fixed',
+                    'z-index': '9999'
+                },
+                'class': 'purr-wrapper'
+            },
+            'alert': {
+                'class': 'purr-alert',
+                'styles': {
+                    'opacity': '.85'
+                }
+            },
+            'buttonWrapper': {
+                'class': 'purr-button-wrapper'
+            },
+            'button': {
+                'class': 'purr-button'
+            }
+        },
+        'alert': {
+            'buttons': [],
+            'clickDismiss': true,
+            'hoverWait': true,
+            'hideAfter': 5000,
+            'fx': {
+                'duration': 500
+            },
+            'highlight': false,
+            'highlightRepeat': false,
+            'highlight': {
+                'start': '#FF0',
+                'end': false
+            }
+        }
+    },
+
+    'Implements': [Options, Events, Chain],
+
+    'initialize': function(options){
+        this.setOptions(options);
+        this.createWrapper();
+        return this;
+    },
+
+    'bindAlert': function(){
+        return this.alert.bind(this);
+    },
+
+    'createWrapper': function(){
+        this.wrapper = new Element(this.options.elements.wrapper, this.options.elementOptions.wrapper);
+        if(this.options.mode == 'top')
+        {
+            this.wrapper.setStyle('top', 0);
+        }
+        else
+        {
+            this.wrapper.setStyle('bottom', 0);
+        }
+        document.id(document.body).grab(this.wrapper);
+        this.positionWrapper(this.options.position);
+    },
+
+    'positionWrapper': function(position){
+        if(typeOf(position) == 'object')
+        {
+
+            var wrapperCoords = this.getWrapperCoords();
+
+            this.wrapper.setStyles({
+                'bottom': '',
+                'left': position.x,
+                'top': position.y - wrapperCoords.height,
+                'position': 'absolute'
+            });
+        }
+        else if(position == 'left')
+        {
+            this.wrapper.setStyle('left', 0);
+        }
+        else if(position == 'right')
+        {
+            this.wrapper.setStyle('right', 0);
+        }
+        else
+        {
+            this.wrapper.setStyle('left', (window.innerWidth / 2) - (this.getWrapperCoords().width / 2));
+        }
+        return this;
+    },
+
+    'getWrapperCoords': function(){
+        this.wrapper.setStyle('visibility', 'hidden');
+        var measurer = this.alert('need something in here to measure');
+        var coords = this.wrapper.getCoordinates();
+        measurer.destroy();
+        this.wrapper.setStyle('visibility','');
+        return coords;
+    },
+
+    'alert': function(msg, options){
+
+        options = Object.merge({}, this.options.alert, options || {});
+
+        var alert = new Element(this.options.elements.alert, this.options.elementOptions.alert);
+
+        if(typeOf(msg) == 'string')
+        {
+            alert.set('html', msg);
+        }
+        else if(typeOf(msg) == 'element')
+        {
+            alert.grab(msg);
+        }
+        else if(typeOf(msg) == 'array')
+        {
+            var alerts = [];
+            msg.each(function(m){
+                alerts.push(this.alert(m, options));
+            }, this);
+            return alerts;
+        }
+
+        alert.store('options', options);
+
+        if(options.buttons.length > 0)
+        {
+            options.clickDismiss = false;
+            options.hideAfter = false;
+            options.hoverWait = false;
+            var buttonWrapper = new Element(this.options.elements.buttonWrapper, this.options.elementOptions.buttonWrapper);
+            alert.grab(buttonWrapper);
+            options.buttons.each(function(button){
+                if(button.text != undefined)
+                {
+                    var callbackButton = new Element(this.options.elements.button, this.options.elementOptions.button);
+                    callbackButton.set('html', button.text);
+                    if(button.callback != undefined)
+                    {
+                        callbackButton.addEvent('click', button.callback.pass(alert));
+                    }
+                    if(button.dismiss != undefined && button.dismiss)
+                    {
+                        callbackButton.addEvent('click', this.dismiss.pass(alert, this));
+                    }
+                    buttonWrapper.grab(callbackButton);
+                }
+            }, this);
+        }
+        if(options.className != undefined)
+        {
+            alert.addClass(options.className);
+        }
+
+        this.wrapper.grab(alert, (this.options.mode == 'top') ? 'bottom' : 'top');
+
+        var fx = Object.merge(this.options.alert.fx, options.fx);
+        var alertFx = new Fx.Morph(alert, fx);
+        alert.store('fx', alertFx);
+        this.fadeIn(alert);
+
+        if(options.highlight)
+        {
+            alertFx.addEvent('complete', function(){
+                alert.highlight(options.highlight.start, options.highlight.end);
+                if(options.highlightRepeat)
+                {
+                    alert.highlight.periodical(options.highlightRepeat, alert, [options.highlight.start, options.highlight.end]);
+                }
+            });
+        }
+        if(options.hideAfter)
+        {
+            this.dismiss(alert);
+        }
+
+        if(options.clickDismiss)
+        {
+            alert.addEvent('click', function(){
+                this.holdUp = false;
+                this.dismiss(alert, true);
+            }.bind(this));
+        }
+
+        if(options.hoverWait)
+        {
+            alert.addEvents({
+                'mouseenter': function(){
+                    this.holdUp = true;
+                }.bind(this),
+                'mouseleave': function(){
+                    this.holdUp = false;
+                }.bind(this)
+            });
+        }
+
+        return alert;
+    },
+
+    'fadeIn': function(alert){
+        var alertFx = alert.retrieve('fx');
+        alertFx.set({
+            'opacity': 0
+        });
+        alertFx.start({
+            'opacity': [this.options.elementOptions.alert.styles.opacity, .9].pick(),
+        });
+    },
+
+    'dismiss': function(alert, now){
+        now = now || false;
+        var options = alert.retrieve('options');
+        if(now)
+        {
+            this.fadeOut(alert);
+        }
+        else
+        {
+            this.fadeOut.delay(options.hideAfter, this, alert);
+        }
+    },
+
+    'fadeOut': function(alert){
+        if(this.holdUp)
+        {
+            this.dismiss.delay(100, this, [alert, true])
+            return null;
+        }
+        var alertFx = alert.retrieve('fx');
+        if(!alertFx)
+        {
+            return null;
+        }
+        var to = {
+            'opacity': 0
+        }
+        if(this.options.mode == 'top')
+        {
+            to['margin-top'] = '-'+alert.offsetHeight+'px';
+        }
+        else
+        {
+            to['margin-bottom'] = '-'+alert.offsetHeight+'px';
+        }
+        alertFx.start(to);
+        alertFx.addEvent('complete', function(){
+            alert.destroy();
+        });
+    }
 });
 
 Element.implement({
 
-	'alert': function(msg, options){
-		var alert = this.retrieve('alert');
-		if(!alert)
-		{
-			options = options || {
-				'mode':'top'
-			};
-			alert = new Purr(options)
-			this.store('alert', alert);
-		}
-
-		var coords = this.getCoordinates();
-
-		alert.alert(msg, options);
-
-		alert.wrapper.setStyles({
-			'bottom': '',
-			'left': (coords.left - (alert.wrapper.getWidth() / 2)) + (this.getWidth() / 2),
-			'top': coords.top - (alert.wrapper.getHeight()),
-			'position': 'absolute'
-		});
-
-	}
+    'alert': function(msg, options){
+        var alert = this.retrieve('alert');
+        if(!alert)
+        {
+            options = options || {
+                'mode':'top'
+            };
+            alert = new Purr(options)
+            this.store('alert', alert);
+        }
+
+        var coords = this.getCoordinates();
+
+        alert.alert(msg, options);
+
+        alert.wrapper.setStyles({
+            'bottom': '',
+            'left': (coords.left - (alert.wrapper.getWidth() / 2)) + (this.getWidth() / 2),
+            'top': coords.top - (alert.wrapper.getHeight()),
+            'position': 'absolute'
+        });
+
+    }
 
 });
\ No newline at end of file
diff --git a/pyload/webui/themes/estate/js/static/tinytab.js b/pyload/webui/themes/estate/js/static/tinytab.js
index 3273451fe..977ef51d8 100644
--- a/pyload/webui/themes/estate/js/static/tinytab.js
+++ b/pyload/webui/themes/estate/js/static/tinytab.js
@@ -15,29 +15,29 @@ provides: TinyTab
 ...
 */
 (function($) {
-	this.TinyTab = new Class({
-		Implements: Events,
-		initialize: function(tabs, contents, opt) {
-			this.tabs = tabs;
-			this.contents = contents;
-			if(!opt) opt = {};
-			this.css = opt.selectedClass || 'selected';
-			this.select(this.tabs[0]);
-			tabs.each(function(el){
-				el.addEvent('click',function(e){
-					this.select(el);
-					e.stop();
-				}.bind(this));
-			}.bind(this));
-		},
+    this.TinyTab = new Class({
+        Implements: Events,
+        initialize: function(tabs, contents, opt) {
+            this.tabs = tabs;
+            this.contents = contents;
+            if(!opt) opt = {};
+            this.css = opt.selectedClass || 'selected';
+            this.select(this.tabs[0]);
+            tabs.each(function(el){
+                el.addEvent('click',function(e){
+                    this.select(el);
+                    e.stop();
+                }.bind(this));
+            }.bind(this));
+        },
 
-		select: function(el) {
-			this.tabs.removeClass(this.css);
-			el.addClass(this.css);
-			this.contents.setStyle('display','none');
-			var content = this.contents[this.tabs.indexOf(el)];
-			content.setStyle('display','block');
-			this.fireEvent('change',[content,el]);
-		}
-	});
+        select: function(el) {
+            this.tabs.removeClass(this.css);
+            el.addClass(this.css);
+            this.contents.setStyle('display','none');
+            var content = this.contents[this.tabs.indexOf(el)];
+            content.setStyle('display','block');
+            this.fireEvent('change',[content,el]);
+        }
+    });
 })(document.id);
\ No newline at end of file
diff --git a/pyload/webui/themes/estate/tml/home.html b/pyload/webui/themes/estate/tml/home.html
index 535c300c4..b5ef764f4 100644
--- a/pyload/webui/themes/estate/tml/home.html
+++ b/pyload/webui/themes/estate/tml/home.html
@@ -7,7 +7,7 @@ var em;
 var operafix = (navigator.userAgent.toLowerCase().search("opera") >= 0);
 
 document.addEvent("domready", function(){
-  em = new EntryManager();
+    em = new EntryManager();
 });
 
 var EntryManager = new Class({
-- 
cgit v1.2.3