text: /*
  ---
  
  script: Core.js
  
  description: The core of MooTools, contains all the base functions and the Native and Hash implementations. Required by all the other scripts.
  
  license: MIT-style license.
  
  copyright: Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/).
  
  authors: The MooTools production team (http://mootools.net/developers/)
  
  inspiration:
  - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php)
  - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php)
  
  provides: [Mootools, Native, Hash.base, Array.each, $util]
  
  ...
  */
  
  var MooTools = {
  	'version': '1.2.4',
  	'build': '0d9113241a90b9cd5643b926795852a2026710d4'
  };
  
  var Native = function(options){
  	options = options || {};
  	var name = options.name;
  	var legacy = options.legacy;
  	var protect = options.protect;
  	var methods = options.implement;
  	var generics = options.generics;
  	var initialize = options.initialize;
  	var afterImplement = options.afterImplement || function(){};
  	var object = initialize || legacy;
  	generics = generics !== false;
  
  	object.constructor = Native;
  	object.$family = {name: 'native'};
  	if (legacy && initialize) object.prototype = legacy.prototype;
  	object.prototype.constructor = object;
  
  	if (name){
  		var family = name.toLowerCase();
  		object.prototype.$family = {name: family};
  		Native.typize(object, family);
  	}
  
  	var add = function(obj, name, method, force){
  		if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method;
  		if (generics) Native.genericize(obj, name, protect);
  		afterImplement.call(obj, name, method);
  		return obj;
  	};
  
  	object.alias = function(a1, a2, a3){
  		if (typeof a1 == 'string'){
  			var pa1 = this.prototype[a1];
  			if ((a1 = pa1)) return add(this, a2, a1, a3);
  		}
  		for (var a in a1) this.alias(a, a1[a], a2);
  		return this;
  	};
  
  	object.implement = function(a1, a2, a3){
  		if (typeof a1 == 'string') return add(this, a1, a2, a3);
  		for (var p in a1) add(this, p, a1[p], a2);
  		return this;
  	};
  
  	if (methods) object.implement(methods);
  
  	return object;
  };
  
  Native.genericize = function(object, property, check){
  	if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){
  		var args = Array.prototype.slice.call(arguments);
  		return object.prototype[property].apply(args.shift(), args);
  	};
  };
  
  Native.implement = function(objects, properties){
  	for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties);
  };
  
  Native.typize = function(object, family){
  	if (!object.type) object.type = function(item){
  		return ($type(item) === family);
  	};
  };
  
  (function(){
  	var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String};
  	for (var n in natives) new Native({name: n, initialize: natives[n], protect: true});
  
  	var types = {'boolean': Boolean, 'native': Native, 'object': Object};
  	for (var t in types) Native.typize(types[t], t);
  
  	var generics = {
  		'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"],
  		'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"]
  	};
  	for (var g in generics){
  		for (var i = generics[g].length; i--;) Native.genericize(natives[g], generics[g][i], true);
  	}
  })();
  
  var Hash = new Native({
  
  	name: 'Hash',
  
  	initialize: function(object){
  		if ($type(object) == 'hash') object = $unlink(object.getClean());
  		for (var key in object) this[key] = object[key];
  		return this;
  	}
  
  });
  
  Hash.implement({
  
  	forEach: function(fn, bind){
  		for (var key in this){
  			if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);
  		}
  	},
  
  	getClean: function(){
  		var clean = {};
  		for (var key in this){
  			if (this.hasOwnProperty(key)) clean[key] = this[key];
  		}
  		return clean;
  	},
  
  	getLength: function(){
  		var length = 0;
  		for (var key in this){
  			if (this.hasOwnProperty(key)) length++;
  		}
  		return length;
  	}
  
  });
  
  Hash.alias('forEach', 'each');
  
  Array.implement({
  
  	forEach: function(fn, bind){
  		for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this);
  	}
  
  });
  
  Array.alias('forEach', 'each');
  
  function $A(iterable){
  	if (iterable.item){
  		var l = iterable.length, array = new Array(l);
  		while (l--) array[l] = iterable[l];
  		return array;
  	}
  	return Array.prototype.slice.call(iterable);
  };
  
  function $arguments(i){
  	return function(){
  		return arguments[i];
  	};
  };
  
  function $chk(obj){
  	return !!(obj || obj === 0);
  };
  
  function $clear(timer){
  	clearTimeout(timer);
  	clearInterval(timer);
  	return null;
  };
  
  function $defined(obj){
  	return (obj != undefined);
  };
  
  function $each(iterable, fn, bind){
  	var type = $type(iterable);
  	((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind);
  };
  
  function $empty(){};
  
  function $extend(original, extended){
  	for (var key in (extended || {})) original[key] = extended[key];
  	return original;
  };
  
  function $H(object){
  	return new Hash(object);
  };
  
  function $lambda(value){
  	return ($type(value) == 'function') ? value : function(){
  		return value;
  	};
  };
  
  function $merge(){
  	var args = Array.slice(arguments);
  	args.unshift({});
  	return $mixin.apply(null, args);
  };
  
  function $mixin(mix){
  	for (var i = 1, l = arguments.length; i < l; i++){
  		var object = arguments[i];
  		if ($type(object) != 'object') continue;
  		for (var key in object){
  			var op = object[key], mp = mix[key];
  			mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op);
  		}
  	}
  	return mix;
  };
  
  function $pick(){
  	for (var i = 0, l = arguments.length; i < l; i++){
  		if (arguments[i] != undefined) return arguments[i];
  	}
  	return null;
  };
  
  function $random(min, max){
  	return Math.floor(Math.random() * (max - min + 1) + min);
  };
  
  function $splat(obj){
  	var type = $type(obj);
  	return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
  };
  
  var $time = Date.now || function(){
  	return +new Date;
  };
  
  function $try(){
  	for (var i = 0, l = arguments.length; i < l; i++){
  		try {
  			return arguments[i]();
  		} catch(e){}
  	}
  	return null;
  };
  
  function $type(obj){
  	if (obj == undefined) return false;
  	if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
  	if (obj.nodeName){
  		switch (obj.nodeType){
  			case 1: return 'element';
  			case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
  		}
  	} else if (typeof obj.length == 'number'){
  		if (obj.callee) return 'arguments';
  		else if (obj.item) return 'collection';
  	}
  	return typeof obj;
  };
  
  function $unlink(object){
  	var unlinked;
  	switch ($type(object)){
  		case 'object':
  			unlinked = {};
  			for (var p in object) unlinked[p] = $unlink(object[p]);
  		break;
  		case 'hash':
  			unlinked = new Hash(object);
  		break;
  		case 'array':
  			unlinked = [];
  			for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
  		break;
  		default: return object;
  	}
  	return unlinked;
  };
  
  
  /*
  ---
  
  script: Browser.js
  
  description: The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash.
  
  license: MIT-style license.
  
  requires: 
  - /Native
  - /$util
  
  provides: [Browser, Window, Document, $exec]
  
  ...
  */
  
  var Browser = $merge({
  
  	Engine: {name: 'unknown', version: 0},
  
  	Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
  
  	Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
  
  	Plugins: {},
  
  	Engines: {
  
  		presto: function(){
  			return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
  		},
  
  		trident: function(){
  			return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4);
  		},
  
  		webkit: function(){
  			return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
  		},
  
  		gecko: function(){
  			return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18);
  		}
  
  	}
  
  }, Browser || {});
  
  Browser.Platform[Browser.Platform.name] = true;
  
  Browser.detect = function(){
  
  	for (var engine in this.Engines){
  		var version = this.Engines[engine]();
  		if (version){
  			this.Engine = {name: engine, version: version};
  			this.Engine[engine] = this.Engine[engine + version] = true;
  			break;
  		}
  	}
  
  	return {name: engine, version: version};
  
  };
  
  Browser.detect();
  
  Browser.Request = function(){
  	return $try(function(){
  		return new XMLHttpRequest();
  	}, function(){
  		return new ActiveXObject('MSXML2.XMLHTTP');
  	}, function(){
  		return new ActiveXObject('Microsoft.XMLHTTP');
  	});
  };
  
  Browser.Features.xhr = !!(Browser.Request());
  
  Browser.Plugins.Flash = (function(){
  	var version = ($try(function(){
  		return navigator.plugins['Shockwave Flash'].description;
  	}, function(){
  		return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
  	}) || '0 r0').match(/\d+/g);
  	return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
  })();
  
  function $exec(text){
  	if (!text) return text;
  	if (window.execScript){
  		window.execScript(text);
  	} else {
  		var script = document.createElement('script');
  		script.setAttribute('type', 'text/javascript');
  		script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text;
  		document.head.appendChild(script);
  		document.head.removeChild(script);
  	}
  	return text;
  };
  
  Native.UID = 1;
  
  var $uid = (Browser.Engine.trident) ? function(item){
  	return (item.uid || (item.uid = [Native.UID++]))[0];
  } : function(item){
  	return item.uid || (item.uid = Native.UID++);
  };
  
  var Window = new Native({
  
  	name: 'Window',
  
  	legacy: (Browser.Engine.trident) ? null: window.Window,
  
  	initialize: function(win){
  		$uid(win);
  		if (!win.Element){
  			win.Element = $empty;
  			if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2
  			win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {};
  		}
  		win.document.window = win;
  		return $extend(win, Window.Prototype);
  	},
  
  	afterImplement: function(property, value){
  		window[property] = Window.Prototype[property] = value;
  	}
  
  });
  
  Window.Prototype = {$family: {name: 'window'}};
  
  new Window(window);
  
  var Document = new Native({
  
  	name: 'Document',
  
  	legacy: (Browser.Engine.trident) ? null: window.Document,
  
  	initialize: function(doc){
  		$uid(doc);
  		doc.head = doc.getElementsByTagName('head')[0];
  		doc.html = doc.getElementsByTagName('html')[0];
  		if (Browser.Engine.trident && Browser.Engine.version <= 4) $try(function(){
  			doc.execCommand("BackgroundImageCache", false, true);
  		});
  		if (Browser.Engine.trident) doc.window.attachEvent('onunload', function(){
  			doc.window.detachEvent('onunload', arguments.callee);
  			doc.head = doc.html = doc.window = null;
  		});
  		return $extend(doc, Document.Prototype);
  	},
  
  	afterImplement: function(property, value){
  		document[property] = Document.Prototype[property] = value;
  	}
  
  });
  
  Document.Prototype = {$family: {name: 'document'}};
  
  new Document(document);
  