/**
 * @projectDescription 	DOM, Animations, Ajax and more Framework Library
 * @author	Sandro Lain
 * @version	1.9b
 */
var AIDA_JS = {
	version: 1.9,
	updated: 20080113
};

// Creatore di classi
var Class = function(p){
	var i, c = function(){
		var k = this.__construct, a = arguments;
		if (k && a[0] != '__extend')
			return k.apply(this, a);
		return this;
	};
	/*for (i in this)
		c[i] = this[i];*/
	
	c.extend = function(p){
		var t = new this('__extend'), a, b, i, z = function(a, b){
			if (!a.apply || !b.apply) 
				return false;
			return function(){
				this.parent = a;
				return b.apply(this, arguments);
			};
		};
		for (i in p) {
			a = t[i];
			b = p[i];
			if (a && a != b) 
				b = z(a, b) || b;
			t[i] = b;
		}
		return new Class(t);
	};
	c.implement = function(o){
		var i, p = this.prototype;
		for (i in o) 
			p[i] = o[i];
	};
	
	c.prototype = p;
	return c;
};


// Classe per il controllo dell'User Agent
var Agent = Class({
	value : '',
	__construct: function(o) {
		this.set(o);
	},
	set: function(o) {
		var u, t;
		if(o) {
			t = typeof o;
			if(t == 'string')
				u = o;
			else if(t == 'object' && o.value)
				u = o.value;
		}
		this.value = u || navigator.userAgent;
	},
	isMSIE: function(v){
		return (document.all && (v = this.value.match((new RegExp('(MSIE) (' + (v || '[0-9\.]+') + ')', 'i'))))) ? parseFloat(v[2], 10) : false;
	},
	isGecko: function(){
		var u = this.value;
		return (/Gecko/.test(u) && !(/Konqueror|Safari|KHTML/.test(u)));
	},
	isSafari: function(){
		return (/Safari/.test(this.value));
	},
	isKonqueror: function(){
		return (/Konqueror/.test(this.value));
	},
	isWebKit: function(){
		return (/WebKit/.test(this.value));
	},
	isNetscape: function(v){
		return ((v = (this.value).match((new RegExp('(Netscape|NS)[0-9]*[ /]{0,1}(' + (v || '[0-9\.]+') + ')', 'i'))))) ? parseFloat(v[2], 10) : false;
	},
	isFirefox: function(v){
		return ((v = (this.value).match((new RegExp('(Firefox|Minefield)/(' + (v || '[0-9\.]+') + ')', 'i'))))) ? parseFloat(v[2], 10) : false;
	},
	isOpera: function(v){
		return (window.opera && (v = (this.value).match((new RegExp('(Opera)[ \/](' + (v || '[0-9\.]+') + ')', 'i'))))) ? parseFloat(v[2], 10) : false;
	}
});


// Oggetto Element
var Element = {
	prototypize: function(e){
		if (!e || e._extended || e.nodeType != 1)
			return e;
		e._extended = true;
		//Element._extended.push(e);
		return Element.extend(e, Element._extensions);
	},
	extend: function(e, m, o){
		for (var i in m)
			if (!e[i] || o)
				e[i] = m[i];
		return e;
	},
	_extensions: {},
	implement: function(o){
		if (typeof o != 'object')
			throw new TypeError('Passed argument must be an object!');
		var i, m = Element._extensions, p = HTMLElement.prototype;
		for (i in o)
			p[i] = m[i] = o[i];
	},
	_extended: []
};


var GET = {};

