From 0ca6e7c210a8cfb0be215a85a4a73c7dcc00bc67 Mon Sep 17 00:00:00 2001
From: Walter Purcaro <vuolter@gmail.com>
Date: Fri, 17 Oct 2014 02:23:53 +0200
Subject: [themes] Restore static js

---
 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 | 8144 ++++++++++----------
 .../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 +-
 6 files changed, 6607 insertions(+), 6607 deletions(-)

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

diff --git a/pyload/webui/themes/estate/js/static/MooDialog.js b/pyload/webui/themes/estate/js/static/MooDialog.js
index 237984981..45a52496f 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 08dc79c1e..ac0fa1874 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 bfa57abbc..db83850fd 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 (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 (!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.');
+	}
 
-  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 3b63949a7..c7f4a1a0e 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 be365c367..9cbc503d9 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 977ef51d8..de50279fc 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
-- 
cgit v1.2.3