// Inizializzatore del framework e prototipizzatore degli oggetti base
var __init = function() {
	var p = 'prototype',
		O = Object, Op = O[p],
		D = Date, Dp = D[p],
		S = String, Sp = S[p],
		Ap = Array[p],
		Np = Number[p],
		F = Function, Fp = F[p],
		M = Math,
		R = RegExp,
		ua = new Agent();

	Agent.MSIE = ua.isMSIE();
	Agent.Gecko = ua.isGecko();
	Agent.Safari = ua.isSafari();
	Agent.Konqueror = ua.isKonqueror();
	Agent.WebKit = ua.isWebKit();
	Agent.Opera = ua.isOpera();
	Agent.Firefox = ua.isFirefox();

	O.extend = function(e, o){
		e = e || {};
		o = o || {};
		for(var i in o)
			e[i] = o[i];
		return e;
	};

	D.now = function() {
		return new Date().getTime();
	};
	D.formats = {
		en: {
			m: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
			w: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
		},
		it: {
			m: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
			w: ['Domenica', 'LunedÏ', 'MartedÏ', 'MercoledÏ', 'GiovedÏ', 'VenerdÏ', 'Sabato']
		},
		es: {
			m: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
			w: ['Lunes', 'Martes', 'MiÈrcoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo']
		},
		fr: {
			m: ['Janvier', 'FÈvrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Ao˚t', 'Septembre', 'Octobre', 'Novembre', 'DÈcembre'],
			w: ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
		}
	};

	Dp.format = function(f, l){
		var c = Date.formats, n = new Date(),
		y = n.getFullYear(), m = n.getMonth() + 1, d = n.getDate(), w = n.getDay(),
		h = n.getHours(), g = h % 12 || 12, i = n.getMinutes(), s = n.getSeconds(), a = g == h ? 'am' : 'pm',
		// Get the number of days in current month
		na = new Date(y, m - 1, 1), nb = new Date(y, m, 1), t = ((na.getTime() - nb.getTime()) / 86400000).round() + 1;

		l = c[(l || 'en').toLowerCase()] || c.en;

		f = f.replace('G', h).replace('g', g).replace('H', h.zeroFill(2)).replace('h', g.zeroFill(2));
		f = f.replace('i', i.zeroFill(2)).replace('s', s.zeroFill(2));
		f = f.replace('Y', y).replace('y', y.zeroFill(2, true)).replace('n', m).replace('m', m.zeroFill(2));
		f = f.replace('j', d).replace('w', w).replace('t', t);

		e = /(a|A|M|F|D|l)/g;
		if(f.match(e))
			f = f.replace(e, function(s, b){
				switch (b) {
					case 'a':
						return a;
					case 'A':
						return a.toUpperCase();
					case 'M':
						return l.m[m - 1].substr(0, 3);
					case 'F':
						return l.m[m - 1];
					case 'D':
						return l.w[w].substr(0, 3);
					case 'l':
						return l.w[w];
				}
				return b;
			});
		return f;
	};

	S.random = function(l, c){
		c = c || "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
		for (var g = c.length, r = '', n, i = l || 8; i > 0; i--) {
			n = Math.floor(Math.random() * g);
			r += c.substring(n, n + 1);
		}
		return r;
	};

	Sp.cleanSize = function(a){
		var s = this, v = 0, u = '', e = s.match(/(-?[0-9\.]*)(in|cm|mm|pt|pc|em|ex|px|%)?/i);
		if (e) {
			v = parseFloat(e[1], 10);
			u = e[2];
			if (!v)
				v = 0;
			if (!u)
				u = '';
		}
		return (a) ? [v, u] : v;
	};
	
	// PHP Like	
	Sp.addSlashes = function() {
		return this.replace(/(\'|\"|\\|\0)/g, '\\$1');
	};
	Sp.stripSlashes = function() {
		return this.replace(/\\(\'|\"|\\|\0)/g, '$1');
	};
	Sp.htmlEntities = function () {
		return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
	};
	Sp.nl2br = function() {
		return this.replace(/[^>]\n/g, '<br/>');
	};
	Sp.stripTags = function() {
		return this.replace(/<[^>]+>/g, '');
	};

	Sp.has = function(s) {
		return (this.indexOf(s) >= 0);
	};
	Sp.trim = function() {
		return this.replace(/^\s+|\s+$/g, '');
	};
	Sp.ltrim = function() {
		return this.replace(/^\s+/g, '');
	};
	Sp.rtrim = function() {
		return this.replace(/^\s+$/g, '');
	};
	Sp.clean = function() {
		return this.replace(/\s{2,}/g, ' ').trim();
	};
	Sp.empty = function(s) {
		return (this.length === 0 || (s && this.match(/^[\s]*$/gm))) ? true : false;
	};
	Sp.toInt = function(i) {
		return parseInt(this, i || 10);
	};
	Sp.toFloat = function(i) {
		return parseFloat(this, i || 10);
	};
	Sp.camelCase = function() {
		return this.replace(/-\D/g, function(m) { return m.charAt(1).toUpperCase(); });
	};
	Sp.hyphenate = function(){
		return this.replace(/\w[A-Z]/g, function(m){
			return (m.charAt(0) + '-' + m.charAt(1).toLowerCase());
		});
	};
	Sp.capitalize = function(){
		return this.toLowerCase().replace(/\b[a-z]/g, function(m){
			return m.toUpperCase();
		});
	};
	Sp.parseCss = function() {
		for(var s = this, p = s.split(';'), r = {}, i = p.length - 1, d, n; i >= 0; i--) {
			d = p[i].split(':');
			n = d[0].trim().camelize();
			if(n) r[n] = d[1].trim();
		}
		return r;
	};

	Sp.whiteSpaceChar = function(i) {
		return (this.charCodeAt(i || 0) <= 32);
	};
	Sp.digitChar = function(i) {
		return ((i = this.charCodeAt(i || 0)) && i >= 48  && i <= 57);
	};
	Sp.letterChar = function(i) {
		return ((i = this.charCodeAt(i || 0)) && ((i >= 65  && i <= 90) || (i >= 97 && i <= 122)));
	};
	Sp.upperCaseChar = function(i) {
		return ((i = this.charCodeAt(i || 0)) && i >= 65  && i <= 90);
	};
	Sp.lowerCaseChar = function(i) {
		return ((i = this.charCodeAt(i || 0)) && i >= 97 && i <= 122);
	};

	Sp.isJSON = function() {
		return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''));
	};

	// Implementazioni dello standard
	if(!Ap.indexOf) {
		Ap.indexOf = function(v, b) {
			for(var i =+ b || 0, l = this.length; i < l; i++) if(this[i] === v) return i;
			return -1;
		};
	}
	// Nota: tolti i controlli rispetto allo standard
	if(!Ap.filter) {
		Ap.filter = function(f, t) {
			if(typeof f != "function") throw new TypeError();
			for(var a = this, l = a.length, r = [], i = 0, j = 0, o; i < l; i++) {
				o = a[i]; if(f.call(t, o, i, a)) r[j++] = o;
			}
			return r;
		};
	}
	if(!Ap.forEach) {
		Ap.forEach = function(f, t) {
			if(typeof f != "function")
				throw new TypeError();
			for(var i = 0, a = this, l = a.length; i < l; i++)
				f.call(t, a[i], i, a);
		};
	}
	Ap.each = Ap.forEach;
	if(!Ap.every) {
		Ap.every = function(f, t){
			for(var i = 0, a = this, l = a.length; i < l; i++) if(!f.call(t, a[i], i, a)) return false;
			return true;
		};
	}
	if(!Ap.map) {
		Ap.map = function(f, t) {
			if(typeof f != "function") throw new TypeError();
			for(var a = this, l = a.length, r = [], i = 0; i < l; i++) r = r.concat(f.call(t, a[i], i, a));
			return r;
		};
	}
	if(!Ap.some) {
		Ap.some = function(f, t){
			for(var i = 0, a = this, l = a.length; i < l; i++) if(f.call(t, a[i], i, a)) return true;
			return false;
		};
	}
	// Implementazioni personalizzate
	Ap.unique = function(b) {
		var a = [], i, l = this.length;
		for(i = 0; i < l; i++) if(a.indexOf(this[i], 0, b) < 0) a.push(this[i]);
		return a;
	};
	Ap.replace = function(f, p) {
		for(var r = [], i = this.length - 1; i >= 0 ; i--) r[i] = (this[i] === f) ? p : this[i];
		return r;
	};
	Ap.intersect = function(a) {
		var r = [], b = this, k = b.length, i, j = 0, c;
		for(i = 0; i < k; i++) {
			c = b[i];
			if(a.indexOf(c) >= 0) r[j++] = c;
		}
		return r;
	};
	Ap.remove = function(a) {
		var i = 0;
		while(i < this.length) if(this[i] === a) this.splice(i, 1); else i++;
		return this;
	};
	Ap.copy = function(s, l){
		var h = this.length, i, r = [];
		if (!s)
			s = 0;
		if (s < 0)
			s = h + s;
		if (!l)
			l = h - s;
		for (i = 0; i < l; i++)
			r[i] = this[s++];
		return r;
	};
	Ap.exists = function(i, s) {
		return this.indexOf(i, s) != -1;
	};
	Ap.has = Ap.exists;
	Ap.clean = function() {
		for(var a = this, r =[], j = 0, i = 0, l = a.length, e; i < l; i++) {
			e = a[i];
			if(e || e === 0) r[j++] = e;
		}
		return r;
	};
	Ap.nearest = function(o) {
		if(typeof o != 'number') return null;
		for(var a = this, r = null, e, d = null, n, i = a.length - 1; i >= 0; i--) {
			e = a[i];
			n = Math.abs(e - o);
			if(d === null || n < d) {
				d = n;
				r = e;
			}
		}
		return d;
	};
	Ap.randomize = function() {
		return this.copy().sort(Sort.random);
	};
	Ap.random = function() {
		return this[Math.floor(Math.random() * this.length)];
	};

	// ### Number prototypes
	Np.bound = function(n, m) {
		return this < n ? n : (this > m ? m : this);
	};
	Np.round = function(p) {
		p = Math.pow(10, p || 0);
		return Math.round(this * p) / p;
	};
	Np.ceil = function() {
		return Math.ceil(this);
	};
	Np.floor = function() {
		return Math.floor(this);
	};
	Np.pow = function(e) {
		return Math.pow(this, e);
	};
	Np.toInt = function(i) {
		return parseInt(this, i || 10);
	};
	Np.toFloat = function(i) {
		return parseFloat(this, i || 10);
	};
	Np.zeroFill = function(z, m){
		var i, r = '', n = this, l;
		n = parseInt(n, 10) + '';
		l = n.length;
		if (m && l > z)
			return n.substr(l - z, z);
		l = z - l;
		for (i = 0; i < l; i++)
			r += '0';
		return r + '' + n;
	};

	// Function Prototypes
	F.get = function(f) {
		var t = typeof f;
		if(t == 'function') return f;
		if(t == 'string') return new Function(f);
		return null;
	};
	F.empty = function(){};
	F.value = function(f){
		return (typeof f === 'function') ? f : function(){
			return f;
		};
	};

	Fp.interval = function(t, a) {
		var f = this, r = function() { f.apply(null, a || []); };
		return window.setInterval(r, t);
	};
	Fp.timeout = function(t, a) {
		var f = this, r = function() { f.apply(null, a || []); };
		return window.setTimeout(r, t);
	};
	Fp.tryCatch = function(t, a, f) {
		try {
			return this.apply(t, a || []);
		} catch(e) {
			return (f ||
			function(){
				return false;
			}).apply(t, e);
		}
	};

	// ### Math prototypes

	M.rand = function(n, m) {
		if(arguments.length < 2) {
			m = n;
			n = 0;
		}
		return (Math.random() * (m - n + 1) + n).floor();
	};
	M.rad = function(g) {
		return ((2 * Math.PI) / 360) * g;
	};
	p = 1.61803398874989484820458683;
	M.PHI = p;
	M.LOW_PHI = 1 / p;

	R.EMAIL = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	R.TIMESTAMP = /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/;
	R.URL = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;

	// eliminare il flickering su IE6
	if (ua.isMSIE(6))
		try {
			document.execCommand('BackgroundImageCache', false, true);
		} catch (e) {
		}


	//fix both IE and Opera (adjust when they implement this method properly)
	if (Agent.MSIE || ((Op = Agent.Opera) && Op < 9.5)) {
		document.nativeGetElementById = document.getElementById;
		//redefine it!
		document.getElementById = function(id){
			var o = document.nativeGetElementById(id);
			if (o) {
				// Verifica se l'elemento ottenuto ha l'id specificato
				if (o.id == id)
					return o;
				else {
					for (var i = 1, a = document.all[id], l = a.length; i < l; i++) {
						if ((o = a[i]).id == id)
							return o;
					}
				}
			}
			return null;
		};
	}

	// Costruttore di HTMLElement

	var h, d, e = {
		extend: function(m, o){
			Element.extend(this, m, o);
		}
	};
	if (typeof HTMLElement == 'undefined') {
		h = window.HTMLElement = function(){};
		p = document.createElement('div').__proto__;
		// Dovrebbe funzionare per Safari 1.3
		d = window["[[DOMElement.prototype]]"];
		if (d)
			h.prototype = d;
		// Dovrebbe funzionare per Safari 2
		else
			if ((d = document.createElement('html').constructor) && (d = d.__proto__) && (d = d.__proto__))
				h.prototype = d;
			// Dovrebbe funzionare se tutti gli elementi hanno lo stesso costruttore
			else
				if (p && p == document.createElement('span').__proto__)
					h.prototype = p;
				// SennÚ Ë un normale oggetto
				else
					h.prototype = {};
		if (typeof p == 'undefined') {
			h.prototype.__proto__ = e.__proto__ = h.prototype;
		}
	}
	HTMLElement.prototype._extended = true;
	Element.implement(e);
	
	
	// Ottengo i parametri passati via GET
	var q = unescape(window.location.search.substr(1)).split('&'), l = q.length, i, v;
	for (i = 0; i < l; i++) {
		if (!(p = q[i]))
			continue;
		p = p.split('=');
		GET[p[0]] = p[1] || '';
	}
	
};
__init();
delete __init;


function isArray(a) {
	return (a instanceof Array);
}


/**
 * @alias				isElement
 * @classDescription	Funzione per il controllo del tipo di oggetto Element
 * @param				{Object} element
 * @param				{String} tag
 * @return				{Boolean} Restituisce vero o falso
 */
function isElement(e, t) {
	if (t)
		return ((e = e.nodeName) && e.toLowerCase() == t.toLowerCase());
	return (e.nodeName && e.ownerDocument);
}

/**
 * @alias				isNumber
 * @classDescription	Funzione per la verifica della numericit‡
 * @param				{String,Number} number
 * @return				{Boolean} Restituisce vero o falso
 */
function isNumeric(n) {
	return !isNaN(parseInt(n, 10));
}

/**
 * @alias				isEnumerable
 * @classDescription	Funzione per verificare se il valore passato Ë un oggetto numerabile
 * @param				{Void} value
 * @return				{Boolean} Restituisce vero o falso
 */
function isEnumerable(o) {
	return (typeof o == 'object' && (o.constructor == Array || o.callee || typeof o.length == 'number'));
}

/**
 * @alias				is
 * @classDescription	Funzione per la verifica della validit‡ del valore
 * @param				{Void} value
 * @return				{Boolean} Restituisce vero o falso
 */
function is(v) {
	return (v !== false && v !== undefined && v !== null);
}

/**
 * @alias				Arr
 * @classDescription	Funzione per la conversione ad array dei tipi di dato listabili o altro
 * @param				{Void} value
 * @return				{Array} Restituisce l'array creato
 */
function Arr(a){
	for (var r = [], i = a.length - 1; i >= 0; i--)
		r[i] = a[i];
	return r;
}
/*function Arr(a){
	//if (isEnumerable(a)) {
		for (var r = [], i = a.length - 1; i >= 0; i--)
			r[i] = a[i];
		return r;
	//}
	return is(a) ? [a] : [];
}*/

function forEach(o, f, t, p){
	if (typeof f != 'function')
		throw new TypeError();
	var i, l;
	if (typeof o == 'object')
		for (i in o)
			f.call(t, o[i], i, o);
	else {
		if (f.construnctor != Array)
			o = [o];
		l = o.length;
		for (i = 0; i < l; i++)
			f.call(t, o[i], i, o);
	}
}

function test(){
	for (var i = 0, a = arguments, l = a.length, r = null; i < l; i++) {
		try {
			r = a[i].apply();
			break;
		} catch (e) {
		}
	}
	return r;
}

function exec(c) {
	return window.execScript ? window.execScript(c) : (this.eval ? this.eval(c) : eval(c));
}

function typeOf(o){
	var t = typeof o;
	if (t == 'object') {
		if (o === null)
			return 'null';
		if (o.constructor == Array)
			return 'array';
		if (o.constructor == Date)
			return 'date';
		if (o.nodeName)
			switch (o.nodeType) {
				case 1:
					return 'element';
				case 3:
					return 'textnode';
			}
		if (o.callee)
			return 'arguments';
		/*if (typeof o.length === 'number' && !(o.propertyIsEnumerable('length')))
			return 'list';*/
		if (o instanceof Error)
			return 'error';
	}
	return t;
}


function I(o, d){
	// Se non Ë stato specificato un documento o non Ë valido come documento, uso 'document'
	if (!d || !d.documentElement)
		d = document;
	// Se non Ë stato specificato un elemento ritorno document
	if (!o)
		return Element.prototypize(d);
	// Se Ë una stringa lo ottengo per id
	if (typeof o == 'string')
		return Element.prototypize(d.getElementById(o));
	// Se Ë qualcos'altro verifico che sia un elemento o un documento
	if (o.nodeName || d.getElementById)
		return Element.prototypize(o);
	return null;
}
if(!window.$)
	$ = I;

function T(t, e){
	return Arr((I(e) || document).getElementsByTagName(t || '*'));
}

function C(c, o, t){
	for (var a = T(t || '*', o), r = [], i = 0, l = a.length, j = 0; i < l; i++) {
		o = a[i];
		if (o.hasClass(c))
			r[j++] = o;
	}
	return r;
}

function N(n, o, t){
	for (var a = T(t || '*', o), r = [], i = 0, l = a.length, j = 0; i < l; i++) {
		o = a[i];
		if (o.getAttribute('name') == n)
			r[j++] = o;
	}
	return r;
}

function A(c, o, t){
	for (var a = T(t || '*', o), r = [], i = 0, l = a.length, j = 0; i < l; i--) {
		o = a[i];
		if (o.hasAttribute(c))
			r[j++] = o;
	}
	return r;
}

// Function to obtain a new Dom elements structure
// Modification of graft() function by Sean M. Burke from interglacial.com
// La funzione pi˘ utile del Dom
function D(t, o){
	var r;
	if (!t && t !== '')
		return null;
	var c = typeOf(t), l, e, m;
	if (c == 'array') {
		l = t.length;
		for (var i = 0; i < l; i++) {
			e = t[i];
			if (!e)
				return null;
			c = typeOf(e);
			if (i === 0 && c == 'string') {
				if (!(m = e.match(/^(\*|[a-z][a-z0-9]*)?(#([a-z][a-z0-9_-]*))?((\.[a-z][a-z0-9_-]*)+)?$/i)))
					return null;
				r = I(document.createElement(m[1]));
				if (m[2])
					r.setAttribute('id', m[3]);
				if (m[4])
					r.className = m[4].replace('.', ' ').trim();
			}
			else if (c == 'number' || c == 'string' || c == 'array' || c == 'element')
				D(e, r);
			else if (c == 'object')
+				r.set(e);
			else
				return null;
		}
	}
	else if (c == 'number' || c == 'string')
		r = document.createTextNode(t + '');
	else if(c == 'element')
		r = t;
	if (o)
		I(o).appendChild(r);
	return r;
}

// Function to obtain a group of elements by a css-like path
function P(p, e){
	p = p.replace('>', ' > ');
	p = p.replace(/(:[a-z][a-z0-9_-]*)/gi, ' $1 ');
	var s = [I(e)], t = p.split(/[\s]+/i), l = t.length, r, n, c, i, j, f, d, g, a = false;
	for (i = 0; i < l; i++) {
		d = t[i];
		if (!d)
			continue;
		g = s.length;
		if (d == '>')
			a = true;
		// Controllo primo figlio
		else if (d == ':first-child') {
			c = [];
			for (j = 0; j < g; j++) {
				f = s[j].first(true);
				if (f)
					c.push(f);
			}
			if (c.length === 0)
				return null;
			s = c;
			// Controllo prima lettera
		}
		else if (d == ':first-letter') {
			c = [];
			for (j = 0; j < g; j++) {
				f = s[j].firstLetter(true);
				if (f)
					c.push(f);
			}
			if (c.length === 0)
				return null;
			s = c;
		}
		else {
			r = null;
			// Controllo elemento
			m = d.match(/^(\*|[a-z][a-z0-9]*)/i);
			if (m) {
				n = m[1];
				if (n) {
					c = [];
					for (j = 0; j < g; j++)
						c = c.concat(T(n, s[j]));
					r = c;
					if (r.length === 0)
						return null;
				}
			}
			// Controllo id
			m = d.match(/#([a-z][a-z0-9_-]*)/i);
			if (m) {
				n = m[1];
				if (n) {
					c = [];
					for (j = 0; j < g; j++) {
						f = I(s[j].getElementById(n));
						if (f) {
							c = [f];
							break;
						}
					}
					r = (r) ? r.intersect(c) : c;
					if (r.length === 0)
						return null;
				}
			}
			// Controllo Classe
			m = d.match(/(\.[a-z][a-z0-9_-]*)+/i);
			if (m) {
				n = m[0];
				if (n) {
					c = [];
					for (j = 0; j < g; j++)
						c = c.concat(C(n, s[j]));
					r = (r) ? r.intersect(c) : c;
					if (r.length === 0)
						return null;
				}
			}
			// Controllo attributi
			m = d.match(/\[([a-z]+)((~|\^|\$|\*)?=?([^\]]*))\]?/i);
			if (m) {
				n = m[0];
				if (n) {
					c = [];
					for (j = 0; j < g; j++)
						c = c.concat(A(n, s[j]));
					r = (r) ? r.intersect(c) : c;
					if (r.length === 0)
						return null;
				}
			}
			// Controllo figli
			if (a && r) {
				c = [];
				for (j = 0; j < g; j++)
					c = c.concat(Arr(s[j].childNodes));
				r = (r) ? r.intersect(c) : c;
				if (r.length === 0)
					return null;
			}
			if (!r)
				return null;
			s = r;
		}
	}
	return s.unique();
}

function V(o, a){
	o = I(o);
	var n = o.nodeName.toLowerCase(), v = null;
	if (n == 'input' || n == 'textarea' || n == 'select' || n == 'option' || n == 'button') {
		v = o.value;
		if (a)
			o.value = a;
	}
	else {
		v = o.nodeValue;
		if (a)
			o.nodeValue = a;
	}
	return v;
}


var Dom = {
	spanSubtext: function(o, s, f){
		if (o.nodeType != 3) 
			throw new TypeError();
		var v = o.nodeValue, b = v.substring(s, f), r = D(['span', b]), l = v.length, a = [o];
		if (s > 0) 
			a.push(v.substring(0, s));
		a.push(r);
		if (f && f < l) 
			a.push(v.substring(f, l));
		Dom.after.apply(null, a);
		Dom.remove(o);
		return r;
	}	
};
var _Dom_implements = {
		getText: function() {
			var c = this.childNodes, l = c.length, i, o, t, r = '';
			for(i = 0; i < l; i++) {
				o = c[i];
				t = o.nodeType;
				if(t == 1)
					r += I(o).getText();
				else if(t == 3)
					r += o.nodeValue;
			}
			return r;
		},
		/*spanSubtext: function(s, f) {
			var v = o.nodeValue, b = v.substring(s, f), r = D(['span', b]), l = v.length, a = [o];
			if(s > 0)
				a.push(v.substring(0, s));
			a.push(r);
			if(f && f < l)
				a.push(v.substring(f, l));
			Dom.after.apply(null, a);
			o.remove();
			return r;
		},*/
		// Metodo che ritorna il primo nodo all'interno di quello passato
		first: function(t){
			var g = this.childNodes, i, c, l = g.length;
			if (t && l > 0)
				return I(g[0]);
			for (i = 0; i < l; i++) {
				c = g[i];
				if (c.nodeType == 1)
					return c;
			}
			return null;
		},
		last: function(t){
			var g = this.childNodes, i, c, l = g.length;
			if (t && l > 0)
				return g[l - 1];
			for (i = 0; i < l; i++) {
				c = g[i];
				if (c.nodeType == 1)
					return c;
			}
			return null;
		},
		next: function(t){
			var o = this.nextSibling;
			if (t && o)
				return o;
			while (o && (o = o.nextSibling))
				if (o.nodeType == 1)
					return o;
			return null;
		},
		// Metodo che ritorna il nodo precedente a quello passato
		prev: function(t){
			var o = this.previousSibling;
			if (t && o)
				return o;
			while (o && (o = o.previousSibling))
				if (o.nodeType == 1)
					return o;
			return null;
		},
		// Metodo che ritorna la prima lettera all'interno del nodo passato
		firstLetter: function(t){
			var g = this.childNodes, l = g.length, i, c, p;
			for (i = 0; i < l; i++) {
				c = I(g[i]);
				p = c.nodeType;
				if (p == 1) {
					p = c.firstLetter(t);
					if (p)
						return p;
				}
				else if (p == 3) {
					p = c.nodeValue;
					if (!p.match(/^[\s]*$/gm)) {
						if (t)
							return p.substr(0, 1);
						if (p.length == 1 && !c.previousSibling && !c.nextSibling && c.parentNode.nodeName.toLowerCase() == 'span')
							return c.parentNode;
						return Dom.spanSubtext(c, 0, 1);
					}
				}
			}
			return null;
		},
		//### Class Name Functions
		// Function to check if an element has a class name
		hasClass: function(s) {
			s = s.split(/[\.\s]+/gi);
			for(var o = this.className, j = s.length - 1, e; j >= 0; j--) {
				if((e = s[j])) {
					e = new RegExp("(^|\\s)" + e + "(\\s|$)", 'g');
					if(!e.test(o))
						return false;
				}
			}
			return true;
		},
		// Function to add one o more classnames to an element
		addClass: function(s){
			this.removeClass(s).className += ' ' + s.split(/[\.\s]+/g).join(' ');
			return this;
		},
		// Function to remove one or more classnames from an element
		removeClass: function(s){
			this.className = this.className.replace((new RegExp("(^|\\s+)(" + s.split(/[\.\s]+/gi).join('|') + ")(\\s+|$)", 'g')), ' ');
			return this;
		},
		getClasses: function() {
			return this.className.split(/[\.\s]+/gi);
		} ,
		switchClass: function(){
			for (var a = arguments, l = a.length, i = 0, e; i < l; i++) {
				e = a[i];
				if (this.hasClass(e)) {
					this.removeClass(e);
					e = (i == l - 1) ? a[1] : a[i + 1];
					this.addClass(e);
					return;
				}
			}
			this.addClass(a[1]);
			return this;
		},
		booClass: function(){
			for (var a = arguments, i = a.length - 1, e; i >= 0; i--) {
				e = a[i];
				if (this.hasClass(e))
					this.removeClass(e);
				else
					this.addClass(e);
			}
			return this;
		},
		//### End Class Name Functions
		// Function to remove elements
		remove: function(){
			this.parentNode.removeChild(this);
			return this;
		},
		// Function to append multiple elements to a specified element
		append: function() {
			for(var a = arguments, l = a.length, i = 0; i < l; i++)
				this.appendChild(D(a[i]));
			return this;
		},
		prepend: function(){
			for (var a = arguments, i = a.length - 1, f; i >= 0; i++) {
				n = D(a[i]);
				if ((f = o.firstChild))
					o.insertBefore(n, f);
				else
					o.appendChild(n);
			}
			return this;
		},
		// Function to insert a child before another
		before: function(){
			for (var a = arguments, p = this.parentNode, l = a.length, i = 0; i < l; i++)
				p.insertBefore(D(a[i]), this);
			return this;
		},
		// Function to insert a child after another
		after: function(){
			for (var a = arguments, p = this.parentNode, n, i = a.length - 1, c; i >= 0; i--) {
				c = D(a[i]);
				if ((n = o.nextSibling))
					p.insertBefore(c, n);
				else
					p.appendChild(c);
			}
			return this;
		},
		copy: function(d) {
			o = I(this.cloneNode(true));
			if(d)
				I(d).append(o);
			return o;
		},
		move: function(o, d) {
			d = o.copy(d);
			o.remove();
			return d;
		},
		childs: function() {
			for(var c = this.childNodes, r = [], j = 0, l = c.length, i = 0; i < l; i++) {
				o = c[i];
				if(o.nodeType == 1)
					r[j++] = o;
			}
			return r;
		},
		// Function to delete all child nodes of an element
		removeChilds: function() {
			while(this.hasChildNodes())
				this.removeChild(this.firstChild);
			return this;
		},
		// Function to move all child nodes of an element to all other elements
		moveChilds: function(d) {
			var f;
			d = I(d);
			while(this.hasChildNodes()) {
				f = this.firstChild;
				d.appendChild(f.cloneNode(true));
				this.removeChild(f);
			}
			return this;
		},
		replaceChilds: function() {
			this.removeChilds();
			this.append.apply(this, arguments);
			return this;
		},
		// Function to copy all child nodes of an element to all other elements
		copyChilds: function(d){
			this.moveChilds.apply(I(this.cloneNode(true)), d);
			return this;
		},
		into: function(t) {
			t = I(t);
			var o = this;
			do {
				if (o === t)
					return true;
			}
			while ((o = o.parentNode));
			return false;
		},
		get: function() {
			var a = arguments, l = a.length;
			if (l == 1) {
				if(a == 'class' || a == 'className')
					return this.className;
				return this.getAttribute(a[0]);
			}
			for(var i = 0, r = {}, c; i < l; i++) {
				c = a[i];
				r[c] = this.get(c);
			}
			return r;
		},
		// Function to set multiple attributes to a specified element
		set: function(k, v) {
			if (typeof k == 'object') 
				for (v in k)
					this.set(v, k[v]);
			else if (typeof v == 'function') 
				this.addEvent(k, v);
				//o[i] = function() { e.apply(this, arguments); };
			else if (k == 'class' || k == 'className') 
				this.addClass(v);
			else if (k == 'style') 
				this.setStyles(v);
			else 
				this.setAttribute(k, v);
			return this;
		},
		hasAttribute: function(c, d) {
			var e = '', v, m;
			if (typeof c == 'string') {
				if(d)
					c += '=' + d;
				if ((m = c.match(/^\[?([a-z]+)(\~|\^|\$|\*)?(\=([^\]]+))?\]?$/i))) {
					var a = m[1], s = m[4];
					//s.replace(/(\\|\.|\(|\)|\[|\]|\^|\$)/gmi, '\\' + '\\1');
					if((v = this.get(a))) {
						if (vm[3]) {
							switch(m[2]) {
								case '~':
									e = '(^|\\s)' + s + '(\\s|$)';
								break;
								case '^':
									e = '^' + s;
								break;
								case '$':
									e = s + '$';
								break;
								case '*':
									e = s;
								break;
								default:
									e = '^' + s + '$';
								break;
							}
							if (v.match((new RegExp(e))))
								return true;
						}
						return true;
					}
				}
				return false;
			}
			var j = 0, l;
			if(c instanceof Array) {
				for (j = 0, l = c.length; i < l; i++) 
					if (!this.hasAttribue(c[j]))
						return false;
				
			} else 
				for (j in c) 
					if(!this.hasAttribue(j, c[j]))
						return false;
			return true;
		},
		// Function to set the CSS style attribute to an element
		setStyles: function(s){
			var z = this.style, e = Agent.MSIE, i, c;
			if (typeof s == 'object') {
				var f = (e) ? 'styleFloat' : 'cssFloat';
				for (i in s) {
					c = s[i];
					if (i == 'opacity')
						this.setOpacity(c);
					else if (i == 'backgroundAlphaImage')
						this.alphabackground(c);
					else if (i == 'float')
						z[f] = c;
					else
						z[i] = c;
				}
			}
			else if (typeof s == 'string') {
				if (e)
					z.cssText = s;
				else
					this.setAttribute('style', s);
			}
			return this;
		},
		getStyle: function(s){
			if(s == 'opacity')
				return this.getOpacity();
			s = s.camelCase();
			var z = this.style, c = this.currentStyle, k = document.defaultView;
			c = c ? c : (k ? k.getComputedStyle(this, '') : {});
			s = z[s] || c[s] || '';
			return s;
		},
		// Function to obtain the values of requested style properties
		getStyles: function(){
			var a = arguments, r = {}, z = this.style, c = this.currentStyle, k = document.defaultView, e = null, i;
			c = c ? c : (k ? k.getComputedStyle(this, '') : {});
			for (i = a.length - 1; i >= 0; i--) {
				e = a[i].camelCase();
				r[e] = z[e] || c[e] || '';
			}
			return r;
		},
		switchStyle: function(){
			var a = arguments, n = a[0], s = this.getStyle(n), l = a.length, i;
			if (n.toLowerCase().has('color'))
				s = new Color(s).hex();
			for (i = 1, e; i < l; i++) {
				e = a[i];
				if (e == s) {
					e = (i == l - 1) ? a[1] : a[i + 1];
					this.style[n] = e;
					return;
				}
			}
			return this;
		},
		setOpacity: function(o){
			var s = this.style;
			o = o.toFloat();
			o = (o < 0.01) ? 0 : ((o > 1) ? 1 : o);
			if (Agent.MSIE)
				s.filter = this.getStyle('filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + (o * 100).round() + ')';
			else if (o === 1 && Agent.Gecko)
				s.opacity = 0.99;
			else
				s.opacity = o;
			return this;
		},
		getOpacity: function(){
			var o = 1, s = this.getStyles('filter', 'opacity');
			if (Agent.MSIE) {
				var e = s.filter.match(/alpha\([\s]*opacity=([0-9]+)[\s]*\)/i);
				if (e && e[1])
					o = e[1].toInt() / 100;
			}
			else
				o = s.opacity;
			if (!isNumeric(o))
				o = 1;
			return o.toFloat();
		},
		removeOpacity: function(){
			var s = this.style;
			if (Agent.MSIE)
				s.filter = this.getStyle('filter').replace(/alpha\([^\)]*\)/gi, '');
			else
				s.opacity = '';
			return this;
		},
		alphaBackground: function(o, m){
			var e = Agent.MSIE, s = this.style;
			if (e && e < 7) {
				if (m != 'crop' && m != 'image' && m != 'scale')
					m = 'crop';
				s.filter += 'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src=\'' + o + '\', sizingMethod=\'' + m + '\')';
			}
			else
				s.backgroundImage = 'url(\'' + o + '\')';
			return this;
		},
		// Corretto il bug con IE6 e position:absolute
		realHeight: function(v){
			var o = this.copy(), r = 0, s = o.style, g = this.getStyles('paddingTop', 'paddingBottom'), e = Agent.MSIE;
			s.visibility = 'hidden';
			s.display = 'block';
			s.height = 'auto';
			if (e && e < 7)
				s.position = 'absolute';
			if (v)
				s.width = v + 'px';
			this.before(o);
			r = o.clientHeight - (g.paddingTop + '').cleanSize() - (g.paddingBottom + '').cleanSize();
			o.remove();
			return r;
		},
		document: function(){
			var d = this.contentWindow || this.contentDocument || this.document || document, c;
			if (d)
				c = d.document;
			if (c)
				d = c;
			return d;
		},
		window: function() {
			return this.contentWindow || window;
		},
		insertText: function(t){
			var n = this.nodeName.toLowerCase();
			if (n == 'input' || n == 'select' || n == 'option' || n == 'textarea')
				o.value = t;
			else
				o.appendChild(document.createTextNode(t));
			return this;
		},
		getId: function(a){
			var r = this.getAttribute('id');
			if (!r)
				this.setAttribute('id', (r = 'random_id_' + String.random()));
			return r;
		},
		body: function() {
			return T('body', this.document())[0];
		},
		head: function() {
			return T('head', this.document())[0];
		},
		clearPosition: function(){
			var s = this.style;
			s.position = s.top = s.left = s.bottom = s.right = '';
		},
		position: function(p){
			var o = this, l = 0, t = 0, c;
			do {
				l += o.offsetLeft;
				t += o.offsetTop;
			}
			while ((o = o.offsetParent));
	
			if (p) {
				c = p.alignment;
				p = p.element;
				if (p) {
					p = p.position();
					l -= p[0];
					t -= p[1];
				}
				if (c) {
					var d = this.sizes();
					// Allineamento orrizzontale
					if (c == 2 || c == 5 || c == 8)
						l += Math.round(d[0] / 2);
					else
						if (c == 3 || c == 6 || c == 9)
							l += d[0];
					// Allineamento verticale
					if (c >= 4 && c <= 6)
						t += Math.round(d[1] / 2);
					if (c >= 7 && c <= 9)
						t += d[1];
				}
			}
			return [l, t];
		},
		sizes: function(o){
			return [this.offsetWidth, this.offsetHeight];
		},
		at: function(x, y){
			var p = this.position(), s = this.sizes(), l = p[0], t = p[1], w = s[0], h = s[1];
			return (x >= l && x < (l + w) && y >= t && y < (t + h));
		},
		disableSelect: function(){
			Event.add(this, 'selectstart', function(e){
				Event.stop(e);
				return false;
			});
			this.unselectable = "on";
			var s = this.style;
			s.MozUserSelect = "none";
			s.cursor = "default";
		}
};

Element.implement(_Dom_implements);


var JS_INCLUDES = {};

function include(u) {
	Load.javascript({
		url: u,
		append: true,
		defer: 'defer'
	});
	JS_INCLUDES[u] = (JS_INCLUDES[u] || 0) + 1;
	return true;
}

function include_once( filename ) {
	return JS_INCLUDES[u] ? false : include(filename);
}

var Load = {
	image: function(o){
		var g = new Image(), u = (o || (o = {})).url, oEr = o.onerror, oAb = o.onabort, oLo = o.onload;
		if (oLo)
			g.onload = function(){
				var ac = arguments.callee;
				if (ac.done)
					return false;
				ac.done = true;
				this.onload = null;
				return oLo.call(this);
			};
		if (oEr)
			g.onerror = oEr;
		if (oAb)
			g.onabort = oAb;
		g.src = u;
		return g;
	},
	images: function(o){
		var i = (o || (o = {})).images, l, j = 0, y = 0, r = [],
		oSt = o.onstart || Function.empty, p = oPr.onprogress || Function.empty, c = oCo.oncomplete || Function.empty;

		i = (i instanceof Array) ? i : [i];
		l = i.length;

		oSt(l);
		i.each(function(g){
			if (typeof g != 'object')
				g = {
					url: g
				};
			var oLo = g.onload || Function.empty, oEr = g.onerror || Function.empty, oAb = g.onabort || Function.empty;
			g.onload = function(e){
				oLo.call(this, e);
				j++;
				oPr.call(this, j, l);
				if (j == l)
					oCo(l);
			};
			g.onerror = function(e){
				oEr.call(this, e);
				j++;
				oPr.call(this, j, l);
				if (j == l)
					oCo(l);
			};
			g.onabort = function(e){
				oAb.call(this, e);
				j++;
				oPr.call(this, j, l);
				if (j == l)
					oCo(l);
			};
			r[y++] = Load.image(g);
		});
		return r;
	},
	css: function(o){
		return D(['link', {
			href: o.url,
			type: 'text/css',
			rel: (o.rel || 'stylesheet'),
			media: (o.media || 'screen')
		}], ((o.append) ? T('head')[0] : ''));
	},
	javascript: function(o){
		return D(['script', {
			src: o.url,
			type: 'text/javascript',
			defer: 'defer',
			id: (o.id || '')
		}], ((o.append) ? T('head')[0]: ''));
	}
};



var Sort = {
	random: function() {
		return 0.5 - Math.random();
		//return (Math.round(Math.random())-0.5);
	},
	number: function(a, b) {
		return a - b;
	},
	numberDesc: function(a, b) {
		return b - a;
	},
	string: function(a, b) {
		a = (a + '').toLowerCase();
		b = (b + '').toLowerCase();
		return a < b ? -1 : (a > b ? 1 : 0);
	},
	stringDesc: function(a, b) {
		a = (a + '').toLowerCase();
		b = (b + '').toLowerCase();
		return a < b ? 1 : (a > b ? -1 : 0);
	},
	date: function(a, b) {
		return a.getTime() - b.getTime();
	},
	dateDesc: function(a, b) {
		return b.getTime() - a.getTime();
	},
	natural: function(a, b){

		a += '';
		b += '';

		var cr = function(a, b){
			var bias = 0, ia = 0, ib = 0, ca, cb, da, db;

			while (true) {
				ca = a.charAt(ia++);
				cb = b.charAt(ib++);
				da = ca.digitChar();
				db = cb.digitChar();

				if (!da && !db)
					return bias;
				else if (!da)
					return -1;
				else if (!db)
					return +1;
				else if (ca < cb) {
					if (bias === 0)
						bias = -1;
				}
				else if (ca > cb) {
					if (bias === 0)
						bias = +1;
				}
				else if (ca === 0 && cb === 0)
					return bias;
			}
		};

		var ia = 0, ib = 0, na, nb, ca, cb, r;

		while (true) {
			na = nb = 0;

			while ((ca = a.charAt(ia++)) && (ca.whiteSpaceChar() || ca == '0'))
				if (ca == '0')
					na++;
				else
					na = 0;

			while ((cb = b.charAt(ib++)) && (cb.whiteSpaceChar() || cb == '0'))
				if (cb == '0')
					nb++;
				else
					nb = 0;

			if ((ca.digitChar() && cb.digitChar()) && ((r = cr(a.substring(ia), b.substring(ib))) !== 0))
				return r;

			if (ca === 0 && cb === 0)
				return na - nb;

			if (ca < cb)
				return -1;
			else if (ca > cb)
				return +1;
		}
	}
};


var Plugins = {
	_nsPlugins: {
		'SVG Viewer': 'image/svg-xml',
		'Shockwave Director': 'application/x-director',
		'Shockwave Flash': 'application/x-shockwave-flash',
		'RealPlayer': 'audio/x-pn-realaudio-plugin',
		'QuickTime': 'video/quicktime',
		'Windows Media Player': 'application/x-mplayer2',
		'Acrobat Reader': 'application/pdf'
	},
	_iePlugins: {
		'SVG Viewer': 'Adobe.SVGCtl',
		'Shockwave Director': 'SWCtl.SWCtl.1',
		'Shockwave Flash': 'ShockwaveFlash.ShockwaveFlash.1',
		'RealPlayer': 'rmocx.RealPlayer G2 Control.1',
		'QuickTime': 'QuickTimeCheckObject.QuickTimeCheck.1',
		'Windows Media Player': 'MediaPlayer.MediaPlayer.1',
		'Acrobat Reader': 'PDF.PdfCtrl.5'
	},
	_nsGetMimeTypes: function() {
		var i, m = navigator.mimeTypes, l = m.length, r = [];
		for (i = 0; i < l; i++) {
			k = m[i].type.toLowerCase();
			r[k] = m[k].enabledPlugin !== null;
		}
		return r;
	},
	detectPlugin: function() {
		var a = arguments, al = a.length, r = false, n = navigator, p = n.plugins, pl, i, j, f, c, d;

		if (p && (pl = p.length) > 0) {
			for(i = 0; i < pl; i++) {
				f = 0;
				c = p[i];
				for(j = 0; j < al; j++) {
					d = a[j];
					if(c.name.has(d) || c.description.has(d))
						f++;
				}
				if(f == al) {
					r = true;
					break;
				}
			}
		}
		return r;
	},
	flash: function(){
		var v = false, n = navigator, p = n.plugins, u = n.userAgent;
		if (p && n.mimeTypes.length) {
			var f = p['Shockwave Flash'];
			if (f && (f = f.description))
				v = f.replace(/([a-zA-Z]|\s)+/, '').replace(/(\s+r|\s+b[0-9]+)/, '.');
		} else {
			for (var i = 10, a; i >= 2; i--) {
				try {
					if ((a = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + i))) {
						v = i + '.0';
						break;
					}
				} catch (e) {
				}
			}
			if (a)
				v = a.GetVariable('$version').split(' ')[1].replace(/[^0-9]+/g, '.');
		}
		return v;
	},
	real: function() {

	},
	compareVersions: function(a, b){
		a = (a + '').split('.');
		b = (b + '').split('.');
		for (var i = 0, c, d; i < 3; i++) {
			c = a[i].toInt();
			d = b[i].toInt();
			if (c > d)
				return 1;
			if (c < d)
				return -1;
		}
		return 0;
	}
};

// Creo l'oggetto base
var _Embed_implements = {
	embed: function(o) {
		var u = o.url, t, m;

		if((m = u.match(/youtube\.com\/watch?v=(.+)/i)))
			u = 'http://www.youtube.com/v/' + m[1];
		else if ((m = u.match(/metacafe\.com\/watch\/([^\/]+\/[^\/]+)/i)))
			u = 'http://www.metacafe.com/fplayer/' + m[1] + '.swf';
		else if ((m = u.match(/google\.com\/videoplay?docid=(.+)/i)))
			u = 'http://video.google.com/googleplayer.swf?docId=' + m[1] + '&hl=en';
		else if ((m = u.match(/ifilm\.com\/video\/(.+)/i))) {
			u = "http://www.ifilm.com/efp";
			(o.flashvars || (o.flashvars = {})).flvbaseclip = m[1] + '&';
		}


		if (!o.type) {
			switch (u.split('?')[0].split('.').pop().toLowerCase()) {
				case 'wmv':
				case 'avi':
					t = {
						type: 'msvideo',
						controls: true
					};
				break;
				case 'mov':
				case 'mp4':
					t = {
						type: 'quicktime'
					};
				break;
				case 'swf':
					t = {
						type: 'flash'
					};
				break;
				case 'flv':
					t = {
						type: 'flashvideo'
					};
				break;
				case 'pdf':
					t = {
						type: 'pdf'
					};
				break;
			}
			o = Object.extend(t || {}, o);
		}

		var f = [[(/(youtube|dailymotion)/i), {
			type: 'flash',
			width: 425,
			height: 355
		}], [(/metacafe/i), {
			type: 'flash',
			width: 400,
			height: 345
		}], [(/ifilm/i), {
			type: 'flash',
			width: 448,
			height: 365
		}]], l = f.length, i, c;

		for (i = 0; i < l; i++) {
			c = f[i];
			if (u.match(c[0])) {
				o = Object.extend(c[1], o);
				break;
			}
		}
		
		c = o.controls ? 'true' : 'false';
		i = o.id || 'random_' + String.random();

		var a = o.autostart ? 'true' : 'false' ,
		bg = o.bgcolor, v = o.version, r, pr = '', fr = [], pa = o.params || {}, fv = o.flashvars || {}, j,
		gr  =	' width="' + (o.width || '100%') + '" height="' + (o.height || '100%') + '"' +
				' id="' + i + '" class="' + (o.className || o['class'] || '') + '"' +
				' name="' + (o.name || 'random_' + String.random()) + '"';

		bg = bg ? '<param name="bgcolor" value="' + bg + '" />' : '';

		for (j in pa)
			pr += '<param name="' + j + '" value="' + pa[j] + '" />';

		for (j in fv)
			fr.push(j + '=' + fv[j]);
		fr = fr.join('&');

		switch(o.type) {
			case 'flash':
			case 'swf':
				r = '<object type="application/x-shockwave-flash" data="' + u + '"' + gr + '>' +
					'<param name="movie" value="' + u + '" />' +
					'<param name="allowScriptAcess" value="sameDomain" />' +
					'<param name="quality" value="best" />' +
					bg +
					'<param name="scale" value="noScale" />' +
					'<param name="salign" value="TL" />' +
					'<param name="wmode" value="transparent" />' +
					'<param name="flashvars" value="playerMode=embedded&' + fr + '" />' +
					pr +
				'</object>';
			break;
			case 'flashvideo':
			case 'flv':
				r = '<object type="application/x-shockwave-flash" data="' + u + '"' + gr + '>' +
					'<param name="movie" value="' + u + '" />' +
					'<param name="allowScriptAcess" value="sameDomain" />' +
					'<param name="quality" value="best" />' +
					((bg) ? '<param name="bgcolor" value="' + bg + '" />' : '') +
					'<param name="scale" value="noScale" />' +
					'<param name="salign" value="TL" />' +
					'<param name="wmode" value="transparent" />' +
					'<param name="flashvars" value="playerMode=embedded" />' +
					pr +
				'</object>';
			break;
			case 'msvideo':
				r = '<object type="video/x-ms-wmv" data="' + u + '"' + gr + '>' +
					'<param name="src" value="' + u + '" />' +
					'<param name="autostart" value="' + a + '" />' +
					'<param name="controller" value="' + c + '" />' +
					//'<param name="showcontrols" value="' + c + '" />' +
					//'<param name="autosize" value="true" />' +
					//'<param name="uimode" value="mini" />' +
					pr +
				'</object>';
			break;
			case 'quicktime':
			case 'mov':
			case 'mp4':
				r = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"' + gr + '>' +
					'<param name="src" value="' + u + '" />' +
					'<param name="controller" value="' + c + '" />' +
					'<param name="autoplay" value="' + a + '" />' +
					pr +
					(!Agent.MSIE ?
					'<object type="video/quicktime" data="' + u + '"' + gr + '>' +
						'<param name="autoplay" value="' + a + '" />' +
						'<param name="controller" value="' + c + '" />' +
						pr +
					'</object>' : '') +
				'</object>';
			break;
			case 'pdf':
				r = '<object classid="clsid:CA8A9780-280D-11CF-A24D-444553540000"' + gr + '>' +
					'<param name="src" value="' + u + '" />' +
					pr +
					(!Agent.MSIE ?
					'<object type="application/pdf" data="' + u + '"' + gr + '>' +
						pr +
					'</object>' : '') +
				'</object>';
			break;
		}
		this.innerHTML = (o.replace ? '' : this.innerHTML) + (r || '');
		return I(i);
	}
};

Element.implement(_Embed_implements);

var IFrame = {
	focus: function(o){
		o = I(o);
		if (o.contentWindow)
			o.contentWindow.focus();
		else
			o.focus();
	}
};

var Window = Class({
	url: '',
	options: {},
	value: null,
	name: '',
	_construct: function(u, o) {
		this.set(u, o);
	},
	set: function(u, o) {
		if(u)
			this.url = u;
		if(o)
			this.options = o;
	},
	open: function() {
		var u = this.url, o = this.options, n = o.name || 'win_' + String.random(),
		w = o.width, h = o.height, aw = screen.availWidth, ah = screen.availHeight, sw = screen.width, sh = screen.height,
		x = 0, y = 0, a = '';
		if (o.fullscreen) {
			w = aw;
			h = ah;
		}
		if(o.center) {
			y = Math.floor((ah - (h || ah)) / 2) - (sh - ah);
			x = Math.floor((aw - (w || aw)) / 2) - (sw - aw);
		}
		if (w)
			a += 'width=' + w + ',';
		if (h)
			a += 'height=' + h + ',';
		a += 'screenx=' + x + ',screeny=' + y + ',left=' + x + ',top=' + y + ',';
		if(o.scrollbars)
			a += 'scrollbars=1,';
		if(o.menubar)
			a += 'menubar=1,';
		if(o.locationbar)
			a += 'location=1,';
		if(o.resizable)
			a += 'resizable=1,';
		this.name = n;
		return (this.value = window.open(u, n, a));
	}
});



var Env = {
	viewSize: function(){
		var e = document.documentElement, o = document.body, w, h, a, b;
		a = e.clientWidth;
		b = o.clientWidth;
		w = a && b ? (a < b ? a : b) : (a || b);
		a = e.clientHeight;
		b = o.clientHeight;
		h = a && b ? (a < b ? a : b) : (a || b);
		return [w, h];
	},
	pageScroll: function() {
		var e = document.documentElement, o = document.body;
		return [self.pageXOffset || e.scrollLeft || o.scrollLeft || 0, self.pageYOffset || e.scrollTop || o.scrollTop || 0];
	},
	maxScroll: function() {
		var p = Env.pageSize(), v = Env.viewSize();
		return [p[0] - v[0], p[1] - v[1]];
	},
	pageSize: function() {
		var o = document.body, n = window, e = document.documentElement, x = 0, y = 0, a, b;
		if ((a = e.clientHeight) && (b = n.scrollMaxY)) {
			x = e.clientWidth + n.scrollMaxX;
			y = a + b;
		} else {
			x = (a = o.scrollWidth) > (b = o.offsetWidth) ? a : b;
			y = (a = o.scrollHeight) > (b = o.offsetHeight) ? a : b;
		}
		return [x, y];
	},
	viewCenter: function(w, h, wd, hd) {
		var t = typeOf(w), c = Env.viewSize(), s = Env.pageScroll();
		if(t == 'array' || (t == 'element' && (w = I(w).sizes()))) {
			hd = wd;
			wd = h;
			h = w[1];
			w = w[0];
		}
		return [Math.round((c[0] - (w || 0)) * (wd || 0.5)) + s[0], Math.round((c[1] - (h || 0)) * (hd || 0.5)) + s[1]];
	},
	gridPosition: function(x, y, o){
		var s = Env.clientSizes(), c = (o || (o = {})).cols, r = o.rows, w = o.width, h = o.height, i = 0, xc = 0, yc = 0;
		w = c ? s[0] / c : w || 50;
		h = r ? s[1] / r : h || 50;
		while ((w * i) <= x)
			xc = i++;
		i = 0;
		while ((h * i) <= y)
			yc = i++;
		return [xc, yc];
	},
	generateGrid: function(w, h, n, s) {
		for(var i = 0, j = 0, x = 0, y = 0, r = []; i < n; i++, j++) {
			x = w * j;
			if ((x + w) > s) {
				x = j = 0;
				y += h;
			}
			r[i] = [x, y];
		}
		return r;
	},
	gridCoords: function(w, h, n, s) {
		s = Math.floor(s / w);
		return [((n % s) * w), Math.floor(n / s) * h];
	}
};

var Cookie = {
	set: function(n, v, o){
		var e = o.expire || 0, p = o.path, d = o.domain, s = o.secure;
		v = escape(v);
		e = new Date((new Date().getTime()) + (e * 1000)).toGMTString();
		document.cookie = n + '=' + v + '; expires=' + e +
		(p ? '; path=' + p : '') +
		(d ? '; domain=' + d : '') +
		(s ? '; secure' : '');
	},
	get: function(n){
		var e = new RegExp('(^|;)\\s*' + n + '=([^;]*)'), m = document.cookie.match(e), v;
		return (m && (v = m[1])) ? unescape(v) : null;
	},
	unset: function(n, o){
		(o || {}).expire = -(365 * 24 * 3600);
		Cookie.set(n, '', o);
	}
};

var Event = {
	mousePosition: function(e, o){
		if (!e)
			e = window.event;
		var x = 0, y = 0, a = e.pageX, b = e.clientX, c, d, p, g;
		if (a) {
			x = a;
			y = e.pageY;
		}
		else
			if (b) {
				c = document.body;
				d = document.documentElement;
				if (c && d) {
					x = b + c.scrollLeft + d.scrollLeft;
					y = e.clientY + c.scrollTop + d.scrollTop;
				}
			}
		if (o) {
			if (typeof o == 'boolean') {
				p = Env.pageScroll();
				return [x - p[0], y - p[1]];
			}
			o = I(o);
			p = Element.position(o);
			return [x - p[0], y - p[1]];
		}
		return [x, y];
	},
	fromElement: function(e) {
		if(!e) e = window.event;
		var r = e.relatedTarget || e.fromElement;
		return r;
	},
	toElement: function(e) {
		if(!e) e = window.event;
		var r = e.relatedTarget || e.toElement;
		return r;
	},
	exitElement: function(e, o) {
		if(!e) e = window.event;
		var t = e.target || e.srcElement, r = Event.toElement(e);
		while(r != t && r.nodeName != 'BODY') r = r.parentNode;
		if(r == t) return false;
		return true;
	},
	cancelBubble: function(e) {
		if(!e) e = window.event;
		e.cancelBubble=true;
	},
	getKey: function(e) {
		if(!e) e = window.event;
		var n = e.keyCode || e.which, k = String.fromCharCode(n),
		s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {code: n, key: k, shift: s, ctrl: c, alt: a};
	},
	checkKey: function(k) {
		var v = 0, n = k.code, m = Event.keysMap;
		if(n > 13 && n < 20) return false;
		v = ((k.shift) ? 4 : 0) + ((k.ctrl) ? 2 : 0) + ((k.alt) ? 1 : 0);
		for(var i = m.length - 1; i >= 0; i--) {
			var c = m[i];
			if(c[0] === n && c[1] == v)
				return c[2];
		}
		return false;
	},
	keysMap: [
		[8, 0, 'BackSpace'],
		[9, 0, 'Tab'],
		[9, 4, 'Btab'],
		[12, 0, 'CursorCenter'],
		[13, 0, 'Enter'],
		[19, 0, 'Pause'],
		[20, 0, 'CapsLock'],
		[27, 0, 'Escape'],
		[33, 0, 'PageUp'],
		[34, 0, 'PageDown'],
		[35, 0, 'End'],
		[35, 2, 'GoToBottom'],
		[36, 0, 'CursorHome'],
		[36, 2, 'ControlHome'],
		[37, 0, 'CursorLeft'],
		[38, 0, 'CursorUp'],
		[39, 0, 'CursorRight'],
		[40, 0, 'CursorDown'],
		[44, 0, 'Print'],
		[45, 0, 'Insert'],
		[46, 0, 'Delete'],
		[46, 4, 'EraseField'],
		[46, 2, 'EraseEOP'],
		[46, 1, 'ClearScreen'],
		[91, 0, 'LeftWin'],
		[92, 0, 'RightWin'],
		[144, 0, 'NumLock'],
		[145, 0, 'ScrollLock']
	],
	getButton: function(e) {
		if(!e) e = window.event;
		var n = e.button, l = false, m = false, r = false;
		if(n) {
			if(n & 1) l = true;
			if(n & 2) r = true;
			if(n & 4) m = true;
		} else {
			n = e.which;
			if(n == 1) l = true;
			if(n == 2) r = true;
			if(n == 3) m = true;
		}
		var s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {button: n, left: l, middle: m, right: r, shift: s, ctrl: c, alt: a};
	},
	getWheel: function(e) {
		if(!e) e = window.event;
		var d = e.detail;
		if(d) d = -d / 3;
		else {
			d = e.wheelDelta / 120;
			if(window.opera) d = -d;
		}
		var s = (e.shiftKey) ? true : false,
		c = (e.ctrlKey) ? true : false,
		a = (e.altKey) ? true : false;
		return {wheel: d, shift: s, ctrl: c, alt: a};
	},
	preventDefault: function(e) {
		if(!e) e = window.event;
		if(e.preventDefault) e.preventDefault();
		else e.returnValue = false;
	},
	stopPropagation: function(e){
		if(!e) e = window.event;
		if(e.stopPropagation) e.stopPropagation();
		else e.cancelBubble = true;
	},
	stop: function(e) {
		if(!e) e = window.event;
		Event.stopPropagation(e);
		Event.preventDefault(e);
		return false;
	},
	target : function(e) {
		if(!e) e = window.event;
		return e.target || e.srcElement;
	},
	add : function(o, t, f) {
		f = Function.get(f);
		if(typeof f !== 'function') throw new TypeError('Not a function');
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		if(t == 'domloaded') {
			if(o == window) Event._onDomLoaded.add(f);
		} else {

			if(t == 'scroll' && o == document && Agent.MSIE)
				o = window;

			var u = ['clickout', 'dblclickout', 'mousemoveout'];
			if(u.indexOf(t) >= 0) {
				var of = f, oo = o;
				o = document;
				t = t.replace(/out$/, '');
				f = function(e) {
					var p = Event.target(e), g = p;
					do { if(p === oo) return; } while((p = p.parentNode));
					of.call(g, e);
				};
			}
			if(!o._events) o._events = {};
			var e = o._events;
			if(!e[t]) e[t] = [];
			e[t].push(f);
			if(o.attachEvent) {
				o['e'+t+f] = f;
				o[t+f] = function(){o['e'+t+f](window.event);};
				o.attachEvent('on'+t, o[t+f]);
			} else {
				if(t == 'mousewheel') t = 'DOMMouseScroll';
				o.addEventListener(t, f, false);
			}
		}
	},
	remove: function(o, t, f) {
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		var e = o._events;
		if(e && e[t]) {
			e = e[t];
			for(var i = e.length - 1, a; i >= 0; i--) {
				a = e[i];
				if(a === f) {
					e[i] = e[e.length - 1];
					e.length--;
				}
			}
		}
		if(o.detachEvent) {
			o.detachEvent('on'+t, o[t+f]);
			o[t+f] = null;
		} else {
			if(t == 'mousewheel') t = 'DOMMouseScroll';
			o.removeEventListener(t, f, false);
		}
	},
	get: function(o, t) {
		o = I(o);
		t = t.toLowerCase().replace(/^on/, '');
		var e = o.events;
		return (e && e[t]) ? e[t] : [];
	},
	clone: function(o, u) {
		o = I(o);
		var e = o._events;
		if(e) {
			for(var t in e) {
				var a = e[t];
				for(var i = 0, l = a.length; i < l; i++) {
					Event.add(u, t, a[i]);
				}
			}
		}
	},
	/* onDomLoaded */
	_onDomLoaded: {
		cache: [],
		run: function() {
			var m = Event._onDomLoaded, e = m.cache, i, l = e.length;
			m.cache = [];
			for(i = 0; i < l; i++) e[i]();
		},
		/*executer: function() {
			var m = this, o = window.opera;
			onload = m.run;
			if(/WebKit|Konqueror/i.test(navigator.userAgent))
				(function() { if(/loaded|complete/.test(document.readyState)) m.callback(); else setTimeout(arguments.callee, 1); })();
			else if((!o || parseInt(o.version(), 10) >= 9) && document.addEventListener)
				document.addEventListener('DOMContentLoaded', Event._onDomLoaded.callback, false);
			else document.write('<scr' + 'ipt src="void(0)" defer="defer" onreadystatechange="if(this.readyState === \'complete\') Event._onDomLoaded.callback()"></scr'+'ipt>');
		},*/
		executer: function() {
			var m = this, a = Agent, o = a.Opera, t = window.setTimeout, d = document;
			//onload = m.run;
			if(a.Konqueror || a.WebKit)
				(function() { if(/loaded|complete/.test(d.readyState)) m.callback(); else t(arguments.callee, 1); })();
			else if((!o || o >= 9) && d.addEventListener)
				d.addEventListener('DOMContentLoaded', Event._onDomLoaded.callback, false);
			else if(Agent.MSIE)
				(function() { try{ d.documentElement.doScroll('left'); m.run(); } catch(e) { t(arguments.callee, 1); }})();
			else
				Event.add(window, 'load', m.run());
		},
		callback: function() { window.onload = null; Event._onDomLoaded.run(); },
		add: function(e) {
			var m = Event._onDomLoaded;
			if(m.cache.length === 0) m.executer();
			e = Function.get(e);
			m.cache.push(e);
		}
	},
	// onClickOut
	// Metodi per creare e eseguire eventi
	_eventTypes: {
		'DOMFocusIn': 'UIEvent',
		'DOMFocusOut': 'UIEvent',
		'DOMActivate': 'UIEvent',
		'focus': 'UIEvent',
		'blur': 'UIEvent',
		'click': 'MouseEvent',
		'mousedown': 'MouseEvent',
		'mouseup': 'MouseEvent',
		'mouseover': 'MouseEvent',
		'mousemove': 'MouseEvent',
		'mouseout': 'MouseEvent',
		'keydown': 'keyboardEvent',
		'keyup': 'KeyboardEvent',
		'textInput': 'TextEvent',
		'DOMSubtreeModified': 'MutationEvent',
		'DOMNodeInserted': 'MutationEvent',
		'DOMNodeRemoved': 'MutationEvent',
		'DOMNodeRemovedFromDocument': 'MutationEvent',
		'DOMNodeInsertedIntoDocument': 'MutationEvent',
		'DOMAttrModified': 'MutationEvent',
		'DOMCharacterDataModified': 'MutationEvent',
		'DOMElementNameChanged': 'MutationNameEvent',
		'DOMAttributeNameChanged': 'MutationNameEvent',
		'load': 'Event',
		'unload': 'Event',
		'abort': 'Event',
		'error': 'Event',
		'select': 'Event',
		'change': 'Event',
		'submit': 'Event',
		'reset': 'Event',
		'resize': 'Event',
		'scroll': 'Event'
	},
	getEventType: function(t) {
		t = t.replace(/^on/, '');
		var i, p = Event._eventTypes;
		for(i in p) if(t == i) return p[i];
		return null;
	},
	create: function(t, m) {
		var e = null, c;
		// Mozilla / DOM
		if(document.createEvent) {
			c = Event.getEventType(t);
			if(c) {
				e = document.createEvent(c);
				m = Event.cleanEventProperties(m);
				switch(c) {
					case 'Event':
						e.initEvent(t, m.bubbles, m.cancelable);
					break;
					case 'UIEvent':
						e.initUIEvent(t, m.bubble, m.cancelable, m.view, m.detail);
					break;
					case 'MouseEvent':
						e.initMouseEvent(t, m.bubble, m.cancelable, m.view,
							m.detail, m.screenX, m.screenY, m.clientX, m.clientY,
							m.ctrlKey, m.altKey, m.shiftKey, m.metaKey,
							m.button, m.relatedTarget);
					break;
					case 'KeyboardEvent':
						e.initKeyEvent(t, m.bubble, m.cancelable, m.view,
							m.ctrlKey, m.altKey, m.shiftKey, m.metaKey,
							m.keyCode, m.charCode);
					break;
					case 'MutationEvent':
						e.initMutationEvent(t, m.bubble, m.cancelable, m.relatedNode,
							m.prevValue, m.newValue, m.attrName, m.attrChange);
					break;
					case 'MutationNameEvent':
						e.initMutationNameEvent(t, m.bubble, m.cancelable, relatedNode, prevNamespaceUri, prevNodeName);
					break;
					case 'TextEvent':
						e.initTextEvent(t, m.bubble, m.cancelable, m.view, m.data);
					break;
					case 'PopupBlocked':
						e.initPopupBlockedEvent();
					break;
					case 'XULCommandEvent':
						e.initCommandEvent();
					break;
					default:
						e = null;
					break;
				}
			}
		// MSIE
		} else if(document.createEventObject) {
			e = document.createEventObject();
			if(m) Tools.object(e, m);
		}
		return e;
	},
	fire: function(o, t, e) {
		o = I(o);
		t = t.replace(/^on/, '');
		if(!e) e = Event.create(t, e);
		// MSIE
		if(o.fireEvent) {
			o.fireEvent('on' + t, e);
		} else if(o.dispatchEvent) {
			o.dispatchEvent(e);
		}
	},
	cleanEventProperties: function(p) {
		if(!p) p = {};
		return Tools.object({
			altKey: false,
			bubbles: true,
			button: 0,
			cancelable: true,
			//cancelBubble: false,
			charCode: 0,
			clientX: 0,
			clientY: 0,
			ctrlKey: false,
			currentTarget: null,
			detail: 0,
			eventPhase: null,
			//explicitOriginalTarget: null,
			isChar: false,
			keyCode: 0,
			layerX: 0,
			layerY: 0,
			metaKey: false,
			//originalTarget: null,
			pageX: 0,
			pageY: 0,
			relatedTarget: null,
			screenX: 0,
			screenY: 0,
			shiftKey: false,
			target: null,
			timeStamp: 0,
			type: '',
			view: window,
			which: 0
		}, p);
	}
};

var _Event_implements = {
	addEvent: function(e, f){
		Event.add(this, e, f);
		return this;
	},
	removeEvent: function(e, f){
		Event.remove(this, e, f);
		return this;
	},
	getEvent: function(e){
		return Event.getEvent(this, e);
	}
};

Element.implement(_Event_implements);

var Cinematic = Class({
	_interval: null,
	_func: '',
	_stepTime: 0,
	step: 0,
	__construct: function(f, o) {
		this._init(f, o);
	},
	_init: function(f, o){
		o = o || {};
		var t = o.time || 1, fps = o.fps || 25, w = (o.wait || 0) * 1000, st = (t * fps).floor(), i = 0, ff, self = this, args, tg = o.target;
		this._func = function(){
			var args = [self.step++, st, self];
			f.apply(tg, args);
			if (self.step == st) 
				clearInterval(self._interval);
		};
		this._stepTime = (1000 / fps).round();
	},
	start: function() {
		var ff;
		this._interval = ff = setInterval(this._func, this._stepTime);
	},
	pause: function() {
		clearInterval(this._interval);
	},
	stop: function() {
		this.pause();
		this.step = 0;
	}
});

var Scroll = Cinematic.extend({
	__construct: function(o) {
		
		var s = Env.pageScroll(), sx = s[0], sy = s[1], f = Scroll.validate(o.x || sx, o.y || sy), dx = f[0] - sx, dy = f[1] - sy, e = o.effect || Effects.linear, px, py;
		
		this._init(function(i, t){
			
			px = e(i, sx, dx, t);
			py = e(i, sy, dy, t);
			
			window.scrollTo(px, py);
		}, o);
		this.start();
		
	}
});
Scroll.validate = function(x, y) {
	var m = Env.maxScroll();
	return [Math.min(x || 0, m[0]), Math.min(y || 0, m[1])];
};


var Point = Class({
	x: 0,
	y: 0,
	__construct: function(x, y) {
		var t = typeOf(x);
		if (t == 'array' || (t == 'element' && (x = I(x).position(y)))) {
			y = x[1];
			x = x[0];
		} else if(t == 'object') {
			y = x.y;
			x = x.x;
		}
		this.x = x || 0;
		this.y = y || 0;
	},
	toArray: function() {
		return [this.x, this.y];
	},
	toString: function() {
		return this.x + ', ' + this.y;
	},
	distance: function(x, y) {
		var p = new Point(x, y), px = p.x, py = p.y, tx = this.x, ty = this.y;
		px = px > tx ? px - tx : tx - px;
		py = py > ty ? py - ty : ty - py;
		return Math.sqrt((px * px) + (py * py));
	}
});


// Morph Constants
var ACTUAL = 'actual';
var ORIGINAL = 'original';

var Morph = {
	// Inizializza la propriet‡ privata per gli elementi in morphing
	_init: function(o){
		// Ottengo o creo
		var m = o._morph || (o._morph = {
			// Gli stili originali
			originals: {},
			// Lista animazioni in pausa
			paused: [],
			// La cache interna degli eventi
			cache: []
		}), n = m.paused.shift();
		// I frames dell'animazione attuale
		m.frames = [];
		// Flag per idicare se l'elemento Ë animato
		m.animated = false;
		// Flag per bloccare l'inizio di nuove animazioni
		m.locked = false;
		// La chiave del loop attuale
		m.loop = null;
		if(n)
			o.morph(n);
		return o;
	},
	// Inizializzatore del morphing
	_core: function(u, o) {
		var i = u.getId(),
		mor = u._morph,
		styles = o.styles, style, j, ll,								// Gli stili, lo stile, la chiave e i passi
		fps = o.fps || 25,												// Il framerate
		t = ((o.time || 1) * fps).round(), lastFrame = t - 1,			// Il numero di frames totali
		e = o.effect || Effects.linear, ee,								// L'effetto generale e specifico
		r = (o.wait || 0) * 1000,										// Il tempo di attesa prima dell'inizio
		c = ['in', 'cm', 'mm', 'pt', 'pc', 'em', 'ex', 'px', '%'], unit,// Le unit‡ di misura dei css
		act, orig,
		p, g,
		ii, jj, yy,
		ss, ff,
		m, mm = null,
		exec = [], args = [], ar;

		for(j in styles) {
			// Controllo che lo stile sia un array
			style = ((style = styles[j]).constructor != Array) ? [style] : style.copy();

			// Ottengo lo stile attuale
			act = u.getStyle(j);

			// Se lo stile attuale Ë un colore diverso nel formato rg o hsl lo converto
			/*if(Color.isColor(act))
				act = new Color(act).hex();*/

			// Ottengo lo stile originale e nel caso lo setto
			orig = mor.originals[j];
			orig = (!is(orig)) ? (mor.originals[j] = act) : orig;

			// Sostituisco gli stili attuali e originali
			style = style.replace(ACTUAL, act).replace(ORIGINAL, orig);

			// Se il primo elemento Ë una funzione la estraggo e la considero come effetto
			ee = (typeof style[0] == 'function') ? style.shift() : e;

			// Se il primo elemento Ë una unit‡ di misura la estraggo e la conservo
			unit = (c.has(style[0])) ? style.shift() : '';

			// Lunghezza dell'array
			ll = style.length;

			// Indice di scorrimento dei frame
			yy = 0;

			// Se Ë un colore
			//if(Color.isColor(style[0])) {
			if(j.toLowerCase().has('color')) {
				if(ll < 2) {
					style = [act].concat(style);
					ll++;
				}
				p = (t / (ll - 1)).round();
				var s0, s1, s2, f0, f1, f2;
				for(ii = 0; ii < (ll - 1); ii++) {

					// Ottengo i colori 2 alla volta
					ss = new Color(style[ii]);
					s0 = ss.red;
					s1 = ss.green;
					s2 = ss.blue;

					ff = new Color(style[ii + 1]);
					f0 = ff.red;
					f1 = ff.green;
					f2 = ff.blue;

					g = (ii > 0) ? p + 1 : p;

					for(jj = 0; jj < g; jj++) {
						if(ii === 0 || (ii > 0 && jj > 0)) {
							m = (new Color([
								(ee(jj, s0, (f0 - s0), g - 1)).floor(),
								(ee(jj, s1, (f1 - s1), g - 1)).floor(),
								(ee(jj, s2, (f2 - s2), g - 1)).floor()
							])).rgb();
							if (m !== mm) {
								ar = args[yy];
								if (!ar)
									exec[yy] = args[yy] = '';
								exec[yy] += 's.' + j + '="' + m + '";';
								args[yy] += ((!ar) ? '' : ',') + '"' + j + '":"' + m + '"';
								mm = m;
							}
							yy++;
						}
					}
				}
			} else if(unit || typeof style[0] == 'number') {
				if(ll < 2) {
					style = [(act+'').cleanSize()].concat(style);
					ll++;
				}

				p = (t / (ll - 1)).round();

				for (ii = 0; ii < (ll - 1); ii++) {
					// Ottengo i passi 2 alla volta
					ss = (style[ii] + '').cleanSize();
					ff = (style[ii + 1] + '').cleanSize();
					g = (ii > 0) ? p + 1 : p;
					for (jj = 0; jj < g; jj++) {
						if (ii === 0 || (ii > 0 && jj > 0)) {
							m = ee(jj, ss, (ff - ss), g - 1);
							if (!isNaN(m)) {
								m = ((unit == 'em' || unit === '') ? (m * 100).floor() / 100 : m.floor()) + unit;
								if ((m || m === 0) && m !== mm) {
									ar = args[yy];
									if (!ar)
										exec[yy] = args[yy] = '';
									exec[yy] += (j == 'opacity') ? 'u.setOpacity(' + m + ');' : 's.' + j + '="' + m + '";';
									args[yy] += ((!ar) ? '' : ',') + '"' + j + '":"' + m + '"';
									mm = m;
								}
							}
							yy++;
						}
					}
				}
			} else {
				if (ll < 2) {
					style = [style[0], style[0]];
					ll++;
				}
				p = (t / (ll - 1)).round();

				m = style[0];
				if(!args[0])
					exec[0] = args[0] = '';
				exec[0] += 's.' + j + '="' + m + '";';
				args[0] += '"' + j + '":"' + m + '"';

				for (ii = 1; ii < lastFrame; ii++) {
					if (ii % p === 0) {
						m = style[(ii / p)];
						ar = args[ii];
						if (!ar)
							exec[ii] = args[ii] = '';
						exec[ii] += 's.' + j + '="' + m + '";';
						args[ii] += ((!ar) ? '' : ',') + '"' + j + '":"' + m + '"';
					}
				}

				m = style[ll - 1];
				ar = args[lastFrame];
				if(!ar)
					exec[lastFrame] = args[lastFrame] = '';
				exec[lastFrame] += 's.' + j + '="' + m + '";';
				args[lastFrame] += ((!ar) ? '' : ',') + '"' + j + '":"' + m + '"';
			}

			/* Non dovrebbe pi˘ servire, mah
			if(unit)
				style = [unit].concat(style);
			if(e !== ee)
				style = [ee].concat(style);
			styles[j] = style;*/

		}

		// Istanzio le nuove variabili
		var oSt = o.onstart, oFi = o.onfinish, oCh = o.onchange, oFr = o.onframe,
		oAr, k = 0, str, frames = [], fCount = 0,
		init = 'var u = document.getElementById("' + i + '"), s = u.style, m = u._morph;';

		j = 0;
		fps = 1000 / fps;

		// onStart // per il frame iniziale, prima di settare i nuovi stili
		if(oSt) {
			mor.cache[k] = oSt;
			oSt = 'm.cache[' + k++ + '].apply(u,';
		}
		// onChange // per i frame non vuoti
		if (oCh) {
			mor.cache[k] = oCh;
			oCh = 'm.cache[' + k++ + '].apply(u,';
		}
		// onFrame // per ogni frame
		if (oFr) {
			mor.cache[k] = oFr;
			oFr = 'm.cache[' + k++ + '].apply(u,';
		}
		// onFinish // per il frame finale, dopo aver settato gli stili
		if (oFi) {
			mor.cache[k] = oFi;
			oFi = 'm.cache[' + k++ + '].apply(u,';
		}

		while(j < t) {
			str = '';

			// Lista degli argomenti passati ai vari eventi
			oAr = '[{' + (args[j] || '') + '},' + (j + 1) + ',' + t + ']);';

			// Se Ë il frame 0 e non coincide con l'ultimo, inserisco onstart
			if (j === 0 && j != lastFrame && oSt)
				str += oSt + oAr;

			// Ottengo i nuovi cambiamenti
			m = exec[j];

			// Inserisco i nuovi stili
			str += (m || '');

			// Se c'Ë un cambiamento in questo frame o Ë l'ultimo frame inserisco onchange
			if (oCh && (m || j == lastFrame))
				str += oCh + oAr;

			// Inserisco onframe
			if (oFr)
				str += oFr + oAr;

			// Se Ë l'ultimo frame
			if (j == lastFrame) {
				// Resetto la propriet‡ con i dati dell'animazione
				str += 'Morph._init(u);';
				if (oFi)
					str += oFi + oAr;
			}

			// Passo al frame successivo
			j++;

			if (str) {
				frames[fCount++] = setTimeout(init + 'm.frames.shift();' + str, ((fps * j) + r).round());
				//I('try').value += init + 'm.frames.shift();' + str + '\n';
			}
		}

		mor.frames = frames;
		mor.locked = o.locked || false;
		mor.animated = true;
	}
};

var _Morph_implements = {
	morph: function(o){
		var m = this._morph || Morph._init(this);
		if (m.animated) {
			if (o.stop && !m.locked) 
				Morph._core(this.stopMorph(), o);
			else 
				m.paused.push(o);
		}
		else 
			Morph._core(this, o);
		return this;
	},
	forceMorph: function(o){
		o.stop = true;
		return this.morph(o);
	},
	loopMorph: function(o){
		var oFi = o.onfinish;
		o.onfinish = function(){
			if (oFi) 
				oFi.apply(this);
			this.morph(o);
		};
		this.morph(o);
	},
	// Ferma il morphing
	stopMorph: function(){
		var m, f, g, l;
		if ((m = this._morph)) {
			f = m.frames;
			l = f.length;
			for (i = 0; i < l; i++) 
				clearTimeout(f[i]);
			m.paused = [];
		}
		Morph._init(this);
		return this;
	}
};

// Implemento il morph
Element.implement(_Morph_implements);

// Animazioni avanzate
var Fx = {
	_implements: {
		//### Opacity
		opacityUp: function(o){
			((o || (o = {})).styles || (o.styles = {})).opacity = [ACTUAL, 1];
			return this.morph(o);
		},
		opacityDown: function(o){
			((o || (o = {})).styles || (o.styles = {})).opacity = [ACTUAL, 0];
			return this.morph(o);
		},
		opacityShift: function(o){
			return this[(this.getOpacity() < 0.5 ? 'opacityUp' : 'opacityDown')](o);
		},
		//### Opacity Pulse
		opacityPulse: function(o){
			var r = [ACTUAL], t = (o || (o = {})).hits || 3;
			for (i = 0; i < t; i++)
				r = r.concat([0, 1]);
			(o.styles || (o.styles = {})).opacity = r;
			return this.morph(o);
		},
		//### Blind
		blindInit: function(c){
			var s = this.style;
			s.overflow = 'hidden';
			s.display = 'block';
			if (c)
				s.height = '0px';
			return this;
		},
		blindUp: function(o){
			this.blindInit();
			((o || (o = {})).styles || (o.styles = {})).height = ['px', ACTUAL, 0];
			if (!o.effect)
				o.effect = Effects.outCubic;
			return this.morph(o);
		},
		blindDown: function(o){
			this.blindInit();
			((o || (o = {})).styles || (o.styles = {})).height = ['px', ACTUAL, this.realHeight()];
			if (!o.effect)
				o.effect = Effects.outCubic;
			return this.morph(o);
		},
		blindShift: function(o){
			return this[(this.blindState() > 0.5 ? 'blindUp' : 'blindDown')](o);
		},
		blindState: function(){
			return this.getStyle('height').cleanSize() / this.realHeight();
		},
		// Effetti complessi
		foldUp: function(o){
			var e = (o || (o = {})).effect || Effects.outCubic, z = (o.styles ||
			{}), t = (o.time || 1) / 2, n = this.getStyle('height').cleanSize(), h = this.realHeight();
			this.blindInit();

			return this.morph({
				onstart: o.onstart,
				styles: {
					height: ['px', ACTUAL, 5]
				},
				effect: e,
				time: t
			}).morph({
				styles: {
					width: ['px', ACTUAL, 0],
					height: ['px', ACTUAL, 0]
				},
				onfinish: o.finish,
				effect: e,
				time: t
			});
		},
		drop: function(o){
			var s = this.getStyles('height', 'position', 'top'), t = s.top.cleanSize(), h = s.height.cleanSize();
			if (s.position != 'absolute')
				this.style.position = 'relative';
			s = (o || (o = {})).styles || (o.styles = {});
			if (!o.effect)
				o.effect = Effects.outCubic;
			s.opacity = [1, 0];
			s.top = ['px', t, t + h];
			return this.morph(o);
		},
		vanish: function(o){
			var s = this.getStyles('width', 'height', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'fontSize'),
			w = s.width.cleanSize(true), h = s.height.cleanSize(true), f = s.fontSize.cleanSize(true);
			if (f[0] === 0)
				f = [1, 'em'];
			s = (o || (o = {})).styles || (o.styles = {});
			if (!o.effect)
				o.effect = Effects.outCubic;
			s.opacity = [1, 0];
			s.width = [w[1], w[0], (w[0] * 2)];
			s.height = [h[1], h[0], (h[0] * 2)];
			s.fontSize = [f[1], f[0], (f[0] * 2)];
			o.onframe = function(){
				var s = this.getStyles('width', 'height'), z = this.style;
				z.marginTop = z.marginBottom = ((h[0] - s.height.cleanSize()) / 2) + h[1];
				z.marginLeft = z.marginRight = ((w[0] - s.width.cleanSize()) / 2) + w[1];
			};
			this.morph(o);
		},
		vclose: function(o){
			var s = this.getStyles('height', 'marginTop', 'marginBottom', 'fontSize'),
			n = s.height.cleanSize(), f = s.fontSize.cleanSize(true), h = this.realHeight(i), z = this.style;
			s = (o || (o = {})).styles || (o.styles = {});
			if (!o.effect)
				o.effect = Effects.outCubic;
			this.blindInit();

			h = (h > n) ? h : n;

			if(f[0] === 0)
				f = [1, 'em'];

			//s.opacity = [1, 0];
			//s.fontSize = [f[1], f[0], 0];

			s.height = ['px', h, 0];

			o.onframe = function(s){
				var a = (s.height || this.getStyle('height')).cleanSize();
				z.marginTop = ((h - a) / 2) + 'px';
				z.marginBottom = ((h - a) / 2) + 'px';
			};
			Morph.set(o);
		},
		animage: function(o){
			if (o) {
				var u = o.url, w = o.width, h = o.height, v = o.vertical, f = o.frames, d = 1000 / (o.fps || 25), p = (o.pause || 0) * 1000, l = o.loop || Infinity, i = 'animage_' + String.random(), s = o.style ||
				{}, g = new Image(), iw, ih, self = this;

				o = D(['div', {
					style: {
						//display: 'inline-block',
						width: w + 'px',
						height: h + 'px',
						backgroundImage: 'url("' + u + '")',
						backgroundRepeat: 'no-repeat',
						backgroundPosition: '0px 0px'
					},
					id: i,
					className: 'animage'
				}], self);

				g.onload = function(){
					iw = g.width;
					ih = g.height;

					if (v) {
						f = f || (ih / h).floor();
						w = 0;
					}
					else {
						f = f || (iw / w).floor();
						h = 0;
					}

					var a = 0, s = o.style, m = function(){
						var t = d;
						if (a === 0 || a == f) {
							a = 0;
							t += p;
							l--;
						}
						if (l > 0) {
							s.backgroundPosition = "-" + (w * a) + "px -" + (h * a) + "px";
							a++;
							setTimeout(m, t);
						}
					};

					m();
				};
				g.src = u;
			}
			return this;
		},
		colors: function(){
			return this.getStyles('backgroundColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'color');
		},
		hide: function() {
			this.style.display = 'none';
			return this;
		},
		show: function() {
			this.style.display = 'block';
			return this;
		},
		tooltip: function(o) {

			var e = this,
			// Cerco il titolo da inserire nell'attributo 'title' se non Ë stato specificato
			t = o.title || this.getAttribute('title'),
			// Cerco il contenuto da inserire nell'attributo 'alt' se non Ë stato specificato
			m = o.content || this.getAttribute('alt'),
			// Se non Ë stato settato un target uso l'elemento del tooltip
			g = o.target || this,
			oSh = o.onshow, oMo = o.onmove, oHi = o.onhide, c = o.className || 'tooltip',
			// Cerco eventuali offset
			f = o.offset || {}, fx = f.x || 16, fy = f.y || 16,
			s = o.style || {}, p = o.position, b, d;

			// Aggiungo position:relative agli stili
			s.position = 'relative';

			// Creo l'elemento del tooltip e gli eventuali per il titolo e contenuto
			b = ['div', {
				style: s,
				className: c
			}];

			if(t)
				b.push(['div', {className: 'title'}, t]);
			if(m)
				b.push(['div', {className: 'content'}, m]);

			// Creo l'elemento tooltip
			b = D(b);

			// Creo l'elemento contenitore del tooltip
			d = D(['div', {
					style: {
						position: 'absolute',
						top: '0px',
						left: '0px',
						zIndex: '1000',
						display: 'none'
					}
				},
				b
			], T('body')[0]);

			if (p && p.constructor == Array) {
				s = d.style;
				s.visibility = 'hidden';
				s.display = 'block';
				n = b.sizes();
				s.visibility = '';
				s.display = 'none';

				c = p[1];

				// Allineamento orrizzontale
				if (c == 2 || c == 5 || c == 8)
					fx -= Math.round(n[0] / 2);
				else if (c == 3 || c == 6 || c == 9)
					fx -= n[0];

				// Allineamento verticale
				if (c >= 4 && c <= 6)
					fy -= Math.round(n[1] / 2);
				if (c >= 7 && c <= 9)
					fy -= n[1];

				p = p[0];
			}

			// Setto gli eventi
			Event.add(this, 'mouseover', function(ev){
				var s = d.style, m = p ? g.position({
					alignment: p
				}) : Event.mousePosition(ev);

				s.left = (m[0] + fx) + 'px';
				s.top = (m[1] + fy) + 'px';

				if (oSh)
					oSh.call(b, ev);

				s.display = 'block';
			});

			Event.add(this, 'mousemove', function(ev){
				var s = d.style, m = p ? g.position({
					alignment: p
				}) : Event.mousePosition(ev);

				s.left = (m[0] + fx) + 'px';
				s.top = (m[1] + fy) + 'px';

				if (oMo)
					oMo.call(b, ev);
			});

			Event.add(this, 'mouseout', function(ev){
				if (oHi)
					oHi.call(b, ev);
				else
					d.style.display = 'none';
			});
			return this;
		}
	},
	// #############################################
	// Non usa il morph
	makeTabs: function(a) {
		for(var l = (a = P(a)).length, f = false, i = 0, b, s, d; i < l; i++) {
			b = I(a[i]);
			if(isElement(b, 'a')) {
				d = I(b.getAttribute('href').split('#')[1]);
				if (d) {
					s = d.style;
					if (!f) {
						s.display = 'block';
						b.addClass('active');
						f = true;
					}
					else {
						s.display = 'none';
						s.height = '0px';
						d.setOpacity(0);
					}
					Event.add(b, 'click', function(e){
						if (this.hasClass('active'))
							return false;

						var h = null, j = 0, b, s = I(this.getAttribute('href').split('#')[1]);
						for (j = 0; j < l; j++) {
							b = a[j];
							if (isElement(b, 'a')) {
								if (b.hasClass('active')) {
									h = I(b.getAttribute('href').split('#')[1]);
									b.removeClass('active');
									break;
								}
							}
						}

						if (h) {
							h.blindUp({
								styles: {
									opacity: [1, 0],
									display: ['block', 'none']
								},
								onfinish: function(){
									s.blindDown({
										styles: {
											opacity: [0, 1],
											display: ['block']
										},
										time: 0.5
									});
								},
								time: 0.5
							});
						}
						else {
							s.blindDown({
								styles: {
									opacity: [0, 1],
									display: ['block']
								},
								time: 0.5
							});
						}
						this.addClass('active');
						return false;
					});

				}
			}
		}
	},
	IEAlphaPngFix: function() {
		var e = Agent.MSIE,a = arguments;
		if(!e || e < 5.5 || e >= 7)
			return false;
		(a.length > 0 ? Arr(a) : T('img')).forEach(function(o) {
			o = I(o);
			var s = o.src;
			if (s.match(/^[^\?]+\.png(\?.*)?(#.*)?$/gi)) {
				var a = {}, i = o.id, c = o.className, g = o.align, t, n;
				if (i)
					a.id = i;
				if (c)
					a.className = c;
				if ((t = o.title || o.alt))
					a.title = t;

				a.style = 'width:' + o.width + 'px;height:' + o.height + 'px;display:inline-block;' +
					(g == 'left' ? 'float:left;' : (g == 'right' ? 'float:right;' : '')) +
					(o.parentElement.href ? 'cursor:hand;' : '') + o.style.cssText +
					';filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + s + '\', sizingMethod=\'scale\');';

				n = D(['span', a]);
				o.after(n);
				Event.clone(o, n);
				o.remove();
			}
		});
	}
};

Element.implement(Fx._implements);

// Easing Equations from Robert Penner http://www.robertpenner.com/
var Effects = {
	linear: function (t, b, c, d) {
		return c*t/d + b;
	},
	inQuad: function(t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	outQuad: function(t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	inOutQuad: function(t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	inCubic: function (t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	outCubic: function (t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	inOutCubic: function (t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	inQuart: function (t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	outQuart: function (t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	inOutQuart: function (t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	inQuint: function (t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	outQuint: function (t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	inOutQuint: function (t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	inSine: function (t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	outSine: function (t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	inOutSine: function (t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	inExpo: function (t, b, c, d) {
		return (t===0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	outExpo: function (t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	inOutExpo: function (t, b, c, d) {
		if (t===0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	inCirc: function (t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	outCirc: function (t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	inOutCirc: function (t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	inElastic: function (t, b, c, d, a, p) {
		if (t===0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*0.3; if(!a) a=0;
		var s;
		if (a < Math.abs(c)) { a=c; s=p/4; }
		else s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	outElastic: function (t, b, c, d, a, p) {
		if (t===0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*0.3; if(!a) a=0;
		var s;
		if (a < Math.abs(c)) { a=c; s=p/4; }
		else s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	inOutElastic: function (t, b, c, d, a, p) {
		if (t===0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(0.3*1.5); if(!a) a=0;
		var s;
		if (a < Math.abs(c)) { a=c; s=p/4; }
		else s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -0.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
	},
	inBack: function (t, b, c, d, s) {
		if (s === undefined)
			s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	outBack: function (t, b, c, d, s) {
		if (s === undefined)
			s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	inOutBack: function (t, b, c, d, s) {
		if (s === undefined) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	inBounce: function (t, b, c, d) {
		return c - Effects.outBounce (d-t, 0, c, d) + b;
	},
	outBounce: function (t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
		}
	},
	inOutBounce: function (t, b, c, d) {
		if (t < d/2) return Effects.inBounce (t*2, 0, c, d) * 0.5 + b;
		return Effects.outBounce (t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
	}
};

// Estendo le Easing Equations Basi con quelle personali
Object.extend(Effects, {
	circleY: function(t, b, c, d) {
		return (c * Math.sin(t / d * 2 * Math.PI)) + b;
	},
	circleX: function(t, b, c, d) {
		return (c * Math.cos(t / d * 2 * Math.PI)) + b;
	},
	outSpiralY: function(t, b, c, d) {
		return ((c / d * t) * Math.sin(t / d * 2 * Math.PI)) + b;
	},
	outSpiralX: function(t, b, c, d) {
		return ((c / d * t) * Math.cos(t / d * 2 * Math.PI)) + b;
	},
	inSpiralY: function(t, b, c, d) {
		return ((c / d * (d-t)) * Math.sin(t / d * 2 * Math.PI)) + b;
	},
	inSpiralX: function(t, b, c, d) {
		return ((c / d * (d-t)) * Math.cos(t / d * 2 * Math.PI)) + b;
	}
});

var _DRAG_ACTIVE = null;
var _DRAG_INIT = false;

// Drag
Element.implement({
	enableDrag: function() {
		var d = this._drag;
		if(d)
			d.disabled = false;
		return this;
	},
	disableDrag: function() {
		var d = this._drag;
		if(d)
			d.disabled = true;
		return this;
	},
	makeDraggable : function(o) {
		var u = this;

		u._drag = {
			xS: 0,
			yS: 0,
			xD: 0,
			yD: 0,
			mD: 0,
			dragging: false,
			onstart: o.onstart,
			onmove: o.onmove,
			onfinish: o.onfinish,
			disabled: false
		};

		// Inizializzo il drag se non Ë gi‡ stato fatto
		if(!_DRAG_INIT) {
			// Al movimento del mouse nel documento
			Event.add(document, 'mousemove', function(e){
				if (_DRAG_ACTIVE) {
					var c = _DRAG_ACTIVE._drag;
					if (!c.disabled) {
						if (!e)
							e = window.event;
						var x = parseInt(e.clientX, 10), y = parseInt(e.clientY, 10), oMo = c.onmove,
						xD = c.xS - x, yD = c.yS - y, mD = Math.sqrt((xD * xD) + (yD * yD));
						c.xD = xD;
						c.yD = yD;
						c.mD = mD;
						c.xS = x;
						c.yS = y;
						if (oMo)
							oMo.call(_DRAG_ACTIVE, e, xD, yD, mD);
					}
					return Event.stop(e);
				}
			});
			// Al rilascio del mouse nel documento
			Event.add(document, 'mouseup', function(e) {
				if(_DRAG_ACTIVE) {
					var c = _DRAG_ACTIVE._drag;
					if(!c.disabled) {
						var oFi = c.onfinish;
						c.dragging = false;
						if (oFi)
							oFi.call(_DRAG_ACTIVE, (e || window.event));
						_DRAG_ACTIVE = null;
					}
				}
			});
		}
		// Alla pressione del mouse sopra all'elemento
		Event.add(u, 'mousedown', function(e){
			var c = this._drag;
			if (!c.disabled) {
				var s = c.onstart;
				c.xS = parseInt(e.clientX, 10);
				c.yS = parseInt(e.clientY, 10);
				c.dragging = true;
				if (s)
					s.call(this, (e || window.event));
				_DRAG_ACTIVE = this;
			}
		});
		/*
		// Al rilascio del mouse sopra all'elemento
		Event.add(u, 'mouseup', function() {
			var c = this._xDrag;
			if(!c.disabled) {
				var f = o.onfinish;
				c.dragging = false;
				if(f) f.apply(this);
				Drag._active = null;
			}
		});
		*/
		this.disableSelect();
	}
});


var Color = Class({
	red: 0,
	green: 0,
	blue: 0,
	alpha: 1,
	_names: {
		AliceBlue: '#F0F8FF',
		AntiqueWhite: '#FAEBD7',
		Aqua: '#00FFFF',
		Aquamarine: '#7FFFD4',
		Azure: '#F0FFFF',
		Beige: '#F5F5DC',
		Bisque: '#FFE4C4',
		Black: '#000000',
		BlanchedAlmond: '#FFEBCD',
		Blue: '#0000FF',
		BlueViolet: '#8A2BE2',
		Brown: '#A52A2A',
		BurlyWood: '#DEB887',
		CadetBlue: '#5F9EA0',
		Chartreuse: '#7FFF00',
		Chocolate: '#D2691E',
		Coral: '#FF7F50',
		CornflowerBlue: '#6495ED',
		Cornsilk: '#FFF8DC',
		Crimson: '#DC143C',
		Cyan: '#00FFFF',
		DarkBlue: '#00008B',
		DarkCyan: '#008B8B',
		DarkGoldenRod: '#B8860B',
		DarkGray: '#A9A9A9',
		DarkGrey: '#A9A9A9',
		DarkGreen: '#006400',
		DarkKhaki: '#BDB76B',
		DarkMagenta: '#8B008B',
		DarkOliveGreen: '#556B2F',
		Darkorange: '#FF8C00',
		DarkOrchid: '#9932CC',
		DarkRed: '#8B0000',
		DarkSalmon: '#E9967A',
		DarkSeaGreen: '#8FBC8F',
		DarkSlateBlue: '#483D8B',
		DarkSlateGray: '#2F4F4F',
		DarkSlateGrey: '#2F4F4F',
		DarkTurquoise: '#00CED1',
		DarkViolet: '#9400D3',
		DeepPink: '#FF1493',
		DeepSkyBlue: '#00BFFF',
		DimGray: '#696969',
		DimGrey: '#696969',
		DodgerBlue: '#1E90FF',
		FireBrick: '#B22222',
		FloralWhite: '#FFFAF0',
		ForestGreen: '#228B22',
		Fuchsia: '#FF00FF',
		Gainsboro: '#DCDCDC',
		GhostWhite: '#F8F8FF',
		Gold: '#FFD700',
		GoldenRod: '#DAA520',
		Gray: '#808080',
		Grey: '#808080',
		Green: '#008000',
		GreenYellow: '#ADFF2F',
		HoneyDew: '#F0FFF0',
		HotPink: '#FF69B4',
		IndianRed : '#CD5C5C',
		Indigo : '#4B0082',
		Ivory: '#FFFFF0',
		Khaki: '#F0E68C',
		Lavender: '#E6E6FA',
		LavenderBlush: '#FFF0F5',
		LawnGreen: '#7CFC00',
		LemonChiffon: '#FFFACD',
		LightBlue: '#ADD8E6',
		LightCoral: '#F08080',
		LightCyan: '#E0FFFF',
		LightGoldenRodYellow: '#FAFAD2',
		LightGray: '#D3D3D3',
		LightGrey: '#D3D3D3',
		LightGreen: '#90EE90',
		LightPink: '#FFB6C1',
		LightSalmon: '#FFA07A',
		LightSeaGreen: '#20B2AA',
		LightSkyBlue: '#87CEFA',
		LightSlateGray: '#778899',
		LightSlateGrey: '#778899',
		LightSteelBlue: '#B0C4DE',
		LightYellow: '#FFFFE0',
		Lime: '#00FF00',
		LimeGreen: '#32CD32',
		Linen: '#FAF0E6',
		Magenta: '#FF00FF',
		Maroon: '#800000',
		MediumAquaMarine: '#66CDAA',
		MediumBlue: '#0000CD',
		MediumOrchid: '#BA55D3',
		MediumPurple: '#9370D8',
		MediumSeaGreen: '#3CB371',
		MediumSlateBlue: '#7B68EE',
		MediumSpringGreen: '#00FA9A',
		MediumTurquoise: '#48D1CC',
		MediumVioletRed: '#C71585',
		MidnightBlue: '#191970',
		MintCream: '#F5FFFA',
		MistyRose: '#FFE4E1',
		Moccasin: '#FFE4B5',
		NavajoWhite: '#FFDEAD',
		Navy: '#000080',
		OldLace: '#FDF5E6',
		Olive: '#808000',
		OliveDrab: '#6B8E23',
		Orange: '#FFA500',
		OrangeRed: '#FF4500',
		Orchid: '#DA70D6',
		PaleGoldenRod: '#EEE8AA',
		PaleGreen: '#98FB98',
		PaleTurquoise: '#AFEEEE',
		PaleVioletRed: '#D87093',
		PapayaWhip: '#FFEFD5',
		PeachPuff: '#FFDAB9',
		Peru: '#CD853F',
		Pink: '#FFC0CB',
		Plum: '#DDA0DD',
		PowderBlue: '#B0E0E6',
		Purple: '#800080',
		Red: '#FF0000',
		RosyBrown: '#BC8F8F',
		RoyalBlue: '#4169E1',
		SaddleBrown: '#8B4513',
		Salmon: '#FA8072',
		SandyBrown: '#F4A460',
		SeaGreen: '#2E8B57',
		SeaShell: '#FFF5EE',
		Sienna: '#A0522D',
		Silver: '#C0C0C0',
		SkyBlue: '#87CEEB',
		SlateBlue: '#6A5ACD',
		SlateGray: '#708090',
		SlateGrey: '#708090',
		Snow: '#FFFAFA',
		SpringGreen: '#00FF7F',
		SteelBlue: '#4682B4',
		Tan: '#D2B48C',
		Teal: '#008080',
		Thistle: '#D8BFD8',
		Tomato: '#FF6347',
		Turquoise: '#40E0D0',
		Violet: '#EE82EE',
		Wheat: '#F5DEB3',
		White: '#FFFFFF',
		WhiteSmoke: '#F5F5F5',
		Yellow: '#FFFF00',
		YellowGreen: '#9ACD32'
	},
	__construct: function(c) {
		this.set(c);
	},
	set: function(c) {
		if(c) {
			var r = 0, g = 0, b = 0, a = 1;
			if(typeof c == 'string') {
				c = c.replace(/[\s]+/g, '');
				var i, n = this._names, m;
				if(c.match(/^[a-z]+$/gi)) {
					c = c.toLowerCase();
					for (i in n) {
						if (c == i.toLowerCase()) {
							c = n[i];
							break;
						}
					}
				}
				//if((/^#[0-9A-F]{3,8}$/gi).test(c)) {
				if(c.match(/^#[0-9A-F]{3,8}$/gi)) {
					a = 'FF';
					switch(c.length) {
						case 5:
							a = c.substring(4, 5);
							a += a;
						case 4:
							r = c.substring(1, 2);
							g = c.substring(2, 3);
							b = c.substring(3, 4);
							r += r;
							g += g;
							b += b;
						break;
						case 9:
							a = c.substring(7, 9);
						default:
						case 7:
							r = c.substring(1, 3);
							g = c.substring(3, 5);
							b = c.substring(5, 7);
						break;
					}
					r = r.toInt(16);
					g = g.toInt(16);
					b = b.toInt(16);
					a = a.toInt(16) / 255;
				} else if((m = c.match(/rgb\(([0-9]+%?),([0-9]+%?),([0-9]+%?)\)/i)) || (m = c.match(/rgba\(([0-9]+%?),([0-9]+%?),([0-9]+%?),([0-9\.]+%?)\)/i))) {
					r = m[1]; g = m[2]; b = m[3]; a = m[4];
					r = r.toInt() * (r.has('%') ? 2.55 : 1);
					g = g.toInt() * (g.has('%') ? 2.55 : 1);
					b = b.toInt() * (b.has('%') ? 2.55 : 1);
					a = (a) ? (a.has('%') ? a.toInt() * 2.55 : a.toFloat()) : 1;
				} else  if((m = c.match(/cmyk\(([0-9]+%?),([0-9]+%?),([0-9]+%?),([0-9]+%?)\)/i)) || (m = c.match(/cmyka\(([0-9]+%?),([0-9]+%?),([0-9]+%?),([0-9]+%?),([0-9\.]+%?)\)/i))) {
					var y = m[3], k = m[4];
					c = m[1]; m = m[2];
					c = c.toInt() * (c.has('%') ? 2.55 : 1);
					m = m.toInt() * (m.has('%') ? 2.55 : 1);
					y = y.toInt() * (y.has('%') ? 2.55 : 1);
					k = (255 - (k.toInt() * (k.has('%') ? 2.55 : 1))) / 255;
					r = (255 - c) * k;
					g = (255 - m) * k;
					b = (255 - y) * k;
					a = (a) ? (a.has('%') ? a.toInt() * 2.55 : a.toFloat()) : 1;
				} else if((m = c.match(/hsl\(([0-9]+),*([0-9]+)%,*([0-9]+)%\)/i)) || (m = c.match(/hsla\(([0-9]+),*([0-9]+)%,*([0-9]+)%,([0-9\.]+%?)\)/i))) {
					var h = m[1].toInt() / 360, s = m[2].toInt() / 100, l = m[3].toInt() / 100,
					f = function(m1, m2, h) {
						if(h < 0) h = h + 1;
						if(h > 1) h = h - 1;
						if(h * 6 < 1) return m1 + (m2 - m1) * h * 6;
						if(h * 2 < 1) return m2;
						if(h * 3 < 2) return m1 + (m2 - m1) * (2 / 3 - h) * 6;
						return m1;
					};
					s = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
					l = l * 2 - s;
					r = f(l, s, h + 1 / 3) * 255;
					g = f(l, s, h) * 255;
					b = f(l, s, h - 1 / 3) * 255;
					a = m[4];
					a = (a) ? (a.has('%') ? a.toInt() * 2.55 : a.toFloat()) : 1;
				}
			} else if(c.constructor == Array) {
				r = c[0];
				g = c[1];
				b = c[2];
				a = c[3];
				if(!is(a)) a = 1;
			} else if(c.red || c.green || c.blue || c.alpha) {
				r = c.red;
				g = c.green;
				b = c.blue;
				a = c.alpha;
			}
			this.red = r.bound(0, 255);
			this.green = g.bound(0, 255);
			this.blue = b.bound(0, 255);
			this.alpha = a.bound(0, 1);
		}
		return false;
	},
	media: function() {
		var a = arguments, l = a.length, i, c, r = 0, g = 0, b = 0;
		for(i = l - 1; i >= 0; i--) {
			c = new Color(a[i]);
			r += c.red;
			g += c.green;
			b += c.blue;
		}
		this.set([r / l, g / l, b / l]);
	},
	hex: function(a) {
		var f = function(o) {
			o = o.bound(0, 255);
			return (o < 16 ? '0' : '')  + o.toString(16);
		};
		return ('#' + f(this.red) + f(this.green) + f(this.blue) + (a ? f(this.alpha * 255) : '')).toUpperCase();
	},
	rgb: function() {
		return 'rgb(' + this.red + ',' + this.green + ',' + this.blue + ')';
	},
	rgba: function() {
		return 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',' + this.alpha + ')';
	},
	sepia: function() {
		var r = this.red, g = this.green, b = this.blue;
		return new Color([
			((r * 0.393) + (g * 0.769) + (b * 0.189)).round(),
			((r * 0.349) + (g * 0.686) + (b * 0.168)).round(),
			((r * 0.272) + (g * 0.534) + (b * 0.131)).round(),
			this.alpha
		]);
	},
	negative: function(c) {
		return new Color([255 - this.red, 255 - this.green, 255 - this.blue, this.alpha]);
	},
	grayscale: function(f) {
		var a = this.red, b = this.blue, c = this.green, r;
		switch(f) {
			case 1: case 'SimpleAverage':
				r = [((a + b + c) / 3).round(),
					((a + b + c) / 3).round(),
					((a + b + c) / 3).round()];
			break;
			case 2: case 'WeightAverage':
				r = [((3 * a) + (4 * c) + (2 * b) / 9).round(),
					((3 * a) + (4 * c) + (2 * b) / 9).round(),
					((3 * a) + (4 * c) + (2 * b) / 9).round()];
			break;
			case 3: case 'CCIRRec709':
				r = [((0.2125 * a) + (0.7154 * b) + (0.0721 * c)).round(),
					((0.2125 * a) + (0.7154 * b) + (0.0721 * c)).round(),
					((0.2125 * a) + (0.7154 * b) + (0.0721 * c)).round()];
			break;
			default: case 4: case 'NtscPal':
				r = [((0.299 * a) + (0.587 * b) + (0.114 * c)).round(),
					((0.299 * a) + (0.587 * b) + (0.114 * c)).round(),
					((0.299 * a) + (0.587 * b) + (0.114 * c)).round()];
			break;
		}
		r[3] = this.alpha;
		return new Color(r);
	},
	colorize: function(f) {
		f = new Color(f);
		var a = this.red, b = this.green, c = this.blue, x = f.red, y = f.green, z = f.blue;
		return new Color([
			((a * (x / 255)) + (b * (x / 255)) + (c * (x / 255))).round(),
			((a * (y / 255)) + (b * (y / 255)) + (c * (y / 255))).round(),
			((a * (z / 255)) + (b * (z / 255)) + (c * (z / 255))).round(),
			this.alpha
		]);
	},
	color: function(f) {
		var r = this.red, g = this.green, b = this.blue, a = this.alpha;
		f = new Color(f);
		return new Color([
			r + (r / 100 * f.red).round(),
			g + (g / 100 * f.green).round(),
			b + (b / 100 * f.blue).round(),
			this.alpha
		]);
	},
	contrast: function(f) {
		var n = function(v) {
			return (((v / 255) - 0.5) * (1 + (f / 100).pow(2)) + 0.5) * 255;
		};
		return new Color([n(this.red), n(this.green), n(this.blue), this.alpha]);
	},
	brightness: function(c, f) {
		return new Color([
			this.red + (255 / 100 * f).round(),
			this.green + (255 / 100 * f).round(),
			this.red + (255 / 100 * f).round(),
			this.alpha
		]);
	}
});

Color.isColor = function(s) {
	return s.match(/((rgb|rgba|hsl|hsla|cmyk|cmyka)\([0-9]%?,[\s]*[0-9]+%?,[\s]*[0-9]+%?(,[\s]*[0-9\.]+)?\)|#[0-9A-F]{3,8})/gi);
};

var ViewPort = {
	_onOpen: [],
	_onClose: [],
	_config: {},
	opened: false,
	init: function(c){
		if (!I('fx_viewport')) {
			ViewPort._config = c || {};
			var o = D(['div', {
				style: {
					backgroundColor: '#000000',
					color: '#FFFFFF',
					width: '100%',
					position: 'absolute',
					top: '0px',
					left: '0px',
					display: 'none',
					zIndex: '25',
					opacity: '0'
				},
				id: 'fx_viewport',
				onclick: function(){
					ViewPort.close();
				}
			}], T('body')[0]);
			ViewPort.setSizes();
			Event.add(window, 'resize', ViewPort.setSizes);
		}
	},
	setSizes: function() {
		I('fx_viewport').style.height = Env.pageSize()[1] + 'px';
	},
	open: function(e) {
		var c = ViewPort._config, a = ViewPort._onOpen, v = I('fx_viewport');
		if (v && v.style.display == 'none') {
			ViewPort.setSizes();
			v.morph({
				styles: {
					opacity: [0, (c.opacity || 0.8)],
					display: ['block', 'block']
				},
				time: (c.time || 0.3),
				effect: (c.animation)
			});
			a.each(function(f){
				f[0].call(f[1], e);
			});
			ViewPort.opened = true;
		}
	},
	close: function(e) {
		var c = ViewPort._config, a = ViewPort._onClose, v = I('fx_viewport');
		if (v && v.style.display == 'block') {
			v.morph({
				styles: {
					opacity: [ACTUAL, 0],
					display: ['block', 'none']
				},
				time: (c.time || 0.3),
				effect: (c.animation)
			});
			a.each(function(f) {
				f[0].call(f[1], e);
			});
			ViewPort.opened = false;
		}
	},
	addOpenEvent: function(e, b) {
		ViewPort._onOpen.push([e, b || null]);
	},
	addCloseEvent: function(e, b) {
		ViewPort._onClose.push([e, b || null]);
	}
};


var AsyncRequest = Class({
	__construct: function(o) {
		this.reset();
		this.createRequest();
		Object.extend(this.options, o || {});
	},
	resetData: function() {
		this.xhr = null;
		this.GETs = {};
		this.POSTs = {};
		this.HEADs = {};
		this.path = '';
		this.response = {
			text : '',
			XML : null,
			headers : {}
		};
		this.status = {
			code : 0,
			text : 'Unknown',
			type : 'Unknown'
		};
		this.options = {
			timeout: 0,
			escapeCache: true,
			urlEncoded: true,
			encoding: 'utf-8'
		};
	},
	resetFunctions: function() {
		this.onRequest = function() {};
		this.onLoaded = function() {};
		this.onInteractive = function() {};
		this.onSuccess = function() {};
		this.onFailure = function() {};
		this.onAbort = function() {};
		this.onException = function() {};
	},
	reset: function() {
		this.resetFunctions();
		this.resetData();
	},
	createRequest: function() {
		var x = null;
		if(window.XMLHttpRequest)
			try {
				x = new XMLHttpRequest();
			} catch(e) {
				x = null;
				this.onException(e, c);
			}
		else if(window.ActiveXObject) {
			var a = [
				'Msxml2.XMLHTTP.7.0',
				'Msxml2.XMLHTTP.6.0',
				'Msxml2.XMLHTTP.5.0',
				'Msxml2.XMLHTTP.4.0',
				'MSXML2.XMLHTTP.3.0',
				'MSXML2.XMLHTTP',
				'Microsoft.XMLHTTP'
			], l = a.length, i, c;
			for(i = 0; i < l && !x; i++) {
				c = a[i];
				try {
					x = new ActiveXObject(c);
				} catch(e) {
					x = null;
					this.onException(e, c);
				}
			}
		}
		return (this.xhr = x) ? true : false;
	},
	addGetData: function(o, v) {
		var p = this.GETs, i;
		if(typeof o == 'object')
			for(i in o)
				p[i] = o[i];
		else
			p[o] = v;
	},
	addPostData: function(o, v) {
		var p = this.POSTs, i;
		if(typeof o == 'object')
			for(i in o)
				p[i] = o[i];
		else
			p[o] = v;
	},
	urlPath: function(u) {
		this.path = u.has('?') ? u.split('?')[0] : u;
	},
	urlParameters: function(u) {
		if(!u.has('?'))
			return;
		var p = u.split('?')[1].replace('&amp;', '&').split('&'), l = p.length, i, v, o = {};
		for(i = 0; i < l; i++) {
			v = p[i].split('=');
			o[v[0]] = v[1];
		}
		this.addGetData(o);
	},
	url: function(u) {
		this.urlPath(u);
		this.urlParameters(u);
	},
	abort: function() {
		if(!this.running)
			return this;
		this.running = false;
		var x = this.xhr;
		x.abort();
		x.onreadystatechange = function(){};
		this.createRequest();
		this.onAbort();
	},
	setHeaders: function(o, v) {
		var p = this.HEADs, i;
		if(typeof o == 'object')
			for(i in o)
				p[i] = o[i];
		else
			p[o] = v;
	},
	getHeaders: function(){
		var r = {}, n = this.xhr.getAllResponseHeaders().split(/(\n)/gmi), i, l = n.length, h;
		for(i = 0; i < l; i++) {
			h = n[i].trim();
			if(!h)
				continue;
			h = h.split(/:[\s]+/gmi);
			r[h[0]] = h[1];
		}
		return r;
	},
	getStatus: function() {
		var q = this.xhr, c = q.status, t = q.statusText, p;
		if(c) {
			if(!t) {
				t = function(){
					switch (c) {
						case 100:	return 'Continue';
						case 101:	return 'Switching Protocols';
						case 200:	return 'OK';
						case 201:	return 'Created';
						case 202:	return 'Accepted';
						case 203:	return 'Non-Authoritative Information';
						case 204:	return 'No Content';
						case 205:	return 'Reset Content';
						case 206:	return 'Partial Content';
						case 207:	return 'Multi-Status';
						case 300:	return 'Multiple Choices';
						case 301:	return 'Moved Permanently';
						case 302:	return 'Found';
						case 303:	return 'See Other';
						case 304:	return 'Not Modified';
						case 305:	return 'Use Proxy';
						case 306:	return 'Switch Proxy';
						case 307:	return 'Temporary Redirect';
						case 400:	return 'Bad Request';
						case 401:	return 'Unauthorized';
						case 402:	return 'Payment Required';
						case 403:	return 'Forbidden';
						case 404:	return 'Not Found';
						case 405:	return 'Method Not Allowed';
						case 406:	return 'Not Acceptable';
						case 407:	return 'Proxy Authentication Required';
						case 408:	return 'Request Timeout';
						case 409:	return 'Conflict';
						case 410:	return 'Gone';
						case 411:	return 'Length Required';
						case 412:	return 'Precondition Failed';
						case 413:	return 'Request Entity Too Large';
						case 414:	return 'Request-URI Too Long';
						case 415:	return 'Unsupported Media Type';
						case 416:	return 'Requested Range Not Satisfiable';
						case 417:	return 'Expectation Failed';
						case 449:	return 'Retry With';
						case 500:	return 'Internal Server Error';
						case 501:	return 'Not Implemented';
						case 502:	return 'Bad Gateway';
						case 503:	return 'Service Unavailable';
						case 504:	return 'Gateway Timeout';
						case 505:	return 'HTTP Version Not Supported';
						case 509:	return 'Bandwidth Limit Exceeded';
					}
				}();
			}
			p = function(){
				if(c < 200) return 'Informational';
				if(c < 300) return 'Success';
				if(c < 400) return 'Redirection';
				if(c < 500) return 'Client Error';
				if(c < 600) return 'Server Error';
			}();
		}
		return {
			code : c,
			text : t || 'Unknown',
			type : p || 'Unknown'
		};
	},
	run: function() {
		if(this.xhr) {

			var s = this,
			r = s.response,
			q = s.xhr,
			u = s.timeout,
			e = s.encoding,
			h = s.HEADs,
			g = s.GETs,
			p = s.POSTs,
			o = s.options;

			// Aggiungo headers base
			h['Connection'] = 'close';
			h['X-Ajax-Request'] = 'AIDA-JS';
			h['Accept'] = 'text/javascript, text/html, application/xml, text/xml, */*';

			// Evado la cache
			if (o.escapeCache)
				g['x_escape_cache'] = new Date().getTime();

			var qs = function(p) {
				var a = [], j = 0, i;
				for(i in p)
					a[j++] = encodeURIComponent(i) + "=" + encodeURIComponent(p[i]);
				return a.join('&');
			},
			qg = qs(g),
			qp = qs(p) || null,
			d, k, t, m = (qp || o.urlEncoded) ? 'POST' : 'GET';

			q.onreadystatechange = function() {
				if(u > 0 && !d) {
					u = new Date().getTime() + (u * 1000);
					(function(){
						if(new Date().getTime() >= u)
							s.abort();
						else
							d = setTimeout(arguments.callee, 100);
					})();
				}
				switch(q.readyState) {
					case 1:
						s.onRequest();
					break;
					case 2:
						s.onLoaded();
					break;
					case 3:
						s.onInteractive();
					break;
					case 4:
						// Se esisteva un timer lo termino
						if(d)
							clearTimeout(d);
						var rT, rX, rH;
						// Conservo le informazioni sulla risposta
						rT = r.text = q.responseText;
						rX = r.XML = q.responseXML;
						rH = r.headers = s.getHeaders();
						// Ottengo i dettagli sullo stato
						s.status = d = s.getStatus();
						s.runnig = false;
						s[(d.type == 'Success' ? 'onSuccess' : 'onFailure')](rT, rX, rH, d);
					break;
				}
			};

			// Se Ë una richiesta via POST imposto l'encoding e il charset
			if(m == 'POST')
				h['Content-type'] = 'application/x-www-form-urlencoded' + (e ? '; charset=' + e : '');

			s.runnig = true;

			// Apro la richiesta
			q.open(m, this.path + (qg ? '?' + qg : ''), true);
			for(k in h) {
				try {
					q.setRequestHeader(k, h[k]);
				} catch (e) {
					this.onException(e, k, h[k]);
				}
			}
			q.send(qp);
		}
	}
});


var XMLSerializer = Class({
	_cdata: false,
	_vars: [],
	__construct: function(c) {
		this._cdata = c;
	},
	// Function to add a new variable
	add: function(v, n) {
		this._vars[this._vars.length] = [v, n];
	},
	serialize: function(h) {
		var a = this._vars, r = '', i, v;
		for(i = a.length - 1; i >= 0; i--) {
			v = a[i];
			r = this._serializer(v[0], v[1]) + r;
		}
		return (h || '<?xml version="1.0" ?>') + (r ? '<vars/>' : '<vars>' + r + '</vars>');
	},
	_serializer: function(v, n) {
		var r = '';
		n = n ? ' name="' + n.toString() + '"' : '';
		switch(typeof v) {
			case 'boolean':
				r = '<boolean' + n + '>' + (v ? 'true' : 'false') + '</boolean>';
			break;
			case 'string':
				if(this._cdata)
					v = '<![CDATA[' + v + ']]>';
				else
					v.replace(/&/g, '&amp;').replace(/</g, '&lt;');
				r = '<string' + n + '>' + v + '</string>';
			break;
			case 'number':
				if(Math.round(v) === v)
					r = '<integer' + n + '>' + v + '</integer>';
				else
					r = '<float' + n + '>' + v + '</float>';
			break;
			case 'object':
				var i, w;
				if (v === null)
					r = '<null' + n + '/>';
				else if (v instanceof Date)
					r = '<date' + n + '>' + v.getTime() + '</date>';
				else if (v instanceof Array) {
					for (i = v.length - 1; i >= 0; i--)
						r = this._serializer(v[i], null) + r;
					r = '<array' + n + '>' + r + '</array>';
				}
				else {
					for (i in v) {
						w = v[i];
						if (typeof(w) == 'function')
							continue;
						r += this._serializer(w, i);
					}
					r = '<associative' + n + '>' + r + '</associative>';
				}
			break;
			default:
			case 'undefined':
				r = '<undefined' + n + '/>';
			break;
		}
		return r;
	}
});

XMLSerializer.serialize = function() {
	var a = arguments, l = a.length, i, s = new XMLSerializer(true);
	for(i = 0; i < l; i++)
		s.addVariable(a[i]);
	return s.serialize();
};

var JSON = {
	encode: function(o){
		switch (typeOf(o)) {
			case 'string':
				var s = {
					'\b': '\\b',
					'\t': '\\t',
					'\n': '\\n',
					'\f': '\\f',
					'\r': '\\r',
					'"': '\\"',
					'\\': '\\\\'
				};
				return '"' +
				o.replace(/["\\\x00-\x1f\x7f-\x9f]/g, function(c){
					return s[c] || '\\u00' + Math.floor(c.charCodeAt() / 16).toString(16) + (c.charCodeAt() % 16).toString(16);
				}) +
				'"';
			case 'array':
			case 'arguments':
			case 'list':
				for (var i = 0, l = o.length, v, r = []; i < l; i++) {
					v = JSON.encode(o[i]);
					if (v)
						r.push(v);
				}
				return '[' + r + ']';
			case 'date':
				var d = function(n){
					return n < 10 ? '0' + n : n;
				};
				return o.getUTCFullYear() + '-' + d(o.getUTCMonth() + 1) + '-' +
				d(o.getUTCDate()) +
				'T' +
				d(o.getUTCHours()) +
				':' +
				d(o.getUTCMinutes()) +
				':' +
				d(o.getUTCSeconds()) +
				'Z';
			case 'number':
				return isFinite(o) && !isNaN(o) ? o + '' : 'null';
			case 'object':
				var i, v, r = [];
				for (i in o) {
					v = JSON.encode(o[i]);
					if (v)
						r.push(JSON.encode(i) + ':' + v);
				}
				return '{' + r + '}';
			case 'null':
			case 'boolean':
				return o + '';
		}
		return false;
	},
	decode: function(s) {
		return (s && typeof s == 'string' && s.isJSON()) ? eval('(' + string + ')') : null;
	}
};



var Ajax = {
	_origTitle: null,
	_cache: [],
	// Ottiene i dati per l'url passato
	_getCached: function(u) {
		var c = Ajax._cache, n = new Date().getTime(), i, e;
		for(i = c.length - 1; i >= 0; i--) {
			e = c[i];
			if(e[0] == u && e[2] > n)
				return e[1];
		}
		return false;
	},
	// Aggiungi i dati dell'url
	_addToCache: function(u, r, t) {
		var c = Ajax._cache, l = c.length, n = (new Date().getTime()) + (t * 1000), i, e;
		for(i = l - 1; i >= 0; i--) {
			e = c[i];
			if(e[0] == u) {
				Ajax._cache[i] = [u, r, n];
				return i;
			}
		}
		Ajax._cache[l] = [u, r, n];
		return l;
	},
	_history: [null],
	_initHistory: function() {
		if(!I('xfa_history_frame')) {
			Dom.body().innerHTML +=
				'<div style="margin-left: -9000px">' +
				'<iframe src="./xframe/ajax/foo.html" id="ajax_history_frame" name="ajax_history_frame"></iframe>' +
				'<form id="ajax_history_form" action="./xframe/ajax/foo.html" method="get" target="ajax_history_frame">' +
				'<input type="hidden" name="history" id="ajax_history_input" value="none" /></form></div>';
			Event.add('xfa_history_frame', 'load', function() {
				var c = Dom.window('xfa_history_frame').location.search.toString().match(/.*history=([0-9]+)/i);
				if(c && (c = parseInt(c[1], 10)) && Ajax._actual != c)
					Ajax._historyBack(c);
			});
		}
	},
	_historyBack: function(c) {
		var h = Ajax._history[c];
		if(h) {
			Ajax._actual = c;
			Ajax.get(h[0], h[1]);
		}
	},
	_addToHistory: function(o, a) {
		var c = Ajax._history.length;
		Ajax._initHistory();
		I('xfa_history_input').value = c;
		I('xfa_history_form').submit();
		Ajax._history[c] = [o, a];
		Ajax._actual = c;
	},
	_setTitle: function(t) {
		// Imposto il titolo
		if(t) {
			var o = Ajax._origTitle;
			if(!o)
				Ajax._origTitle = document.title;
			document.title = t;
		}
	},
	get: function(o, r) {
		var i = I(o.element),
			u = o.url,
			eF = Function.empty,
			oS = o.onSuccess || eF,
			c = o.cache,
			h = o.history,
			t = o.time || 1800;

		// Se l'history Ë abilitata e la chiamata proviene da li eseguo
		if(h && r)
			return oS.apply(i, [r[0], r[1], r[2]]);

		// Provo a cercare nella cache se abilitata
		if(c && (r = Ajax._getCached(u)))
			return oS.apply(i, [r[0], r[1], r[2]]);

		// Creo la chiamata
		var a = new AsyncRequest();
		a.url(u, true);
		a.addGetData(o.get || {});
		a.addPostData(o.post || {});
		a.onRequest = o.onRequest || eF;
		a.onFailure = o.onFilure || eF;
		a.onLoading = o.onLoading || eF;
		a.onInteractive = o.onInteractive || eF;
		a.onAbort = o.onAbort || eF;
		a.onSuccess = function() {
			var a = arguments;
			// Aggiungo alla cache se impostato
			if(c)
				Ajax._addToCache(u, a, t);
			// Aggiungo all'history se impostato
			if(h)
				Ajax._addToHistory(u, o, a);
			oS.apply(null, a);
			Ajax._setTitle(o.title);
		};
		a.run();
	},
	formSubmit: function(f, t, u, m) {
		f = I(f);
		t = I(t);
		// If the obtained element is a form proceed
		if(f.tagName.toLowerCase() == "form") {
			if(!u) {
				u = f.getAttribute("action");
				if(!u || !u.length) return false;
			}
			var a = new AjaxRequest(), e = f.elements, l = e.length, i, o, n;
			if(!m) {
				m = f.getAttribute("method");
				if(!m || !m.length) m = "GET";
			}
			m = m.toUpperCase();
			a.method = m;
			a.extractUrl(u, true);
			a.encode = true;
			a.onLoading = function() {
				t.innerHTML = "<span class=\"lijaxLoading\"><strong>Loading...</strong></span>";
			};
			a.onCompletion = function() {
				t.innerHTML = this.response.text;
			};
			for(i = 0; i < l; i++) {
				o = e[i];
				n = o.name;
				t = o.type;
				if(n && n.length > 0) {
					if((t == "radio" || t == "checkbox") && o.checked) a.addParameter(n, o.value, true, m);
					else a.addParameter(n, o.value, true, m);
				}
			}
			a.addHeader('X-Ajax-Engine', Ajax.config.appName);
			a.run();
			return true;
		}
		return false;
	},
	hiddenFrame: function(o) {
		var i = (o || (o = {})).id || 'random_' + String.random();
		(I(o.element) || T('body')[0]).innerHTML += '<div style="margin-left:-9000px;overflow:hidden;height:0px;width:0px;"><iframe src="' + (o.url || '') + '" id="' + i + '" name="' + (o.name || i) + '"></iframe></div>';
		return I(i);
	}
};