

/*!
 * Copyright (c) 2008 Simo Kinnunen.
 * Licensed under the MIT license.
 */

var Cufon = (function() {
	
	var api = function() {	
		return api.replace.apply(null, arguments);
	};
	
	var DOM = api.DOM = {
			
		ready: (function() {
		
			var complete = false, readyStatus = { loaded: 1, complete: 1 };
		
			var queue = [], perform = function() {
				if (complete) return;
				complete = true;
				for (var fn; fn = queue.shift(); fn());
			};
			
			// Gecko, Opera, WebKit r26101+
			
			if (document.addEventListener) {
				document.addEventListener('DOMContentLoaded', perform, false);
				window.addEventListener('pageshow', perform, false); // For cached Gecko pages
			}
			
			// Old WebKit, Internet Explorer
			
			if (!window.opera && document.readyState) (function() {
				readyStatus[document.readyState] ? perform() : setTimeout(arguments.callee, 10);
			})();
			
			// Internet Explorer
			
			if (document.readyState && document.createStyleSheet) (function() {
				try {
					document.body.doScroll('left');
					perform();
				}
				catch (e) {
					setTimeout(arguments.callee, 1);
				}
			})();
			
			addEvent(window, 'load', perform); // Fallback
			
			return function(listener) {
				if (!arguments.length) perform();
				else complete ? listener() : queue.push(listener);
			};
			
		})()
		
	};

	var CSS = api.CSS = {
	
		Size: function(value, base) {
		
			this.value = parseFloat(value);
			this.unit = String(value).match(/[a-z%]*$/)[0] || 'px';
		
			this.convert = function(value) {
				return value / base * this.value;
			};
			
			this.convertFrom = function(value) {
				return value / this.value * base;
			};
			
			this.toString = function() {
				return this.value + this.unit;
			};

		},
	
		getStyle: function(el) {
			var view = document.defaultView;
			if (view && view.getComputedStyle) return new Style(view.getComputedStyle(el, null));
			if (el.currentStyle) return new Style(el.currentStyle);
			return new Style(el.style);
		},
		
		ready: (function() {
			
			var complete = false;
			
			var queue = [], perform = function() {
				complete = true;
				for (var fn; fn = queue.shift(); fn());
			};
			
			// Safari 2 does not include <style> elements in document.styleSheets.
			// Safari 2 also does not support Object.prototype.propertyIsEnumerable.
			
			var styleElements = Object.prototype.propertyIsEnumerable ? elementsByTagName('style') : { length: 0 };
			var linkElements = elementsByTagName('link');
			
			DOM.ready(function() {
				// These checks are actually only needed for WebKit-based browsers, but don't really hurt other browsers.
				var linkStyles = 0, link;
				for (var i = 0, l = linkElements.length; link = linkElements[i], i < l; ++i) {
					// WebKit does not load alternate stylesheets.
					if (!link.disabled && link.rel.toLowerCase() == 'stylesheet') ++linkStyles;
				}
				if (document.styleSheets.length >= styleElements.length + linkStyles) perform();
				else setTimeout(arguments.callee, 10);
			});
			
			return function(listener) {
				if (complete) listener();
				else queue.push(listener);
			};
			
		})(),

		supports: function(property, value) {
			var checker = document.createElement('span').style;
			if (checker[property] === undefined) return false;
			checker[property] = value;
			return checker[property] === value;
		},
		
		textAlign: function(word, style, position, wordCount) {
			if (style.get('textAlign') == 'right') {
				if (position > 0) word = ' ' + word;
			}
			else if (position < wordCount - 1) word += ' ';
			return word;
		},
		
		textDecoration: function(el, style) {
			if (!style) style = this.getStyle(el);
			var types = {
				underline: null,
				overline: null,
				'line-through': null
			};
			for (var search = el; search.parentNode && search.parentNode.nodeType == 1; ) {
				var foundAll = true;
				for (var type in types) {
					if (types[type]) continue;
					if (style.get('textDecoration').indexOf(type) != -1) types[type] = style.get('color');
					foundAll = false;
				}
				if (foundAll) break; // this is rather unlikely to happen
				style = this.getStyle(search = search.parentNode);
			}
			return types;
		},
		
		textShadow: cached(function(value) {
			if (value == 'none') return null;
			var shadows = [], currentShadow = {}, result, offCount = 0;
			var re = /(#[a-f0-9]+|[a-z]+\(.*?\)|[a-z]+)|(-?[\d.]+[a-z%]*)|,/ig;
			while (result = re.exec(value)) {
				if (result[0] == ',') {
					shadows.push(currentShadow);
					currentShadow = {}, offCount = 0;
				}
				else if (result[1]) {
					currentShadow.color = result[1];
				}
				else {
					currentShadow[[ 'offX', 'offY', 'blur' ][offCount++]] = result[2];
				}
			}
			shadows.push(currentShadow);
			return shadows;
		}),
		
		color: cached(function(value) {
			var parsed = {};
			parsed.color = value.replace(/^rgba\((.*?),\s*([\d.]+)\)/, function($0, $1, $2) {
				parsed.opacity = parseFloat($2);
				return 'rgb(' + $1 + ')';
			});
			return parsed;
		}),
		
		textTransform: function(text, style) {
			return text[{
				uppercase: 'toUpperCase',
				lowercase: 'toLowerCase'
			}[style.get('textTransform')] || 'toString']();
		}
		
	};
	
	api.VML = {
	
		parsePath: function(path) {
			var cmds = [], re = /([mrvxe])([^a-z]*)/g, match;
			while (match = re.exec(path)) {
				cmds.push({
					type: match[1],
					coords: match[2].split(',')
				});
			}
			return cmds;
		}
			
	};
	
	function Font(data) {
		
		var face = this.face = data.face;
		this.glyphs = data.glyphs;
		this.w = data.w;
		this.baseSize = parseInt(face['units-per-em'], 10);
		
		this.family = face['font-family'].toLowerCase();
		this.weight = face['font-weight'];
		this.style = face['font-style'] || 'normal';
		
		this.viewBox = (function () {
			var parts = face.bbox.split(/\s+/);
			return {
				minX: parseInt(parts[0], 10),
				minY: parseInt(parts[1], 10),
				width: parseInt(parts[2], 10) - parseInt(parts[0], 10),
				height: parseInt(parts[3], 10) - parseInt(parts[1], 10),
				toString: function() {
					return [ this.minX, this.minY, this.width, this.height ].join(' ');
				}
			};
		})();
		
		this.ascent = -parseInt(face.ascent, 10);
		this.descent = -parseInt(face.descent, 10);
		
		this.height = -this.ascent + this.descent;
		
	}
	
	function FontFamily() {

		var styles = {}, mapping = {
			oblique: 'italic',
			italic: 'oblique'
		};
		
		this.add = function(font) {
			(styles[font.style] || (styles[font.style] = {}))[font.weight] = font;
		};
		
		this.get = function(style, weight) {
			var weights = styles[style] || styles[mapping[style]]
				|| styles.normal || styles.italic || styles.oblique;
			if (!weights) return null;
			// we don't have to worry about "bolder" and "lighter"
			// because IE's currentStyle returns a numeric value for it,
			// and other browsers use the computed value anyway
			weight = {
				normal: 400,
				bold: 700
			}[weight] || parseInt(weight, 10);
			if (weights[weight]) return weights[weight];
			// http://www.w3.org/TR/CSS21/fonts.html#propdef-font-weight
			// Gecko uses x99/x01 for lighter/bolder
			var up = {
				1: 1,
				99: 0
			}[weight % 100], alts = [], min, max;
			if (up === undefined) up = weight > 400;
			if (weight == 500) weight = 400;
			for (var alt in weights) {
				alt = parseInt(alt, 10);
				if (!min || alt < min) min = alt;
				if (!max || alt > max) max = alt;
				alts.push(alt);
			}
			if (weight < min) weight = min;
			if (weight > max) weight = max;
			alts.sort(function(a, b) {
				return (up
					? (a > weight && b > weight) ? a < b : a > b
					: (a < weight && b < weight) ? a > b : a < b) ? -1 : 1;
			});
			return weights[alts[0]];
		};
	
	}
	
	function Storage() {
		
		var map = {}, at = 0;
		
		function identify(el) {
			return el.cufid || (el.cufid = ++at);
		}
		
		this.get = function(el) {
			var id = identify(el);
			return map[id] || (map[id] = {});
		};
		
	}
	
	function Style(style) {
		
		var custom = {}, sizes = {};
		
		this.get = function(property) {
			return custom[property] != undefined ? custom[property] : style[property];
		};
		
		this.getSize = function(property, base) {
			return sizes[property] || (sizes[property] = new CSS.Size(this.get(property), base));
		};
		
		this.extend = function(styles) {
			for (var property in styles) custom[property] = styles[property];
			return this;
		};
		
	}
	
	function addEvent(el, type, listener) {
		if (el.addEventListener) {
			el.addEventListener(type, listener, false);
		}
		else if (el.attachEvent) {
			el.attachEvent('on' + type, function() {
				return listener.apply(el, arguments);
			});
		}
	}
	
	function cached(fun) {
		var cache = {};
		return function(key) {
			if (!cache.hasOwnProperty(key)) cache[key] = fun.apply(null, arguments);
			return cache[key];
		};	
	}
	
	function getFont(el, style) {
		if (!style) style = CSS.getStyle(el);
		var families = style.get('fontFamily').split(/\s*,\s*/), family;
		for (var i = 0, l = families.length; i < l; ++i) {
			family = families[i].replace(/^(["'])(.*?)\1$/, '$2').toLowerCase();
			if (fonts[family]) return fonts[family].get(style.get('fontStyle'), style.get('fontWeight'));
		}
		return null;
	}
	
	function elementsByTagName(query) {
		return document.getElementsByTagName(query);
	}
	
	function merge() {
		var merged = {}, key;
		for (var i = 0, l = arguments.length; i < l; ++i) {
			for (key in arguments[i]) merged[key] = arguments[i][key];
		}
		return merged;
	}
	
	function process(font, text, style, options, node, el) {
		var separate = options.separate;
		if (separate == 'none') return engines[options.engine].apply(null, arguments);
		var fragment = document.createDocumentFragment(), processed;
		var parts = text.split(separators[separate]), needsAligning = (separate == 'words');
		if (needsAligning && HAS_BROKEN_REGEXP) {
			// @todo figure out a better way to do this
			if (/^\s/.test(text)) parts.unshift('');
			if (/\s$/.test(text)) parts.push('');
		}
		for (var i = 0, l = parts.length; i < l; ++i) {
			processed = engines[options.engine](font,
				needsAligning ? CSS.textAlign(parts[i], style, i, l) : parts[i],
				style, options, node, el, i < l - 1);
			if (processed) fragment.appendChild(processed);
		}
		return fragment;
	}
	
	function replaceElement(el, options) {
		var storage = sharedStorage.get(el);
		if (!options) options = storage.options;
		var font, style, nextNode;
		for (var node = el.firstChild; node; node = nextNode) {
			nextNode = node.nextSibling;
			if (node.nodeType == 1) {
				if (!node.firstChild) continue;
				if (!/cufon/.test(node.className)) {
					arguments.callee(node, options);
					continue;
				}
			}
			var text = node.nodeType == 3 ? node.data : node.alt;
			if (text === '') continue;
			if (!style) style = CSS.getStyle(el).extend(options);
			if (!font) font = getFont(el, style);
			if (!font) continue;
			var processed = process(font, text, style, options, node, el);
			if (processed) node.parentNode.replaceChild(processed, node);
			else node.parentNode.removeChild(node);
		}
		if (!storage.options) {
			storage.options = options;
		}
	}
	
	var HAS_BROKEN_REGEXP = ' '.split(/\s+/).length == 0;
	
	var sharedStorage = new Storage();
	var replaceHistory = [];
	
	var engines = {}, fonts = {}, defaultOptions = {
		enableTextDecoration: false,
		engine: null,
		//fontScale: 1,
		//fontScaling: false,
		//hover: false,
		printable: true,
		//rotation: 0,
		//selectable: false,
		selector: (
				window.Sizzle
			||	(window.dojo && dojo.query)
			||	(window.$$ && function(query) { return $$(query); })
			||	window.$
			||	(document.querySelectorAll && function(query) { return document.querySelectorAll(query); })
			||	elementsByTagName
		),
		separate: 'words', // 'none' and 'characters' are also accepted
		textShadow: 'none'
	};
	
	var separators = {
		words: /\s+/,
		characters: ''
	};
	
	api.now = function() {
		DOM.ready();
		return api;
	};
	
	api.refresh = function() {
		var currentHistory = replaceHistory.splice(0, replaceHistory.length);
		for (var i = 0, l = currentHistory.length; i < l; ++i) {
			api.replace.apply(null, currentHistory[i]);
		}
		return api;
	};
	
	api.registerEngine = function(id, engine) {
		if (!engine) return api;
		engines[id] = engine;
		return api.set('engine', id);
	};
	
	api.registerFont = function(data) {
		var font = new Font(data), family = font.family;
		if (!fonts[family]) fonts[family] = new FontFamily();
		fonts[family].add(font);
		return api.set('fontFamily', family);
	};
	
	api.replace = function(elements, options, ignoreHistory) {
		options = merge(defaultOptions, options);
		if (!options.engine) return api; // there's no browser support so we'll just stop here
		if (typeof options.textShadow == 'string')
			options.textShadow = CSS.textShadow(options.textShadow);
		if (!ignoreHistory) replaceHistory.push(arguments);
		if (elements.nodeType || typeof elements == 'string') elements = [ elements ];
		CSS.ready(function() {
			for (var i = 0, l = elements.length; i < l; ++i) {
				var el = elements[i];
				if (typeof el == 'string') api.replace(options.selector(el), options, true);
				else replaceElement(el, options);
			}
		});
		return api;
	};
	
	api.set = function(option, value) {
		defaultOptions[option] = value;
		return api;
	};
	
	return api;
	
})();

Cufon.registerEngine('canvas', (function() {

	// Safari 2 doesn't support .apply() on native methods
	
	var check = document.createElement('canvas');
	if (!check || !check.getContext || !check.getContext.apply) return null;
	check = null;
	
	var HAS_INLINE_BLOCK = Cufon.CSS.supports('display', 'inline-block');
	
	// Firefox 2 w/ non-strict doctype (almost standards mode)
	var HAS_BROKEN_LINEHEIGHT = !HAS_INLINE_BLOCK && (document.compatMode == 'BackCompat' || /frameset|transitional/i.test(document.doctype.publicId));
	
	var styleSheet = document.createElement('style');
	styleSheet.type = 'text/css';
	styleSheet.appendChild(document.createTextNode(
		'@media screen,projection{' +
			'.cufon-canvas{display:inline;display:inline-block;position:relative;vertical-align:middle' + 
			(HAS_BROKEN_LINEHEIGHT
				? ''
				: ';font-size:1px;line-height:1px') +
			'}.cufon-canvas .cufon-alt{display:none}' +
			(HAS_INLINE_BLOCK
				? '.cufon-canvas canvas{position:relative}'
				: '.cufon-canvas canvas{position:absolute}') +
		'}' +
		'@media print{' +
			'.cufon-canvas{padding:0 !important}' +
			'.cufon-canvas canvas{display:none}' +
			'.cufon-canvas .cufon-alt{display:inline}' +
		'}'
	));
	document.getElementsByTagName('head')[0].appendChild(styleSheet);

	function generateFromVML(path, context) {
		var atX = 0, atY = 0;
		var cmds = Cufon.VML.parsePath(path);
		var code = new Array(cmds.length - 1);
		generate: for (var i = 0, l = cmds.length; i < l; ++i) {
			var c = cmds[i].coords;
			switch (cmds[i].type) {
				case 'v':
					code[i] = { m: 'bezierCurveTo', a: [ atX + Number(c[0]), atY + Number(c[1]), atX + Number(c[2]), atY + Number(c[3]), atX += Number(c[4]), atY += Number(c[5]) ] };
					break;
				case 'r':
					code[i] = { m: 'lineTo', a: [ atX += Number(c[0]), atY += Number(c[1]) ] };
					break;
				case 'm':
					code[i] = { m: 'moveTo', a: [ atX = Number(c[0]), atY = Number(c[1]) ] };
					break;
				case 'x':
					code[i] = { m: 'closePath' };
					break;
				case 'e':
					break generate;
			}
			context[code[i].m].apply(context, code[i].a);
		}
		return code;
	}
	
	function interpret(code, context) {
		for (var i = 0, l = code.length; i < l; ++i) {
			var line = code[i];
			context[line.m].apply(context, line.a);
		}
	}
	
	return function(font, text, style, options, node, el) {
		
		var viewBox = font.viewBox;
		
		var size = style.getSize('fontSize', font.baseSize);
		
		var letterSpacing = style.get('letterSpacing');
		letterSpacing = (letterSpacing == 'normal') ? 0 : size.convertFrom(parseInt(letterSpacing, 10));
		
		var expandTop = 0, expandRight = 0, expandBottom = 0, expandLeft = 0;
		var shadows = options.textShadow, shadowOffsets = [];
		if (shadows) {
			for (var i = 0, l = shadows.length; i < l; ++i) {
				var shadow = shadows[i];
				var x = size.convertFrom(parseFloat(shadow.offX));
				var y = size.convertFrom(parseFloat(shadow.offY));
				shadowOffsets[i] = [ x, y ];
				if (y < expandTop) expandTop = y;
				if (x > expandRight) expandRight = x;
				if (y > expandBottom) expandBottom = y;
				if (x < expandLeft) expandLeft = x;
			}
		}
		
		var chars = Cufon.CSS.textTransform(text, style).split('');
		
		var width = 0, lastWidth = null;
		
		for (var i = 0, l = chars.length; i < l; ++i) {
			var glyph = font.glyphs[chars[i]] || font.missingGlyph;
			if (!glyph) continue;
			width += lastWidth = Number(glyph.w || font.w) + letterSpacing;
		}
		
		if (lastWidth === null) return null; // there's nothing to render
		
		expandRight += (viewBox.width - lastWidth);
		expandLeft += viewBox.minX;
		
		var wrapper = document.createElement('span');
		wrapper.className = 'cufon cufon-canvas';
		wrapper.alt = text;
		
		var canvas = document.createElement('canvas');
		
		var wStyle = wrapper.style;
		var cStyle = canvas.style;
		
		var height = size.convert(viewBox.height - expandTop + expandBottom);
		var roundedHeight = Math.ceil(height);
		var roundingFactor = roundedHeight / height;
		
		canvas.width = Math.ceil(size.convert(width + expandRight - expandLeft) * roundingFactor);
		canvas.height = roundedHeight;
		
		// minY has no part in canvas.height
		expandTop += viewBox.minY;
		
		cStyle.top = Math.round(size.convert(expandTop - font.ascent)) + 'px';
		cStyle.left = Math.round(size.convert(expandLeft)) + 'px';
		
		var wrapperWidth = Math.ceil(size.convert(width * roundingFactor)) + 'px';
		
		if (HAS_INLINE_BLOCK) {
			wStyle.width = wrapperWidth;
			wStyle.height = size.convert(font.height) + 'px';
		}
		else {
			wStyle.paddingLeft = wrapperWidth;
			wStyle.paddingBottom = (size.convert(font.height) - 1) + 'px';
		}
		
		var g = canvas.getContext('2d'), scale = roundedHeight / viewBox.height;
		
		g.scale(scale, scale);
		g.translate(-expandLeft, -expandTop);
		
		g.lineWidth = font.face['underline-thickness'];
		
		g.save();
		
		function line(y, color) {
			g.strokeStyle = color;
			
			g.beginPath();
			
			g.moveTo(0, y);
			g.lineTo(width, y);
			
			g.stroke();
		}
		
		var textDecoration = options.enableTextDecoration ? Cufon.CSS.textDecoration(el, style) : {};
		
		if (textDecoration.underline) line(-font.face['underline-position'], textDecoration.underline);
		if (textDecoration.overline) line(font.ascent, textDecoration.overline);
		
		g.fillStyle = style.get('color');
		
		function renderText() {
			for (var i = 0, l = chars.length; i < l; ++i) {
				var glyph = font.glyphs[chars[i]] || font.missingGlyph;
				if (!glyph) continue;
				g.beginPath();
				if (glyph.d) {
					if (glyph.code) interpret(glyph.code, g);
					else glyph.code = generateFromVML('m' + glyph.d, g);
				}
				g.fill();
				g.translate(Number(glyph.w || font.w) + letterSpacing, 0);
			}
		}
		
		if (shadows) {
			for (var i = 0, l = shadows.length; i < l; ++i) {
				var shadow = shadows[i];
				g.save();
				g.fillStyle = shadow.color;
				g.translate.apply(g, shadowOffsets[i]);
				renderText();
				g.restore();
			}
		}
		
		renderText();
		
		g.restore();
		
		if (textDecoration['line-through']) line(-font.descent, textDecoration['line-through']);
		
		wrapper.appendChild(canvas);
		
		if (options.printable) {
			var print = document.createElement('span');
			print.className = 'cufon-alt';
			print.appendChild(document.createTextNode(text));
			wrapper.appendChild(print);
		}
		
		return wrapper;
			
	};
	
})());

Cufon.registerEngine('vml', (function() {

	if (!document.namespaces) return;

	// isn't undocumented stuff great?
	document.write('<!--[if vml]><script type="text/javascript">Cufon.vmlEnabled=true;</script><![endif]-->');
	if (!Cufon.vmlEnabled) return;
	
	if (document.namespaces['cvml'] == null) {
		document.namespaces.add('cvml', 'urn:schemas-microsoft-com:vml');
		document.write('<style type="text/css">' +
			'@media screen{' + 
				'cvml\\:shape,cvml\\:group,cvml\\:shapetype,cvml\\:fill{behavior:url(#default#VML);display:inline-block;antialias:true;position:absolute}' +
				'.cufon-vml{display:inline-block;position:relative;vertical-align:middle}' +
				'.cufon-vml .cufon-alt{display:none}' +
				'a .cufon-vml{cursor:pointer}' +
			'}' +
			'@media print{' + 
				'.cufon-vml *{display:none}' +
				'.cufon-vml .cufon-alt{display:inline}' +
			'}' +
		'</style>');
		// modified by Nathan 03/03/09.
		/*document.write('<style type="text/css">' +
			'@media screen{' + 
				'cvml\\:shape,cvml\\:group,cvml\\:shapetype,cvml\\:fill{behavior:url(#default#VML);display:inline-block;antialias:true}' +
				'.cufon-vml{display:inline-block;position:relative;vertical-align:middle}' +
				'.cufon-vml .cufon-alt{display:none}' +
				'a .cufon-vml{cursor:pointer}' +
			'}' +
			'@media print{' + 
				'.cufon-vml *{display:none}' +
				'.cufon-vml .cufon-alt{display:inline}' +
			'}' +
		'</style>');*/
	}

	var typeIndex = 0; // this is used to reference VML ShapeTypes

	function getFontSizeInPixels(el, value) {
		return getSizeInPixels(el, /(?:em|ex|%)$/i.test(value) ? '1em' : value);
	}
	
	// Original by Dead Edwards.
	// Combined with getFontSizeInPixels it also works with relative units.
	function getSizeInPixels(el, value) {
		if (/px$/i.test(value)) return parseFloat(value);
		var style = el.style.left, runtimeStyle = el.runtimeStyle.left;
		el.runtimeStyle.left = el.currentStyle.left;
		el.style.left = value;
		var result = el.style.pixelLeft;
		el.style.left = style;
		el.runtimeStyle.left = runtimeStyle;
		return result;
	}
	
	function createType(glyph, viewBox) {
		var shapeType = document.createElement('cvml:shapetype');
		shapeType.id = 'cufon-glyph-' + typeIndex++;
		glyph.typeRef = '#' + shapeType.id;
		shapeType.stroked = 'f';
		shapeType.coordsize = viewBox.width + ',' + viewBox.height;
		shapeType.coordorigin = viewBox.minX + ',' + viewBox.minY;
		var ensureSize = 'm' + viewBox.minX + ',' + viewBox.minY + ' r' + viewBox.width + ',' + viewBox.height;
		shapeType.path = (glyph.d ? 'm' + glyph.d + 'x' : '') + ensureSize;
		document.body.insertBefore(shapeType, document.body.firstChild);
	}
	
	return function(font, text, style, options, node, el, hasNext) {
	
		// @todo word-spacing, text-decoration
	
		var viewBox = font.viewBox;
		
		var size = style.computedFontSize || (style.computedFontSize = new Cufon.CSS.Size(getFontSizeInPixels(el, style.get('fontSize')) + 'px', font.baseSize));
		
		var letterSpacing = style.computedLSpacing;
		
		if (letterSpacing == undefined) {
			letterSpacing = style.get('letterSpacing');
			style.computedLSpacing = letterSpacing = (letterSpacing == 'normal') ? 0 : size.convertFrom(getSizeInPixels(el, letterSpacing));
		}
		
		var wrapper = document.createElement('span');
		wrapper.className = 'cufon cufon-vml';
		wrapper.alt = text;
		
		var canvas = document.createElement('cvml:group');
		
		var wStyle = wrapper.runtimeStyle;
		var cStyle = canvas.runtimeStyle;
		
		var height = size.convert(viewBox.height);
		
		cStyle.height = Math.ceil(height);
		cStyle.top = Math.round(size.convert(viewBox.minY - font.ascent));
		cStyle.left = Math.round(size.convert(viewBox.minX));
		
		var roundingFactor = parseInt(cStyle.height, 10) / height;
		
		wStyle.height = size.convert(-font.ascent + font.descent) + 'px';
		
		var textDecoration = options.enableTextDecoration ? Cufon.CSS.textDecoration(el, style) : {};
		
		var color = style.get('color');
		var chars = Cufon.CSS.textTransform(text, style).split('');
		
		var width = 0, offsetX = 0, advance = null;
		
		var shadows = options.textShadow;
		
		for (var i = 0, l = chars.length; i < l; ++i) {
		
			var glyph = font.glyphs[chars[i]] || font.missingGlyph;
			if (!glyph) continue;
			
			if (!glyph.typeRef) createType(glyph, viewBox);
			
			var shape = document.createElement('cvml:shape');
			shape.type = glyph.typeRef;
			var sStyle = shape.runtimeStyle;
			sStyle.width = viewBox.width;
			sStyle.height = viewBox.height;
			sStyle.top = 0;
			sStyle.left = offsetX;
			sStyle.zIndex = 1;
			shape.fillcolor = color;
			canvas.appendChild(shape);
			
			if (shadows) {
				// the VML shadow element is not used because it can only support
				// up to 2 shadows. and it breaks text selection.
				for (var z = 0, p = shadows.length; z < p; ++z) {
					var shadow = shadows[z];
					var shadowColor = Cufon.CSS.color(shadow.color);
					var shadowNode = shape.cloneNode(false), zStyle = shadowNode.runtimeStyle;
					zStyle.top = size.convertFrom(parseFloat(shadow.offY));
					zStyle.left = offsetX + size.convertFrom(parseFloat(shadow.offX));
					zStyle.zIndex = 0;
					shadowNode.fillcolor = shadowColor.color;
					if (shadowColor.opacity) {
						var shadowFill = document.createElement('cvml:fill');
						shadowFill.opacity = shadowColor.opacity;
						shadowNode.appendChild(shadowFill);
					}
					canvas.appendChild(shadowNode);
				}
			}
			
			advance = Number(glyph.w || font.w) + letterSpacing;
			
			width += advance;
			offsetX += advance;
			
		}
		
		if (advance === null) return null;
		
		var fullWidth = -viewBox.minX + width + (viewBox.width - advance);
		
		canvas.coordsize = fullWidth + ',' + viewBox.height;
		
		cStyle.width = size.convert(fullWidth * roundingFactor);
		
		wStyle.width = Math.max(Math.ceil(size.convert(width * roundingFactor)), 0);
		
		wrapper.appendChild(canvas);
	
		if (options.printable) {
			var print = document.createElement('span');
			print.className = 'cufon-alt';
			print.innerText = text;
			wrapper.appendChild(print);
		}
		
		// ie6, for some reason, has trouble rendering the last VML element in the document.
		// we can work around this by injecting a dummy element where needed.
		// @todo find a better solution
		if (!hasNext) wrapper.appendChild(document.createElement('cvml:group'));
		
		return wrapper;
		
	};
	
})());


Cufon.registerFont({"w":556,"face":{"font-family":"Helvetica Neue","font-weight":500,"font-stretch":"normal","units-per-em":"1000","panose-1":"2 11 6 0 0 0 0 0 0 0","ascent":"779","descent":"-221","x-height":"14","bbox":"-29 -809 938 214","underline-thickness":"50","underline-position":"-100","stemh":"90","stemv":"114","unicode-range":"U+0020-U+007E"},"glyphs":{" ":{"w":278},"\u00a0":{"w":278},"!":{"d":"77,-508r0,-206r125,0r0,206r-33,309r-59,0xm72,0r0,-125r134,0r0,125r-134,0","w":278},"\"":{"d":"83,-432r0,-282r102,0r0,282r-102,0xm259,-432r0,-282r102,0r0,282r-102,0","w":444},"#":{"d":"495,-285r0,75r-95,0r-30,210r-80,0r29,-210r-110,0r-30,210r-80,0r29,-210r-94,0r0,-75r105,0r18,-130r-94,0r0,-75r104,0r29,-210r81,0r-30,210r111,0r29,-210r81,0r-30,210r86,0r0,75r-96,0r-18,130r85,0xm348,-415r-111,0r-18,130r111,0"},"$":{"d":"302,-306r0,233v72,-5,123,-39,123,-119v0,-75,-61,-98,-123,-114xm17,-217r114,0v-1,88,37,141,128,144r0,-242v-109,-30,-227,-74,-227,-220v0,-127,108,-196,227,-196r0,-78r43,0r0,78v120,0,219,63,219,195r-114,0v-3,-67,-34,-105,-105,-105r0,211v121,32,237,77,237,222v0,150,-104,219,-237,225r0,78r-43,0r0,-78v-144,-3,-244,-85,-242,-234xm259,-441r0,-200v-72,0,-113,28,-113,98v0,65,57,88,113,102"},"%":{"d":"260,24r389,-748r76,0r-387,748r-78,0xm751,14v-121,0,-167,-90,-167,-199v0,-108,50,-199,167,-199v117,0,167,91,167,199v0,109,-46,199,-167,199xm674,-185v0,75,20,134,76,134v56,0,78,-59,78,-134v0,-67,-16,-134,-78,-134v-62,0,-76,67,-76,134xm249,-316v-121,0,-167,-90,-167,-199v0,-108,50,-199,167,-199v117,0,167,91,167,199v0,109,-46,199,-167,199xm172,-515v0,75,20,134,76,134v56,0,78,-59,78,-134v0,-67,-16,-134,-78,-134v-62,0,-76,67,-76,134","w":1000},"&":{"d":"302,-646v-42,0,-76,31,-76,79v0,47,39,83,65,119v43,-29,84,-59,84,-116v0,-47,-29,-82,-73,-82xm396,-156r-140,-174v-42,26,-110,49,-110,134v0,77,49,120,115,120v83,0,113,-51,135,-80xm522,0r-65,-80v-53,65,-117,94,-200,94v-131,0,-225,-78,-225,-212v0,-101,82,-165,164,-207v-37,-47,-72,-94,-72,-156v0,-103,78,-170,175,-170v92,0,178,57,178,171v0,84,-60,144,-129,181r111,134v8,-22,17,-50,22,-96r100,0v-7,62,-24,125,-56,175r137,166r-140,0","w":648},"(":{"d":"286,191r-93,0v-80,-127,-144,-270,-144,-461v0,-161,53,-321,144,-461r93,0v-161,277,-167,646,0,922","w":278},")":{"d":"-8,-731r93,0v80,128,144,271,144,462v0,161,-53,321,-144,460r-93,0v161,-276,167,-645,0,-922","w":278},"*":{"d":"130,-534r-111,-38r22,-65r110,43r0,-120r68,0r0,120r109,-43r24,65r-114,38r70,94r-53,39r-71,-98r-68,98r-56,-39","w":370},"+":{"d":"249,-304r0,-202r102,0r0,202r201,0r0,102r-201,0r0,202r-102,0r0,-202r-201,0r0,-102r201,0","w":600},",":{"d":"69,0r0,-135r139,0r0,135v-1,82,-56,142,-135,158r0,-61v44,-11,66,-54,65,-97r-69,0","w":278},"-":{"d":"49,-218r0,-108r291,0r0,108r-291,0","w":389},"\u00ad":{"d":"49,-218r0,-108r291,0r0,108r-291,0","w":389},".":{"d":"69,0r0,-135r139,0r0,135r-139,0","w":278},"\/":{"d":"-22,17r287,-748r109,0r-287,748r-109,0","w":352},"0":{"d":"278,-81v100,0,128,-123,128,-269v0,-146,-28,-269,-128,-269v-100,0,-128,123,-128,269v0,146,28,269,128,269xm278,-714v201,0,242,205,242,364v0,159,-41,364,-242,364v-201,0,-242,-205,-242,-364v0,-159,41,-364,242,-364"},"1":{"d":"53,-494r0,-90v96,1,187,-32,204,-116r93,0r0,700r-125,0r0,-494r-172,0"},"2":{"d":"517,-102r0,102r-478,0v1,-115,60,-202,154,-265v91,-66,209,-121,211,-230v1,-50,-20,-124,-118,-124v-90,0,-117,77,-120,175r-114,0v0,-155,85,-270,241,-270v171,0,225,125,225,215v0,111,-76,180,-156,236v-81,56,-166,99,-186,161r341,0"},"3":{"d":"228,-325r0,-85v76,3,155,-24,155,-110v0,-59,-46,-99,-109,-99v-79,0,-118,71,-116,143r-114,0v6,-136,91,-238,232,-238v109,0,221,63,221,187v2,72,-36,124,-99,152v79,16,127,85,127,175v0,132,-114,214,-248,214v-162,0,-243,-98,-246,-244r114,0v-3,85,43,149,132,149v76,0,134,-45,134,-125v0,-109,-93,-123,-183,-119"},"4":{"d":"522,-256r0,90r-90,0r0,166r-108,0r0,-166r-300,0r0,-113r300,-421r108,0r0,444r90,0xm322,-564r-210,308r212,0r0,-308r-2,0"},"5":{"d":"48,-317r75,-383r362,0r0,102r-277,0r-36,178r2,2v31,-34,82,-53,129,-53v139,0,219,100,219,234v0,112,-70,251,-242,251v-135,0,-240,-73,-245,-213r114,0v7,75,55,118,129,118v97,0,130,-69,130,-154v0,-77,-41,-146,-133,-146v-48,0,-95,15,-113,64r-114,0"},"6":{"d":"285,-81v82,0,123,-71,123,-146v0,-75,-41,-143,-123,-143v-83,0,-126,66,-126,143v0,76,43,146,126,146xm509,-523r-114,0v-5,-57,-43,-96,-102,-96v-124,0,-138,148,-145,240r2,2v31,-55,89,-83,151,-83v139,0,221,101,221,235v0,136,-93,239,-233,239v-206,0,-255,-162,-255,-366v0,-167,66,-362,264,-362v111,0,205,77,211,191"},"7":{"d":"35,-598r0,-102r479,0r0,95v-146,165,-243,352,-261,605r-125,0v15,-221,126,-436,270,-598r-363,0"},"8":{"d":"278,-76v76,0,133,-48,133,-130v0,-77,-57,-123,-133,-123v-76,0,-133,46,-133,123v0,82,57,130,133,130xm278,14v-142,0,-247,-83,-247,-220v-2,-90,54,-148,128,-173v-63,-24,-99,-76,-99,-144v0,-119,79,-191,218,-191v139,0,218,72,218,191v2,70,-40,118,-99,146v78,20,128,83,128,171v0,137,-105,220,-247,220xm278,-624v-61,0,-110,38,-110,107v0,66,47,103,110,103v63,0,110,-37,110,-103v0,-69,-49,-107,-110,-107"},"9":{"d":"270,-619v-83,0,-122,67,-122,143v0,76,39,147,122,147v85,0,127,-70,127,-147v0,-75,-42,-143,-127,-143xm47,-177r114,0v5,57,43,96,102,96v124,0,138,-148,145,-240r-2,-2v-30,54,-87,84,-151,84v-132,0,-221,-93,-221,-236v0,-136,88,-239,241,-239v198,0,247,162,247,366v0,167,-66,362,-264,362v-111,0,-205,-77,-211,-191"},":":{"d":"69,-371r0,-135r139,0r0,135r-139,0xm69,0r0,-135r139,0r0,135r-139,0","w":278},";":{"d":"69,0r0,-135r139,0r0,135v-1,82,-56,142,-135,158r0,-61v44,-11,66,-54,65,-97r-69,0xm69,-371r0,-135r139,0r0,135r-139,0","w":278},"<":{"d":"554,-94r0,102r-508,-225r0,-72r508,-225r0,102r-374,159","w":600},"=":{"d":"552,-405r0,102r-504,0r0,-102r504,0xm552,-203r0,102r-504,0r0,-102r504,0","w":600},">":{"d":"46,-94r374,-159r-374,-159r0,-102r508,225r0,72r-508,225r0,-102","w":600},"?":{"d":"507,-529v1,186,-182,149,-176,335r-108,0v0,-117,25,-157,78,-203v43,-37,81,-61,81,-128v0,-81,-62,-111,-98,-111v-82,0,-121,59,-121,149r-114,0v-1,-147,93,-244,240,-244v122,0,218,73,218,202xm208,0r0,-125r134,0r0,125r-134,0"},"@":{"d":"361,-216v79,0,137,-105,137,-178v0,-47,-36,-88,-79,-88v-83,0,-138,100,-138,175v0,53,31,91,80,91xm615,-542r-72,263v-10,31,-17,69,10,69v62,0,130,-94,130,-216v0,-149,-121,-240,-267,-240v-170,0,-287,133,-287,300v0,195,127,318,296,318v87,0,171,-37,225,-99r70,0v-64,103,-176,164,-299,164v-206,0,-372,-158,-372,-387v0,-202,168,-361,367,-361v178,0,335,121,335,293v0,201,-155,298,-236,298v-34,2,-54,-24,-61,-58v-27,30,-69,57,-112,57v-83,0,-146,-71,-146,-157v0,-127,88,-259,219,-259v47,0,87,21,112,72r18,-57r70,0","w":800},"A":{"d":"331,-591r-108,307r218,0r-107,-307r-3,0xm-7,0r274,-714r133,0r275,714r-134,0r-67,-189r-285,0r-67,189r-129,0","w":667},"B":{"d":"201,-325r0,223r221,0v76,0,120,-41,120,-113v0,-70,-44,-110,-120,-110r-221,0xm76,0r0,-714r347,0v128,0,212,58,212,177v2,74,-41,122,-102,154v87,19,134,87,134,184v0,112,-78,199,-263,199r-328,0xm201,-612r0,197r204,0v60,0,105,-35,105,-99v0,-72,-37,-98,-105,-98r-204,0","w":704},"C":{"d":"683,-487r-125,0v-21,-82,-74,-142,-178,-142v-153,0,-217,135,-217,272v0,137,64,272,217,272v111,0,172,-83,182,-187r122,0v-10,171,-131,289,-304,289v-214,0,-342,-170,-342,-374v0,-204,128,-374,342,-374v161,1,288,90,303,244","w":722},"D":{"d":"201,-612r0,510r123,0v196,0,238,-112,238,-255v0,-143,-42,-255,-238,-255r-123,0xm76,0r0,-714r296,0v220,0,315,160,315,357v0,197,-95,357,-315,357r-296,0","w":722},"E":{"d":"76,0r0,-714r514,0r0,108r-389,0r0,187r360,0r0,102r-360,0r0,209r396,0r0,108r-521,0","w":630},"F":{"d":"76,0r0,-714r493,0r0,108r-368,0r0,187r323,0r0,102r-323,0r0,317r-125,0","w":593},"G":{"d":"699,-376r0,376r-80,0r-19,-84v-67,76,-128,101,-215,101v-214,0,-342,-170,-342,-374v0,-204,128,-374,342,-374v156,0,287,83,306,244r-122,0v-12,-94,-94,-142,-184,-142v-153,0,-217,135,-217,272v0,137,64,272,217,272v128,2,198,-75,200,-196r-190,0r0,-95r304,0","w":759},"H":{"d":"73,0r0,-714r125,0r0,284r325,0r0,-284r125,0r0,714r-125,0r0,-322r-325,0r0,322r-125,0","w":722},"I":{"d":"76,0r0,-714r125,0r0,714r-125,0","w":278},"J":{"d":"461,-714r0,484v0,124,-30,247,-235,247v-165,-3,-221,-111,-213,-267r125,0v-3,94,8,168,98,165v81,0,100,-49,100,-138r0,-491r125,0","w":537},"K":{"d":"76,0r0,-714r125,0r0,325r318,-325r154,0r-285,285r305,429r-156,0r-234,-341r-102,101r0,240r-125,0","w":685},"L":{"d":"76,0r0,-714r125,0r0,606r363,0r0,108r-488,0","w":574},"M":{"d":"74,0r0,-714r176,0r197,559r2,0r192,-559r174,0r0,714r-119,0r0,-551r-2,0r-198,551r-103,0r-198,-551r-2,0r0,551r-119,0","w":889},"N":{"d":"71,0r0,-714r132,0r326,526r2,0r0,-526r119,0r0,714r-132,0r-325,-525r-3,0r0,525r-119,0","w":722},"O":{"d":"380,-731v214,0,342,170,342,374v0,204,-128,374,-342,374v-214,0,-342,-170,-342,-374v0,-204,128,-374,342,-374xm380,-629v-153,0,-217,135,-217,272v0,137,64,272,217,272v153,0,217,-135,217,-272v0,-137,-64,-272,-217,-272","w":760},"P":{"d":"201,-612r0,236v143,-8,298,43,308,-118v-1,-167,-167,-107,-308,-118xm76,0r0,-714r315,0v204,0,243,132,243,221v0,88,-39,220,-243,219r-190,0r0,274r-125,0","w":667},"Q":{"d":"460,-102r-72,-63r60,-69r87,76v118,-154,74,-471,-155,-471v-153,0,-217,135,-217,272v0,137,64,272,217,272v26,0,55,-5,80,-17xm621,-83r92,80r-61,68r-104,-91v-53,30,-112,43,-168,43v-214,0,-342,-170,-342,-374v0,-204,128,-374,342,-374v214,0,342,170,342,374v0,98,-30,206,-101,274","w":760},"R":{"d":"201,-612r0,223r205,0v79,0,122,-39,122,-114v0,-91,-59,-109,-124,-109r-203,0xm76,0r0,-714r341,0v156,0,236,72,236,193v1,140,-97,168,-118,182v43,6,106,38,106,151v0,83,12,159,39,188r-134,0v-19,-31,-19,-70,-19,-105v0,-131,-27,-189,-142,-189r-184,0r0,294r-125,0","w":704},"S":{"d":"33,-238r125,0v0,110,81,153,181,153v110,0,151,-54,151,-108v0,-55,-30,-77,-59,-88v-50,-19,-115,-32,-213,-59v-122,-33,-158,-107,-158,-181v0,-143,132,-210,261,-210v149,0,274,79,274,228r-125,0v-6,-92,-68,-126,-154,-126v-58,0,-131,21,-131,93v0,50,34,78,85,92v11,3,169,44,206,55v94,28,139,108,139,182v0,160,-142,224,-284,224v-163,0,-295,-78,-298,-255","w":648},"T":{"d":"8,-606r0,-108r578,0r0,108r-227,0r0,606r-125,0r0,-606r-226,0","w":593},"U":{"d":"68,-257r0,-457r125,0r0,416v0,96,6,207,168,207v162,0,168,-111,168,-207r0,-416r125,0r0,457v0,183,-117,274,-293,274v-176,0,-293,-91,-293,-274","w":722},"V":{"d":"233,0r-238,-714r130,0r179,565r2,0r183,-565r127,0r-244,714r-139,0","w":611},"W":{"d":"194,0r-188,-714r127,0r129,546r2,0r144,-546r128,0r140,546r2,0r133,-546r127,0r-197,714r-127,0r-143,-546r-2,0r-146,546r-129,0","w":944},"X":{"d":"250,-370r-236,-344r149,0r162,252r169,-252r140,0r-236,344r253,370r-152,0r-178,-273r-181,273r-143,0","w":648},"Y":{"d":"262,0r0,-280r-268,-434r145,0r189,320r186,-320r140,0r-267,434r0,280r-125,0","w":648},"Z":{"d":"55,-606r0,-108r543,0r0,95r-416,511r426,0r0,108r-585,0r0,-102r416,-504r-384,0","w":630},"[":{"d":"72,191r0,-922r223,0r0,90r-115,0r0,742r115,0r0,90r-223,0","w":296},"\\":{"d":"87,-731r287,748r-109,0r-287,-748r109,0","w":352},"]":{"d":"224,-731r0,922r-223,0r0,-90r115,0r0,-742r-115,0r0,-90r223,0","w":296},"^":{"d":"186,-335r-102,0r180,-365r72,0r180,365r-102,0r-114,-247","w":600},"_":{"d":"500,125r-500,0r0,-50r500,0r0,50","w":500},"a":{"d":"379,-259v-71,46,-232,-1,-233,117v0,51,65,66,105,66v50,0,128,-26,128,-98r0,-85xm493,-381r0,266v-2,42,19,42,55,37r0,79v-62,20,-150,24,-160,-50v-105,100,-353,90,-356,-88v0,-129,103,-150,199,-161v82,-15,155,-6,155,-73v0,-59,-61,-70,-107,-70v-64,0,-109,26,-114,82r-114,0v8,-133,121,-172,235,-172v101,0,207,41,207,150"},"b":{"d":"318,-76v200,0,184,-367,0,-365v-96,0,-145,73,-145,183v0,104,53,182,145,182xm63,0r0,-714r114,0r0,264r2,0v31,-50,96,-81,154,-81v163,0,242,124,242,275v0,139,-70,270,-223,270v-70,0,-145,-17,-179,-85r-2,0r0,71r-108,0","w":611},"c":{"d":"523,-344r-114,0v-9,-63,-55,-97,-118,-97v-59,0,-142,31,-142,188v0,86,38,177,137,177v66,0,112,-44,123,-118r114,0v-21,134,-104,208,-237,208v-162,0,-251,-115,-251,-267v0,-156,85,-278,255,-278v120,0,222,60,233,187"},"d":{"d":"149,-253v0,89,44,177,143,177v102,0,145,-93,145,-183v0,-114,-55,-182,-143,-182v-107,0,-145,95,-145,188xm547,-714r0,714r-108,0v-2,-22,4,-52,-2,-70v-30,59,-95,84,-160,84v-163,0,-242,-121,-242,-276v0,-187,111,-269,224,-269v67,-2,136,27,174,81r0,-264r114,0","w":611},"e":{"d":"529,-229r-380,0v0,81,44,153,139,153v66,0,106,-29,126,-86r108,0v-25,113,-121,176,-234,176v-162,0,-253,-113,-253,-272v0,-147,96,-273,250,-273v163,0,263,147,244,302xm149,-304r266,0v-4,-72,-53,-137,-130,-137v-79,0,-133,60,-136,137"},"f":{"d":"9,-432r0,-85r85,0r0,-43v0,-169,111,-162,223,-147r0,89v-44,-9,-112,-18,-109,48r0,53r97,0r0,85r-97,0r0,432r-114,0r0,-432r-85,0","w":315},"g":{"d":"285,-90v101,0,139,-92,139,-180v0,-89,-40,-171,-139,-171v-101,0,-136,94,-136,180v0,85,41,171,136,171xm538,-517r0,490v0,155,-91,232,-254,232v-104,0,-221,-40,-231,-161r114,0v14,65,66,76,124,76v92,0,133,-47,133,-132v-2,-25,4,-58,-2,-79v-32,57,-91,91,-155,91v-164,0,-232,-124,-232,-272v0,-139,87,-259,234,-259v67,-2,122,31,155,85r0,-71r114,0","w":593},"h":{"d":"60,0r0,-714r114,0r0,265r2,0v28,-47,87,-82,155,-82v112,0,183,60,183,176r0,355r-114,0r0,-325v-2,-81,-34,-116,-101,-116v-76,0,-125,60,-125,136r0,305r-114,0","w":574},"i":{"d":"63,0r0,-517r114,0r0,517r-114,0xm63,-606r0,-108r114,0r0,108r-114,0","w":241},"j":{"d":"63,39r0,-556r114,0r0,561v7,122,-74,178,-199,157r0,-90v15,2,28,4,39,4v42,0,46,-25,46,-76xm63,-606r0,-108r114,0r0,108r-114,0","w":241},"k":{"d":"63,0r0,-714r114,0r0,406r206,-209r140,0r-198,190r217,327r-139,0r-158,-251r-68,66r0,185r-114,0","w":537},"l":{"d":"63,0r0,-714r114,0r0,714r-114,0","w":241},"m":{"d":"60,0r0,-517r108,0r0,72r3,0v34,-51,77,-86,159,-86v63,0,122,27,145,86v38,-53,87,-86,162,-86v109,0,173,48,173,174r0,357r-114,0r0,-302v0,-82,-5,-139,-94,-139v-77,0,-110,51,-110,138r0,303r-114,0r0,-332v0,-71,-22,-109,-91,-109v-59,0,-113,48,-113,134r0,307r-114,0","w":870},"n":{"d":"60,0r0,-517r108,0v2,25,-3,57,2,78v34,-57,93,-92,161,-92v112,0,183,60,183,176r0,355r-114,0r0,-325v-2,-81,-34,-116,-101,-116v-76,0,-125,60,-125,136r0,305r-114,0","w":574},"o":{"d":"297,-76v198,-2,198,-363,0,-365v-199,2,-197,363,0,365xm297,14v-166,0,-261,-114,-261,-273v0,-158,95,-272,261,-272v166,0,261,114,261,272v0,159,-95,273,-261,273","w":593},"p":{"d":"318,-76v200,0,184,-367,0,-365v-96,0,-145,73,-145,183v0,104,53,182,145,182xm63,191r0,-708r108,0v2,22,-4,52,2,70v32,-59,94,-84,160,-84v163,0,242,124,242,275v0,139,-70,270,-223,270v-68,2,-136,-27,-175,-81r0,258r-114,0","w":611},"q":{"d":"149,-258v0,90,39,182,143,182v99,0,145,-74,145,-182v0,-112,-50,-183,-145,-183v-94,0,-143,89,-143,183xm547,-517r0,708r-114,0r0,-258r-2,0v-36,57,-107,81,-173,81v-153,0,-223,-131,-223,-270v0,-151,79,-275,242,-275v68,-2,126,29,162,84r0,-70r108,0","w":611},"r":{"d":"60,0r0,-517r107,0v2,32,-4,72,2,100v16,-66,102,-131,194,-111r0,110v-114,-24,-185,38,-189,172r0,246r-114,0","w":352},"s":{"d":"32,-166r114,0v6,66,56,90,117,90v43,0,118,-9,115,-68v-3,-60,-86,-67,-169,-86v-84,-18,-166,-48,-166,-153v0,-113,122,-148,216,-148v106,0,202,44,216,159r-119,0v-10,-54,-55,-69,-105,-69v-33,0,-94,8,-94,53v0,56,84,64,168,83v83,19,167,49,167,151v0,123,-124,168,-231,168v-130,0,-227,-58,-229,-180","w":519},"t":{"d":"8,-432r0,-85r86,0r0,-155r114,0r0,155r103,0r0,85r-103,0r0,276v0,47,4,71,55,71v16,0,32,0,48,-4r0,88v-25,2,-49,6,-74,6v-119,0,-141,-46,-143,-132r0,-305r-86,0","w":333},"u":{"d":"514,-517r0,517r-112,0v-2,-23,4,-53,-2,-72v-28,52,-90,86,-147,86v-135,0,-193,-68,-193,-203r0,-328r114,0r0,317v0,91,37,124,99,124v95,0,127,-61,127,-141r0,-300r114,0","w":574},"v":{"d":"197,0r-188,-517r124,0r131,397r2,0r126,-397r118,0r-185,517r-128,0","w":519},"w":{"d":"173,0r-160,-517r121,0r101,386r2,0r97,-386r115,0r93,386r2,0r105,-386r116,0r-162,517r-117,0r-96,-384r-2,0r-95,384r-120,0","w":778},"x":{"d":"4,0r195,-272r-179,-245r138,0r108,159r113,-159r132,0r-176,239r198,278r-137,0r-131,-191r-127,191r-134,0","w":537},"y":{"d":"199,-2r-196,-515r125,0r135,386r2,0r131,-386r119,0r-201,545v-37,93,-64,177,-183,177v-27,0,-53,-2,-79,-6r0,-96v18,3,36,7,54,7v70,3,74,-61,93,-112","w":519},"z":{"d":"42,-427r0,-90r420,0r0,80r-296,347r311,0r0,90r-455,0r0,-80r286,-347r-266,0","w":500},"{":{"d":"-4,-225r0,-90v28,0,94,-15,94,-73r0,-206v0,-94,85,-137,128,-137r91,0r0,90r-55,0v-51,0,-56,40,-56,70r0,195v0,84,-75,97,-104,107v32,3,103,14,104,111r0,189v0,30,5,70,56,70r55,0r0,90r-91,0v-43,0,-128,-43,-128,-137r0,-198v0,-65,-66,-81,-94,-81","w":296},"|":{"d":"60,214r0,-1000r102,0r0,1000r-102,0","w":222},"}":{"d":"300,-315r0,90v-28,0,-94,15,-94,73r0,206v0,94,-85,137,-128,137r-91,0r0,-90r55,0v51,0,56,-40,56,-70r0,-195v0,-84,75,-97,104,-107v-32,-3,-103,-14,-104,-111r0,-189v0,-30,-5,-70,-56,-70r-55,0r0,-90r91,0v43,0,128,43,128,137r0,198v0,65,66,81,94,81","w":296},"~":{"d":"194,-338v66,-2,155,64,213,68v40,0,65,-37,88,-68r36,84v-30,42,-63,86,-125,86v-80,0,-130,-70,-217,-68v-44,0,-68,37,-84,68r-36,-84v22,-42,58,-86,125,-86","w":600},"'":{"d":"88,-432r0,-282r102,0r0,282r-102,0","w":278},"`":{"d":"-29,-731r134,0r91,143r-83,0","w":241}}});

Cufon.registerFont({"w":556,"face":{"font-family":"Helvetica Neue","font-weight":300,"font-style":"italic","font-stretch":"normal","units-per-em":"1000","panose-1":"2 11 4 0 0 0 0 0 0 0","ascent":"786","descent":"-214","x-height":"15","bbox":"-137 -786 978 214","underline-thickness":"50","underline-position":"-100","slope":"-12","stemh":"53","stemv":"63","unicode-range":"U+0020-U+007E"},"glyphs":{" ":{"w":278},"\u00a0":{"w":278},"!":{"d":"107,0r-84,0r23,-106r85,0xm122,-178r-38,0r53,-314r48,-222r67,0r-48,223","w":278},"\"":{"d":"137,-471r0,-243r58,0r0,243r-58,0xm262,-471r0,-243r58,0r0,243r-58,0","w":370},"#":{"d":"497,-268r-10,45r-101,0r-31,223r-50,0r31,-223r-141,0r-31,223r-50,0r31,-223r-110,0r10,-45r106,0r22,-156r-110,0r10,-45r106,0r31,-222r50,0r-31,222r141,0r31,-222r50,0r-31,222r105,0r-10,45r-101,0r-22,156r105,0xm364,-424r-141,0r-22,156r141,0"},"$":{"d":"268,-406r56,-265v-92,0,-190,37,-190,143v0,82,69,103,134,122xm297,-332r-61,288v103,6,215,-41,218,-152v0,-93,-83,-116,-157,-136xm573,-506r-68,0v-1,-106,-48,-150,-137,-161r-58,274v104,32,212,60,212,188v0,70,-44,220,-276,220v-8,0,-16,0,-23,-1r-18,86r-45,0r20,-91v-125,-18,-210,-96,-203,-244r68,0v-6,117,52,172,147,186r63,-296v-99,-23,-192,-68,-189,-180v0,-153,136,-204,270,-204r11,-52r45,0r-12,56v116,15,200,78,193,219"},"%":{"d":"104,32r570,-755r55,0r-571,755r-54,0xm202,-327v-88,0,-135,-59,-135,-141v0,-111,60,-238,186,-238v82,0,134,58,134,139v0,111,-58,240,-185,240xm203,-372v94,0,131,-114,131,-192v0,-56,-23,-97,-84,-97v-91,0,-130,121,-130,195v0,49,27,94,83,94xm581,15v-88,0,-135,-59,-135,-141v0,-111,60,-238,186,-238v82,0,134,58,134,139v0,111,-58,240,-185,240xm581,-30v94,0,131,-114,131,-192v0,-56,-23,-97,-84,-97v-91,0,-130,121,-130,195v0,49,27,94,83,94","w":833},"&":{"d":"278,-420v56,-31,147,-77,147,-152v0,-59,-43,-89,-96,-89v-57,0,-107,42,-107,102v0,48,33,99,56,139xm396,-130r-141,-221v-78,38,-175,87,-175,187v0,70,60,126,133,126v77,0,132,-30,183,-92xm489,-315r63,0v-15,67,-40,129,-85,187r83,128r-71,0r-54,-84v-51,62,-124,99,-207,99v-117,0,-201,-64,-201,-183v0,-124,109,-179,210,-227v-36,-54,-68,-99,-68,-166v0,-93,76,-153,172,-153v80,0,157,45,157,130v0,105,-101,161,-182,206r128,199v28,-35,45,-88,55,-136","w":611},"(":{"d":"156,191r-43,0v-44,-123,-71,-248,-64,-379v11,-212,108,-395,244,-541r52,0v-213,244,-300,564,-189,920","w":259},")":{"d":"87,-729r43,0v44,123,71,248,64,379v-11,212,-108,395,-244,541r-52,0v213,-244,300,-564,189,-920","w":259},"*":{"d":"173,-561r-101,-55r21,-35r102,57r26,-120r39,0r-25,124r116,-24r5,38r-115,25r60,102r-38,19r-59,-106r-86,92r-28,-27","w":352},"+":{"d":"274,-278r0,-225r53,0r0,225r225,0r0,53r-225,0r0,225r-53,0r0,-225r-225,0r0,-53r225,0","w":600},",":{"d":"-12,137r8,-40v47,-14,58,-54,69,-97r-42,0r24,-106r84,0r-33,140v-15,64,-45,86,-110,103","w":278},"-":{"d":"38,-246r12,-58r251,0r-12,58r-251,0","w":370},"\u00ad":{"d":"38,-246r12,-58r251,0r-12,58r-251,0","w":370},".":{"d":"107,0r-84,0r23,-106r85,0","w":278},"\/":{"d":"391,-729r-411,744r-59,0r411,-744r59,0","w":333},"0":{"d":"216,15v-150,0,-191,-131,-191,-259v0,-176,91,-462,308,-462v149,0,198,113,198,245v0,188,-85,476,-315,476xm468,-468v0,-95,-28,-185,-142,-185v-170,0,-238,297,-238,429v0,96,31,186,143,186v174,0,237,-296,237,-430"},"1":{"d":"134,-525r13,-50v86,-13,175,-49,222,-125r48,0r-150,700r-63,0r124,-581v-61,32,-127,45,-194,56"},"2":{"d":"523,-526v-6,258,-393,266,-461,468r391,0r-11,58r-453,0v8,-149,126,-221,241,-285v116,-64,230,-121,230,-243v0,-85,-68,-125,-144,-125v-107,0,-168,86,-173,187r-63,0v6,-138,104,-240,242,-240v110,0,201,63,201,180"},"3":{"d":"9,-222r63,0v-6,109,44,184,154,184v103,0,189,-70,189,-174v-2,-108,-86,-134,-190,-129r11,-53v113,2,217,-5,222,-137v0,-80,-65,-122,-136,-122v-102,0,-159,65,-175,166r-63,0v24,-134,100,-219,240,-219v104,0,197,58,197,173v2,90,-66,151,-147,170v69,17,104,76,104,147v0,147,-120,231,-247,231v-165,0,-226,-98,-222,-237"},"4":{"d":"407,-592r-335,365r258,0r79,-363xm10,-233r429,-467r56,0r-102,473r106,0r-12,53r-105,0r-38,174r-63,0r38,-174r-320,0"},"5":{"d":"60,-335r115,-356r357,0r-14,58r-306,0r-75,224v42,-36,97,-57,156,-55v121,0,194,90,194,206v0,159,-107,273,-267,273v-130,0,-213,-82,-205,-213r63,0v-9,101,49,160,149,160v119,0,197,-98,197,-209v0,-97,-51,-164,-153,-164v-62,0,-122,22,-155,81"},"6":{"d":"436,-252v0,-93,-68,-151,-159,-151v-108,0,-178,99,-178,200v0,91,57,165,153,165v121,0,184,-104,184,-214xm36,-221v1,-205,95,-492,316,-485v119,0,194,60,194,183r-63,0v-3,-88,-47,-130,-135,-130v-151,0,-206,181,-235,296r2,0v38,-64,108,-99,184,-99v123,0,200,94,200,212v0,151,-103,259,-255,259v-142,0,-208,-102,-208,-236"},"7":{"d":"110,-633r14,-58r447,0r-13,54v-175,170,-314,401,-387,637r-70,0v80,-259,223,-457,390,-633r-381,0"},"8":{"d":"81,-183v0,100,73,145,165,145v102,0,181,-63,181,-167v0,-104,-76,-140,-172,-140v-97,0,-174,62,-174,162xm490,-202v7,264,-473,305,-472,18v0,-112,81,-185,185,-196r0,-2v-62,-20,-100,-77,-100,-140v0,-117,101,-184,210,-184v106,0,209,47,209,169v1,89,-65,153,-148,169v77,22,116,89,116,166xm317,-653v-79,0,-151,48,-151,134v0,83,65,121,142,121v83,0,151,-47,151,-135v0,-84,-64,-120,-142,-120"},"9":{"d":"302,-653v-121,0,-184,104,-184,214v0,93,68,151,159,151v108,0,178,-99,178,-200v0,-91,-57,-165,-153,-165xm518,-470v-1,205,-95,492,-316,485v-119,0,-194,-60,-194,-183r63,0v3,88,47,130,135,130v151,0,206,-181,235,-296r-2,0v-38,64,-108,99,-184,99v-123,0,-200,-94,-200,-212v0,-151,103,-259,255,-259v142,0,208,102,208,236"},":":{"d":"107,0r-84,0r23,-106r85,0xm197,-394r-84,0r23,-106r85,0","w":278},";":{"d":"-12,137r8,-40v47,-14,58,-54,69,-97r-42,0r24,-106r84,0r-33,140v-15,64,-45,86,-110,103xm197,-394r-84,0r23,-106r85,0","w":278},"<":{"d":"554,-47r0,55r-508,-234r0,-54r508,-234r0,55r-446,206","w":600},"=":{"d":"552,-378r0,53r-503,0r0,-53r503,0xm552,-181r0,53r-503,0r0,-53r503,0","w":600},">":{"d":"46,-47r446,-206r-446,-206r0,-55r508,234r0,54r-508,234r0,-55","w":600},"?":{"d":"258,-182r-63,0v16,-116,60,-148,148,-211v56,-37,114,-90,114,-159v0,-81,-55,-124,-134,-124v-105,0,-165,80,-173,183r-63,0v6,-144,95,-236,239,-236v101,0,194,56,194,168v0,109,-77,167,-160,222v-69,43,-86,81,-102,157xm147,0r23,-106r85,0r-24,106r-84,0","w":537},"@":{"d":"426,-510v-102,0,-170,137,-170,231v0,60,35,97,83,97v93,0,166,-147,166,-235v0,-47,-40,-93,-79,-93xm561,-544r53,0r-96,288v-14,43,-20,83,13,83v89,0,169,-136,169,-248v0,-165,-130,-263,-284,-263v-187,0,-316,147,-316,331v0,182,136,323,318,323v98,0,200,-50,258,-133r51,0v-60,110,-184,178,-309,178v-215,0,-371,-164,-371,-375v0,-208,163,-369,367,-369v193,0,339,127,339,311v0,161,-120,290,-232,290v-36,2,-60,-28,-69,-67v-30,32,-76,66,-127,66v-82,0,-132,-66,-132,-145v0,-138,95,-289,237,-289v44,0,84,24,106,84","w":800},"A":{"d":"-75,0r437,-714r74,0r130,714r-71,0r-36,-222r-326,0r-132,222r-76,0xm386,-656r-219,376r282,0r-61,-376r-2,0","w":630},"B":{"d":"148,-343r-62,285r242,0v99,0,204,-46,204,-158v-6,-179,-221,-115,-384,-127xm5,0r155,-714r277,0v107,0,196,44,196,163v2,96,-67,160,-155,180v74,9,122,73,122,147v0,168,-138,224,-287,224r-308,0xm216,-656r-55,255r225,0v92,-2,179,-46,179,-143v-1,-160,-204,-101,-349,-112","w":667},"C":{"d":"688,-488r-68,0v-2,-120,-81,-183,-199,-183v-215,0,-319,194,-319,388v0,146,88,240,236,240v114,0,207,-76,242,-201r68,0v-33,146,-138,259,-321,259v-186,0,-293,-124,-293,-304v0,-228,143,-440,388,-440v150,0,264,82,266,241","w":704},"D":{"d":"216,-656r-130,598r172,0v237,2,336,-185,336,-383v0,-143,-72,-215,-215,-215r-163,0xm5,0r155,-714r230,0v205,0,272,114,272,286v0,225,-135,428,-391,428r-266,0","w":685},"E":{"d":"5,0r152,-714r479,0r-13,58r-410,0r-55,258r383,0r-13,58r-382,0r-60,282r420,0r-13,58r-488,0","w":574},"F":{"d":"5,0r153,-714r457,0r-12,58r-389,0r-55,258r345,0r-11,58r-347,0r-73,340r-68,0","w":537},"G":{"d":"706,-494r-68,0v-4,-119,-91,-177,-221,-177v-188,0,-315,191,-315,383v0,146,78,245,231,245v157,0,261,-113,285,-262r-246,0r14,-58r305,0r-75,363r-46,0v2,-39,13,-85,10,-120v-60,94,-148,135,-259,135v-185,0,-287,-116,-287,-299v0,-230,134,-445,389,-445v179,0,278,87,283,235","w":741},"H":{"d":"5,0r152,-714r68,0r-66,310r413,0r66,-310r68,0r-152,714r-68,0r74,-346r-413,0r-74,346r-68,0","w":704},"I":{"d":"5,0r151,-714r68,0r-151,714r-68,0","w":222},"J":{"d":"-11,-229r68,0v-5,29,-9,59,-9,88v0,73,57,98,124,98v103,0,135,-78,153,-162r109,-509r68,0r-114,534v-27,124,-85,195,-221,195v-106,0,-187,-46,-187,-163v0,-27,3,-55,9,-81","w":500},"K":{"d":"5,0r152,-714r68,0r-82,381r2,2r461,-383r95,0r-366,298r255,416r-78,0r-227,-374r-159,127r-53,247r-68,0","w":648},"L":{"d":"5,0r154,-714r68,0r-141,656r395,0r-14,58r-462,0","w":537},"M":{"d":"2,0r155,-714r99,0r111,641r392,-641r99,0r-153,714r-67,0r147,-646r-2,0r-395,646r-68,0r-115,-656r-2,0r-135,656r-66,0","w":852},"N":{"d":"0,0r154,-714r77,0r285,638r2,0r132,-638r66,0r-156,714r-75,0r-285,-638r-2,0r-133,638r-65,0","w":704},"O":{"d":"650,-413v0,-148,-72,-258,-229,-258v-215,0,-319,194,-319,388v0,146,88,240,236,240v194,0,312,-193,312,-370xm327,15v-186,0,-293,-124,-293,-304v0,-228,143,-440,388,-440v182,0,296,119,296,299v0,233,-139,445,-391,445","w":741},"P":{"d":"5,0r154,-714r288,0v107,0,190,66,190,176v0,148,-103,232,-246,232r-252,0r-66,306r-68,0xm215,-656r-63,292r241,0v99,0,176,-61,176,-164v5,-173,-199,-120,-354,-128","w":630},"Q":{"d":"558,-62r91,85r-40,41r-100,-94v-51,29,-112,45,-182,45v-186,0,-293,-124,-293,-304v0,-228,143,-440,388,-440v182,0,296,119,296,299v0,147,-56,286,-160,368xm382,-149r39,-41r90,84v89,-69,139,-191,139,-307v0,-148,-72,-258,-229,-258v-215,0,-319,194,-319,388v0,146,88,240,236,240v46,0,88,-12,124,-32","w":741},"R":{"d":"5,0r152,-714r304,0v119,0,187,61,187,178v2,108,-81,185,-181,197v121,21,87,162,81,277v0,17,2,48,12,62r-70,0v-22,-59,-1,-136,0,-201v0,-68,-25,-116,-98,-116r-252,0r-67,317r-68,0xm213,-656r-60,281r241,0v103,0,186,-50,186,-156v0,-84,-35,-125,-122,-125r-245,0","w":648},"S":{"d":"607,-506r-68,0v-1,-125,-67,-165,-189,-165v-88,0,-182,41,-182,143v2,107,115,111,196,141v98,30,192,62,192,182v0,70,-44,220,-276,220v-160,0,-277,-77,-269,-250r68,0v-7,139,76,192,206,192v93,0,203,-46,203,-153v-4,-129,-152,-125,-247,-163v-83,-24,-141,-74,-141,-166v0,-143,126,-204,253,-204v145,0,262,58,254,223","w":630},"T":{"d":"69,-656r12,-58r558,0r-12,58r-245,0r-143,656r-68,0r143,-656r-245,0"},"U":{"d":"54,-248r96,-466r68,0r-95,454v-34,137,44,220,188,217v128,0,206,-68,231,-188r101,-483r68,0r-102,488v-35,168,-144,241,-307,241v-144,5,-288,-85,-248,-263","w":704},"V":{"d":"176,0r-112,-714r70,0r91,656r2,0r366,-656r74,0r-412,714r-79,0","w":593},"W":{"d":"124,0r-53,-714r68,0r37,635r2,0r304,-635r82,0r49,629r2,0r292,-629r71,0r-344,714r-74,0r-47,-649r-2,0r-312,649r-75,0","w":907},"X":{"d":"-68,0r328,-372r-176,-342r75,0r148,300r259,-300r81,0r-310,353r186,361r-72,0r-159,-318r-280,318r-80,0","w":574},"Y":{"d":"299,-352r299,-362r83,0r-358,426r-63,288r-69,0r65,-295r-190,-419r72,0","w":574},"Z":{"d":"98,-656r13,-58r515,0r-12,57r-571,599r476,0r-13,58r-556,0r13,-60r569,-596r-434,0","w":574},"[":{"d":"133,191r-161,0r195,-920r163,0r-11,53r-98,0r-175,814r97,0","w":241},"\\":{"d":"353,15r-411,-744r59,0r411,744r-59,0","w":333},"]":{"d":"123,-729r161,0r-195,920r-163,0r11,-53r98,0r175,-814r-97,0","w":241},"^":{"d":"102,-238r-58,0r230,-453r52,0r230,453r-57,0r-200,-390","w":600},"_":{"d":"500,125r-500,0r0,-50r500,0r0,50","w":500},"a":{"d":"354,-189v4,-29,19,-63,18,-89v-20,25,-82,27,-114,29v-77,6,-204,10,-204,118v0,66,55,93,115,93v101,0,165,-61,185,-151xm459,-416v-2,89,-69,305,-66,348v2,27,35,21,58,19r-9,50v-49,12,-111,5,-107,-51v-1,-9,4,-24,0,-30v-65,127,-346,142,-344,-48v-5,-169,210,-160,343,-175v41,-10,62,-33,62,-101v0,-61,-61,-74,-109,-74v-80,0,-149,30,-162,116r-63,0v17,-117,107,-169,218,-169v70,0,179,24,179,115","w":519},"b":{"d":"238,-38v143,0,218,-154,218,-280v0,-96,-46,-160,-148,-160v-138,0,-211,166,-211,283v0,87,46,157,141,157xm-11,0r152,-714r63,0r-61,289r2,0v36,-62,100,-106,178,-106v131,0,196,92,196,215v0,157,-97,331,-273,331v-89,2,-153,-52,-175,-133r-25,118r-57,0","w":574},"c":{"d":"487,-355r-63,0v5,-77,-50,-123,-124,-123v-151,0,-223,146,-223,280v0,92,46,160,144,160v83,0,143,-54,170,-129r63,0v-38,118,-116,182,-241,182v-128,0,-199,-86,-199,-213v0,-161,103,-333,280,-333v112,0,197,56,193,176","w":519},"d":{"d":"216,-38v145,0,225,-163,225,-291v0,-90,-52,-149,-144,-149v-145,0,-220,160,-220,286v0,88,44,154,139,154xm591,-714r-153,714r-61,0r23,-93r-2,0v-44,68,-97,108,-188,108v-132,0,-196,-85,-196,-211v0,-158,109,-335,282,-335v83,-2,143,35,170,112r62,-295r63,0","w":574},"e":{"d":"484,-241r-404,0v-16,113,31,203,147,203v82,0,145,-53,169,-128r63,0v-34,115,-113,181,-235,181v-136,0,-210,-85,-210,-219v0,-163,102,-327,279,-327v157,-1,218,127,191,290xm88,-294r337,0v12,-110,-38,-183,-140,-184v-104,0,-175,88,-197,184","w":519},"f":{"d":"296,-516r-12,53r-101,0r-102,463r-63,0r102,-463r-90,0r12,-53r89,0v19,-99,36,-203,154,-198v22,0,44,1,65,7r-11,52v-66,-16,-123,2,-130,67r-15,72r102,0","w":259},"g":{"d":"84,-226v0,87,43,162,139,162v128,0,206,-140,206,-256v0,-92,-39,-158,-141,-158v-129,0,-204,137,-204,252xm536,-516r-98,462v-38,180,-99,260,-259,260v-105,0,-197,-44,-199,-167r63,0v1,88,71,114,145,114v160,0,180,-169,202,-257r-2,-2v-35,60,-106,95,-176,95v-125,0,-191,-91,-191,-210v0,-152,99,-310,264,-310v81,-2,152,44,171,121r22,-106r58,0"},"h":{"d":"-11,0r154,-714r63,0r-63,292r2,0v36,-61,104,-109,181,-109v90,0,156,40,156,139v-17,136,-55,262,-79,392r-63,0r72,-333v4,-16,7,-35,7,-52v0,-68,-52,-93,-108,-93v-91,0,-174,82,-202,213r-57,265r-63,0","w":537},"i":{"d":"-11,0r111,-516r63,0r-111,516r-63,0xm121,-613r22,-101r63,0r-22,101r-63,0","w":185},"j":{"d":"-28,86r128,-602r63,0r-129,604v-13,83,-78,116,-171,98r12,-52v49,13,91,-7,97,-48xm121,-613r21,-101r64,0r-22,101r-63,0","w":185},"k":{"d":"-11,0r152,-714r63,0r-96,448r2,2r302,-252r84,0r-244,199r156,317r-69,0r-137,-279r-110,92r-40,187r-63,0","w":463},"l":{"d":"-11,0r154,-714r63,0r-154,714r-63,0","w":185},"m":{"d":"-11,0r111,-516r58,0v-4,30,-19,65,-18,92v37,-60,105,-107,182,-107v75,-2,115,42,127,110v40,-63,104,-110,181,-110v123,0,160,87,136,195r-72,336r-63,0r73,-338v19,-77,-4,-140,-92,-140v-186,3,-192,306,-239,478r-63,0r72,-336v17,-71,0,-141,-81,-142v-91,0,-167,96,-193,216r-56,262r-63,0","w":833},"n":{"d":"-11,0r111,-516r58,0v-4,30,-17,67,-16,94v39,-61,107,-109,184,-109v90,0,156,40,156,139v-17,136,-55,262,-79,392r-63,0r72,-333v4,-16,7,-35,7,-52v0,-68,-52,-93,-108,-93v-91,0,-174,82,-202,213r-57,265r-63,0","w":537},"o":{"d":"302,-531v120,0,204,75,204,202v0,174,-95,344,-286,344v-133,0,-206,-86,-206,-215v0,-169,104,-331,288,-331xm232,-38v138,0,211,-158,211,-278v0,-96,-51,-162,-152,-162v-138,0,-214,151,-214,272v0,100,50,168,155,168"},"p":{"d":"327,-478v-145,0,-225,163,-225,291v0,90,52,149,144,149v145,0,220,-160,220,-286v0,-88,-44,-154,-139,-154xm-46,191r152,-707r57,0v-4,30,-18,67,-18,93v44,-68,97,-108,188,-108v132,0,196,85,196,211v0,158,-109,335,-282,335v-84,2,-148,-38,-167,-118r-63,294r-63,0","w":574},"q":{"d":"303,-478v-143,0,-218,154,-218,280v0,96,46,160,148,160v138,0,211,-166,211,-283v0,-87,-46,-157,-141,-157xm554,-516r-152,707r-63,0r61,-282r-2,0v-38,62,-102,106,-180,106v-131,0,-196,-92,-196,-215v0,-157,97,-331,273,-331v88,-2,153,52,179,118r22,-103r58,0","w":574},"r":{"d":"-11,0r111,-516r57,0r-26,119r2,0v46,-83,105,-137,221,-125r-14,63v-140,-15,-206,82,-230,189r-58,270r-63,0","w":315},"s":{"d":"-1,-168r63,0v-1,100,73,130,146,130v56,0,130,-29,130,-95v0,-67,-71,-88,-139,-114v-69,-27,-138,-58,-138,-143v0,-100,108,-141,191,-141v108,0,186,47,184,166r-63,0v5,-79,-50,-113,-121,-113v-55,0,-128,17,-128,88v0,48,51,72,109,95v71,28,168,57,168,152v0,116,-110,158,-208,158v-99,0,-200,-54,-194,-183","w":481},"t":{"d":"31,-463r12,-53r93,0r33,-156r63,0r-33,156r103,0r-10,53r-105,0r-71,331v-9,42,-18,85,26,85v25,0,49,-2,74,-6r-11,55v-73,6,-159,17,-159,-70v0,-135,54,-265,78,-395r-93,0","w":296},"u":{"d":"513,-516r-111,516r-58,0v4,-30,17,-67,16,-94v-39,61,-107,109,-184,109v-90,0,-156,-40,-156,-139v17,-136,55,-262,79,-392r63,0r-72,333v-4,16,-7,35,-7,52v0,68,52,93,108,93v91,0,174,-82,202,-213r57,-265r63,0","w":537},"v":{"d":"116,0r-81,-516r66,0r61,445r2,0r242,-445r69,0r-291,516r-68,0","w":463},"w":{"d":"90,0r-60,-516r66,0r41,440r2,0r213,-440r74,0r35,436r2,0r219,-436r67,0r-271,516r-68,0r-37,-433r-2,0r-212,433r-69,0","w":741},"x":{"d":"-58,0r246,-272r-121,-244r72,0r94,203r178,-203r76,0r-227,250r137,266r-72,0r-110,-225r-198,225r-75,0","w":463},"y":{"d":"-55,186r12,-51v66,13,114,-9,135,-53r47,-82r-95,-516r66,0r74,438r2,0r238,-438r68,0r-367,638v-34,62,-99,78,-180,64","w":463},"z":{"d":"44,-463r11,-53r388,0r-11,50r-401,413r331,0r-11,53r-409,0r11,-51r399,-412r-308,0","w":426},"{":{"d":"178,191v-83,14,-132,-39,-112,-125v13,-74,38,-153,42,-232v0,-44,-13,-76,-50,-76r11,-53v100,-8,110,-204,137,-309v23,-95,63,-137,164,-125r-11,53v-62,-1,-67,-2,-95,103r-29,141v-22,112,-93,152,-106,164v9,6,42,37,42,105v-5,82,-39,184,-47,257v0,17,3,44,39,44r26,0","w":333},"|":{"d":"85,214r0,-1000r53,0r0,1000r-53,0","w":222},"}":{"d":"131,-729v83,-14,132,39,112,125v-13,74,-38,153,-42,232v0,44,13,76,50,76r-11,53v-100,8,-110,204,-137,309v-23,95,-63,137,-164,125r11,-53v62,1,67,2,95,-103r29,-141v22,-112,93,-152,106,-164v-9,-6,-42,-37,-42,-105v5,-82,39,-184,47,-257v0,-17,-3,-44,-39,-44r-26,0","w":333},"~":{"d":"194,-311v68,-2,156,62,213,65v40,0,65,-34,88,-69r36,36v-30,42,-63,86,-125,86v-78,1,-140,-65,-217,-65v-44,0,-68,34,-84,69r-36,-36v22,-42,58,-86,125,-86","w":600},"'":{"d":"153,-471r0,-243r58,0r0,243r-58,0","w":278},"`":{"d":"67,-729r74,0r82,144r-50,0","w":185}}});

Cufon.replace('h1');

/*(function($){
	$.fn.makeAbsolute = function(ob) {
	    return this.each(function() {
			var el = $(this);
		    var pos = el.position();
		
		    el.css({
				position	: 'absolute',
		        marginLeft	: 0,
				marginTop	: 0,
		        top			: pos.top,
				left		: pos.left
			});

		    el.appendTo(ob);
	    });
	}
})(jQuery);

$(function() {
	var email	= $('#email');
	var pass	= $('#password');
	
	$("#dialog").dialog({
		bgiframe	: true,
		autoOpen	: false,
		height		: 230,
		width		: 350,
		modal		: true,
		draggable	: false,
		resizable	: false,
		buttons		: {'Login': function() {
						$.ajax({
							url			: 'login.php',
			   				data		: 'email='+email.val()+'&pass='+pass.val(),
			   				success		: function(msg) {
			    							//$('#dialog').dialog('close');
			    							location.reload();
			   				}
						});
					},
					'Cancel': function() {
						$(this).dialog('close');
					}
		}
	});
	
	$('#admin').click(function() {
		email.val('');
		pass.val('');
		
		$('#dialog').dialog('open');
	});
	
	function show_edit(divs, tag) {
      	for (var i=0; i<divs.length; i++) {
      		var new_n	= 'edit_button_'+(i+1);
				
			$._img_()
				.addClass('edit_tag_'+(i+1))
				.attr('src', 'images/icons/cms/pencil_add.png')
				.css({
					cursor	: 'pointer',
					display	: 'inline'
				}).hover(function() {
					$('.left .inner .title.bold')
						.css({
							color	: '#ff0000'
						});
				}, function() {
					$('.left .inner .title.bold')
						.css({
							color	: '#000'
						});
				})
				.appendTo(divs[i]);
				
			$('.edit_tag_'+(i+1)).makeAbsolute('#content');
      	}
    }
    
    if ($('#logged_in').size()>0) {
    	show_edit($('.edit').get());
    }
    
    $('.left .inner .title.bold').editable('http://www.example.com/save.php');
    $('.edit_tag_1').click(function() {
    	$('.left .inner .title.bold').click();
   	});
   	
   	$('.right .inner .title.bold:first').editable('http://www.example.com/save.php');
    $('.edit_tag_2').click(function() {
    	$('.right .inner .title.bold:first').click();
   	});
   	
   	$('.right .inner .title.bold:last').editable('http://www.example.com/save.php');
    $('.edit_tag_3').click(function() {
    	$('.right .inner .title.bold:last').click();
   	});
});*/

//MooTools, <http://mootools.net>, My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

var MooTools={version:"1.2.1",build:"0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf"};var Native=function(K){K=K||{};var A=K.name;var I=K.legacy;var B=K.protect;
var C=K.implement;var H=K.generics;var F=K.initialize;var G=K.afterImplement||function(){};var D=F||I;H=H!==false;D.constructor=Native;D.$family={name:"native"};
if(I&&F){D.prototype=I.prototype;}D.prototype.constructor=D;if(A){var E=A.toLowerCase();D.prototype.$family={name:E};Native.typize(D,E);}var J=function(N,L,O,M){if(!B||M||!N.prototype[L]){N.prototype[L]=O;
}if(H){Native.genericize(N,L,B);}G.call(N,L,O);return N;};D.alias=function(N,L,O){if(typeof N=="string"){if((N=this.prototype[N])){return J(this,L,N,O);
}}for(var M in N){this.alias(M,N[M],L);}return this;};D.implement=function(M,L,O){if(typeof M=="string"){return J(this,M,L,O);}for(var N in M){J(this,N,M[N],L);
}return this;};if(C){D.implement(C);}return D;};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments);
return B.prototype[C].apply(D.shift(),D);};}};Native.implement=function(D,C){for(var B=0,A=D.length;B<A;B++){D[B].implement(C);}};Native.typize=function(A,B){if(!A.type){A.type=function(C){return($type(C)===B);
};}};(function(){var A={Array:Array,Date:Date,Function:Function,Number:Number,RegExp:RegExp,String:String};for(var G in A){new Native({name:G,initialize:A[G],protect:true});
}var D={"boolean":Boolean,"native":Native,object:Object};for(var C in D){Native.typize(D[C],C);}var F={Array:["concat","indexOf","join","lastIndexOf","pop","push","reverse","shift","slice","sort","splice","toString","unshift","valueOf"],String:["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","replace","search","slice","split","substr","substring","toLowerCase","toUpperCase","valueOf"]};
for(var E in F){for(var B=F[E].length;B--;){Native.genericize(window[E],F[E][B],true);}}})();var Hash=new Native({name:"Hash",initialize:function(A){if($type(A)=="hash"){A=$unlink(A.getClean());
}for(var B in A){this[B]=A[B];}return this;}});Hash.implement({forEach:function(B,C){for(var A in this){if(this.hasOwnProperty(A)){B.call(C,this[A],A,this);
}}},getClean:function(){var B={};for(var A in this){if(this.hasOwnProperty(A)){B[A]=this[A];}}return B;},getLength:function(){var B=0;for(var A in this){if(this.hasOwnProperty(A)){B++;
}}return B;}});Hash.alias("forEach","each");Array.implement({forEach:function(C,D){for(var B=0,A=this.length;B<A;B++){C.call(D,this[B],B,this);}}});Array.alias("forEach","each");
function $A(C){if(C.item){var D=[];for(var B=0,A=C.length;B<A;B++){D[B]=C[B];}return D;}return Array.prototype.slice.call(C);}function $arguments(A){return function(){return arguments[A];
};}function $chk(A){return !!(A||A===0);}function $clear(A){clearTimeout(A);clearInterval(A);return null;}function $defined(A){return(A!=undefined);}function $each(C,B,D){var A=$type(C);
((A=="arguments"||A=="collection"||A=="array")?Array:Hash).each(C,B,D);}function $empty(){}function $extend(C,A){for(var B in (A||{})){C[B]=A[B];}return C;
}function $H(A){return new Hash(A);}function $lambda(A){return(typeof A=="function")?A:function(){return A;};}function $merge(){var E={};for(var D=0,A=arguments.length;
D<A;D++){var B=arguments[D];if($type(B)!="object"){continue;}for(var C in B){var G=B[C],F=E[C];E[C]=(F&&$type(G)=="object"&&$type(F)=="object")?$merge(F,G):$unlink(G);
}}return E;}function $pick(){for(var B=0,A=arguments.length;B<A;B++){if(arguments[B]!=undefined){return arguments[B];}}return null;}function $random(B,A){return Math.floor(Math.random()*(A-B+1)+B);
}function $splat(B){var A=$type(B);return(A)?((A!="array"&&A!="arguments")?[B]:B):[];}var $time=Date.now||function(){return +new Date;};function $try(){for(var B=0,A=arguments.length;
B<A;B++){try{return arguments[B]();}catch(C){}}return null;}function $type(A){if(A==undefined){return false;}if(A.$family){return(A.$family.name=="number"&&!isFinite(A))?false:A.$family.name;
}if(A.nodeName){switch(A.nodeType){case 1:return"element";case 3:return(/\S/).test(A.nodeValue)?"textnode":"whitespace";}}else{if(typeof A.length=="number"){if(A.callee){return"arguments";
}else{if(A.item){return"collection";}}}}return typeof A;}function $unlink(C){var B;switch($type(C)){case"object":B={};for(var E in C){B[E]=$unlink(C[E]);
}break;case"hash":B=new Hash(C);break;case"array":B=[];for(var D=0,A=C.length;D<A;D++){B[D]=$unlink(C[D]);}break;default:return C;}return B;}var Browser=$merge({Engine:{name:"unknown",version:0},Platform:{name:(window.orientation!=undefined)?"ipod":(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase()},Features:{xpath:!!(document.evaluate),air:!!(window.runtime),query:!!(document.querySelector)},Plugins:{},Engines:{presto:function(){return(!window.opera)?false:((arguments.callee.caller)?960:((document.getElementsByClassName)?950:925));
},trident:function(){return(!window.ActiveXObject)?false:((window.XMLHttpRequest)?5:4);},webkit:function(){return(navigator.taintEnabled)?false:((Browser.Features.xpath)?((Browser.Features.query)?525:420):419);
},gecko:function(){return(document.getBoxObjectFor==undefined)?false:((document.getElementsByClassName)?19:18);}}},Browser||{});Browser.Platform[Browser.Platform.name]=true;
Browser.detect=function(){for(var B in this.Engines){var A=this.Engines[B]();if(A){this.Engine={name:B,version:A};this.Engine[B]=this.Engine[B+A]=true;
break;}}return{name:B,version:A};};Browser.detect();Browser.Request=function(){return $try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject("MSXML2.XMLHTTP");
});};Browser.Features.xhr=!!(Browser.Request());Browser.Plugins.Flash=(function(){var A=($try(function(){return navigator.plugins["Shockwave Flash"].description;
},function(){return new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version");})||"0 r0").match(/\d+/g);return{version:parseInt(A[0]||0+"."+A[1]||0),build:parseInt(A[2]||0)};
})();function $exec(B){if(!B){return B;}if(window.execScript){window.execScript(B);}else{var A=document.createElement("script");A.setAttribute("type","text/javascript");
A[(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerText":"text"]=B;document.head.appendChild(A);document.head.removeChild(A);}return B;}Native.UID=1;
var $uid=(Browser.Engine.trident)?function(A){return(A.uid||(A.uid=[Native.UID++]))[0];}:function(A){return A.uid||(A.uid=Native.UID++);};var Window=new Native({name:"Window",legacy:(Browser.Engine.trident)?null:window.Window,initialize:function(A){$uid(A);
if(!A.Element){A.Element=$empty;if(Browser.Engine.webkit){A.document.createElement("iframe");}A.Element.prototype=(Browser.Engine.webkit)?window["[[DOMElement.prototype]]"]:{};
}A.document.window=A;return $extend(A,Window.Prototype);},afterImplement:function(B,A){window[B]=Window.Prototype[B]=A;}});Window.Prototype={$family:{name:"window"}};
new Window(window);var Document=new Native({name:"Document",legacy:(Browser.Engine.trident)?null:window.Document,initialize:function(A){$uid(A);A.head=A.getElementsByTagName("head")[0];
A.html=A.getElementsByTagName("html")[0];if(Browser.Engine.trident&&Browser.Engine.version<=4){$try(function(){A.execCommand("BackgroundImageCache",false,true);
});}if(Browser.Engine.trident){A.window.attachEvent("onunload",function(){A.window.detachEvent("onunload",arguments.callee);A.head=A.html=A.window=null;
});}return $extend(A,Document.Prototype);},afterImplement:function(B,A){document[B]=Document.Prototype[B]=A;}});Document.Prototype={$family:{name:"document"}};
new Document(document);Array.implement({every:function(C,D){for(var B=0,A=this.length;B<A;B++){if(!C.call(D,this[B],B,this)){return false;}}return true;
},filter:function(D,E){var C=[];for(var B=0,A=this.length;B<A;B++){if(D.call(E,this[B],B,this)){C.push(this[B]);}}return C;},clean:function(){return this.filter($defined);
},indexOf:function(C,D){var A=this.length;for(var B=(D<0)?Math.max(0,A+D):D||0;B<A;B++){if(this[B]===C){return B;}}return -1;},map:function(D,E){var C=[];
for(var B=0,A=this.length;B<A;B++){C[B]=D.call(E,this[B],B,this);}return C;},some:function(C,D){for(var B=0,A=this.length;B<A;B++){if(C.call(D,this[B],B,this)){return true;
}}return false;},associate:function(C){var D={},B=Math.min(this.length,C.length);for(var A=0;A<B;A++){D[C[A]]=this[A];}return D;},link:function(C){var A={};
for(var E=0,B=this.length;E<B;E++){for(var D in C){if(C[D](this[E])){A[D]=this[E];delete C[D];break;}}}return A;},contains:function(A,B){return this.indexOf(A,B)!=-1;
},extend:function(C){for(var B=0,A=C.length;B<A;B++){this.push(C[B]);}return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[$random(0,this.length-1)]:null;
},include:function(A){if(!this.contains(A)){this.push(A);}return this;},combine:function(C){for(var B=0,A=C.length;B<A;B++){this.include(C[B]);}return this;
},erase:function(B){for(var A=this.length;A--;A){if(this[A]===B){this.splice(A,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var D=[];
for(var B=0,A=this.length;B<A;B++){var C=$type(this[B]);if(!C){continue;}D=D.concat((C=="array"||C=="collection"||C=="arguments")?Array.flatten(this[B]):this[B]);
}return D;},hexToRgb:function(B){if(this.length!=3){return null;}var A=this.map(function(C){if(C.length==1){C+=C;}return C.toInt(16);});return(B)?A:"rgb("+A+")";
},rgbToHex:function(D){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!D){return"transparent";}var B=[];for(var A=0;A<3;A++){var C=(this[A]-0).toString(16);
B.push((C.length==1)?"0"+C:C);}return(D)?B:"#"+B.join("");}});Function.implement({extend:function(A){for(var B in A){this[B]=A[B];}return this;},create:function(B){var A=this;
B=B||{};return function(D){var C=B.arguments;C=(C!=undefined)?$splat(C):Array.slice(arguments,(B.event)?1:0);if(B.event){C=[D||window.event].extend(C);
}var E=function(){return A.apply(B.bind||null,C);};if(B.delay){return setTimeout(E,B.delay);}if(B.periodical){return setInterval(E,B.periodical);}if(B.attempt){return $try(E);
}return E();};},run:function(A,B){return this.apply(B,$splat(A));},pass:function(A,B){return this.create({bind:B,arguments:A});},bind:function(B,A){return this.create({bind:B,arguments:A});
},bindWithEvent:function(B,A){return this.create({bind:B,arguments:A,event:true});},attempt:function(A,B){return this.create({bind:B,arguments:A,attempt:true})();
},delay:function(B,C,A){return this.create({bind:C,arguments:A,delay:B})();},periodical:function(C,B,A){return this.create({bind:B,arguments:A,periodical:C})();
}});Number.implement({limit:function(B,A){return Math.min(A,Math.max(B,this));},round:function(A){A=Math.pow(10,A||0);return Math.round(this*A)/A;},times:function(B,C){for(var A=0;
A<this;A++){B.call(C,A,this);}},toFloat:function(){return parseFloat(this);},toInt:function(A){return parseInt(this,A||10);}});Number.alias("times","each");
(function(B){var A={};B.each(function(C){if(!Number[C]){A[C]=function(){return Math[C].apply(null,[this].concat($A(arguments)));};}});Number.implement(A);
})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);String.implement({test:function(A,B){return((typeof A=="string")?new RegExp(A,B):A).test(this);
},contains:function(A,B){return(B)?(B+this+B).indexOf(B+A+B)>-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim();
},camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase());
});},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");
},toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A="";
var C=this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C);
}}return C;},substitute:function(A,B){return this.replace(B||(/\\?\{([^{}]+)\}/g),function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:"";
});}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null;
},hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},combine:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C);
},this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null;
},set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this);
return this;},include:function(B,C){var A=this[B];if(A==undefined){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this));
},this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false;
}}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[];
Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(A){var B=[];
Hash.each(this,function(F,E){if(A){E=A+"["+E+"]";}var D;switch($type(F)){case"object":D=Hash.toQueryString(F,E);break;case"array":var C={};F.each(function(H,G){C[G]=H;
});D=Hash.toQueryString(C,E);break;default:D=E+"="+encodeURIComponent(F);}if(F!=undefined){B.push(D);}});return B.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"});
var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;var K=F.document;A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type;
var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;var M=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111;
if(D>0&&D<13){M="f"+D;}}M=M||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){K=(!K.compatMode||K.compatMode=="CSS1Compat")?K.html:K.body;
var I={x:A.pageX||A.clientX+K.scrollLeft,y:A.pageY||A.clientY+K.scrollTop};var C={x:(A.pageX)?A.pageX-F.pageXOffset:A.clientX,y:(A.pageY)?A.pageY-F.pageYOffset:A.clientY};
if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;}var E=(A.which==3)||(A.button==2);var L=null;if(J.match(/over|out/)){switch(J){case"mouseover":L=A.relatedTarget||A.fromElement;
break;case"mouseout":L=A.relatedTarget||A.toElement;}if(!(function(){while(L&&L.nodeType==3){L=L.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){L=false;
}}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:L,target:G,code:B,key:M,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey});
}});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault();
},stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault();
}else{this.event.returnValue=false;}return this;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(){for(var E in this){if($type(this[E])!="function"){this[E]=$unlink(this[E]);
}}this.constructor=A;if(Class.prototyping){return this;}var D=(this.initialize)?this.initialize.apply(this,arguments):this;if(this.options&&this.options.initialize){this.options.initialize.call(this);
}return D;};for(var C in Class.Mutators){if(!B[C]){continue;}B=Class.Mutators[C](B,B[C]);delete B[C];}$extend(A,this);A.constructor=Class;A.prototype=B;
return A;}});Class.Mutators={Extends:function(C,A){Class.prototyping=A.prototype;var B=new A;delete B.parent;B=Class.inherit(B,C);delete Class.prototyping;
return B;},Implements:function(A,B){$splat(B).each(function(C){Class.prototying=C;$extend(A,($type(C)=="class")?new C:C);delete Class.prototyping;});return A;
}};Class.extend({inherit:function(B,E){var A=arguments.callee.caller;for(var D in E){var C=E[D];var G=B[D];var F=$type(C);if(G&&F=="function"){if(C!=G){if(A){C.__parent=G;
B[D]=C;}else{Class.override(B,D,C);}}}else{if(F=="object"){B[D]=$merge(G,C);}else{B[D]=C;}}}if(A){B.parent=function(){return arguments.callee.caller.__parent.apply(this,arguments);
};}return B;},override:function(B,A,E){var D=Class.prototyping;if(D&&B[A]!=D[A]){D=null;}var C=function(){var F=this.parent;this.parent=D?D[A]:B[A];var G=E.apply(this,arguments);
this.parent=F;return G;};B[A]=C;}});Class.implement({implement:function(){var A=this.prototype;$each(arguments,function(B){Class.inherit(A,B);});return this;
}});var Chain=new Class({$chain:[],chain:function(){this.$chain.extend(Array.flatten(arguments));return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false;
},clearChain:function(){this.$chain.empty();return this;}});var Events=new Class({$events:{},addEvent:function(C,B,A){C=Events.removeOn(C);if(B!=$empty){this.$events[C]=this.$events[C]||[];
this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;},fireEvent:function(C,B,A){C=Events.removeOn(C);
if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();},this);return this;},removeEvent:function(B,A){B=Events.removeOn(B);
if(!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;},removeEvents:function(C){if($type(C)=="object"){for(var D in C){this.removeEvent(D,C[D]);
}return this;}if(C){C=Events.removeOn(C);}for(var D in this.$events){if(C&&C!=D){continue;}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]);
}}return this;}});Events.removeOn=function(A){return A.replace(/^on([A-Z])/,function(B,C){return C.toLowerCase();});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments));
if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;}this.addEvent(A,this.options[A]);
delete this.options[A];}return this;}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A);
if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){Element.Prototype[A]=B;if(Array[A]){return ;
}Elements.implement(A,function(){var C=[],G=true;for(var E=0,D=this.length;E<D;E++){var F=this[E][A].apply(this[E],arguments);C.push(F);if(G){G=($type(F)=="element");
}}return(G)?new Elements(C):C;});}});Element.Prototype={$family:{name:"element"}};Element.Constructors=new Hash;var IFrame=new Native({name:"IFrame",generics:false,initialize:function(){var E=Array.link(arguments,{properties:Object.type,iframe:$defined});
var C=E.properties||{};var B=$(E.iframe)||false;var D=C.onload||$empty;delete C.onload;C.id=C.name=$pick(C.id,C.name,B.id,B.name,"IFrame_"+$time());B=new Element(B||"iframe",C);
var A=function(){var F=$try(function(){return B.contentWindow.location.host;});if(F&&F==window.location.host){var G=new Window(B.contentWindow);new Document(B.contentWindow.document);
$extend(G.Element.prototype,Element.Prototype);}D.call(B.contentWindow,B.contentWindow.document);};(window.frames[C.id])?A():B.addListener("load",A);return B;
}});var Elements=new Native({initialize:function(F,B){B=$extend({ddup:true,cash:true},B);F=F||[];if(B.ddup||B.cash){var G={},E=[];for(var C=0,A=F.length;
C<A;C++){var D=$.element(F[C],!B.cash);if(B.ddup){if(G[D.uid]){continue;}G[D.uid]=true;}E.push(D);}F=E;}return(B.cash)?$extend(F,this):F;}});Elements.implement({filter:function(A,B){if(!A){return this;
}return new Elements(Array.filter(this,(typeof A=="string")?function(C){return C.match(A);}:A,B));}});Document.implement({newElement:function(A,B){if(Browser.Engine.trident&&B){["name","type","checked"].each(function(C){if(!B[C]){return ;
}A+=" "+C+'="'+B[C]+'"';if(C!="checked"){delete B[C];}});A="<"+A+">";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A);
},getDocument:function(){return this;},getWindow:function(){return this.window;}});Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B);
return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);}var F=[];var C=Array.flatten(arguments);
for(var D=0,B=C.length;D<B;D++){var E=C[D];switch($type(E)){case"element":F.push(E);break;case"string":F.extend(this.document.getElements(E,true));}}return new Elements(F);
},getDocument:function(){return this.document;},getWindow:function(){return this;}});$.string=function(C,B,A){C=A.getElementById(C);return(C)?$.element(C,B):null;
};$.element=function(A,D){$uid(A);if(!D&&!A.$family&&!(/^object|embed$/i).test(A.tagName)){var B=Element.Prototype;for(var C in B){A[C]=B[C];}}return A;
};$.object=function(B,C,A){if(B.toElement){return $.element(B.toElement(A),C);}return null;};$.textnode=$.whitespace=$.window=$.document=$arguments(0);
Native.implement([Element,Document],{getElement:function(A,B){return $(this.getElements(A,true)[0]||null,B);},getElements:function(A,D){A=A.split(",");
var C=[];var B=(A.length>1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D});
}});(function(){var H={},F={};var I={input:"checked",option:"selected",textarea:(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerHTML":"value"};
var C=function(L){return(F[L]||(F[L]={}));};var G=function(N,L){if(!N){return ;}var M=N.uid;if(Browser.Engine.trident){if(N.clearAttributes){var P=L&&N.cloneNode(false);
N.clearAttributes();if(P){N.mergeAttributes(P);}}else{if(N.removeEvents){N.removeEvents();}}if((/object/i).test(N.tagName)){for(var O in N){if(typeof N[O]=="function"){N[O]=$empty;
}}Element.dispose(N);}}if(!M){return ;}H[M]=F[M]=null;};var D=function(){Hash.each(H,G);if(Browser.Engine.trident){$A(document.getElementsByTagName("object")).each(G);
}if(window.CollectGarbage){CollectGarbage();}H=F=null;};var J=function(N,L,S,M,P,R){var O=N[S||L];var Q=[];while(O){if(O.nodeType==1&&(!M||Element.match(O,M))){if(!P){return $(O,R);
}Q.push(O);}O=O[L];}return(P)?new Elements(Q,{ddup:false,cash:!R}):null;};var E={html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident||(Browser.Engine.webkit&&Browser.Engine.version<420))?"innerText":"textContent"};
var B=["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"];var K=["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"];
Hash.extend(E,B.associate(B));Hash.extend(E,K.associate(K.map(String.toLowerCase)));var A={before:function(M,L){if(L.parentNode){L.parentNode.insertBefore(M,L);
}},after:function(M,L){if(!L.parentNode){return ;}var N=L.nextSibling;(N)?L.parentNode.insertBefore(M,N):L.parentNode.appendChild(M);},bottom:function(M,L){L.appendChild(M);
},top:function(M,L){var N=L.firstChild;(N)?L.insertBefore(M,N):L.appendChild(M);}};A.inside=A.bottom;Hash.each(A,function(L,M){M=M.capitalize();Element.implement("inject"+M,function(N){L(this,$(N,true));
return this;});Element.implement("grab"+M,function(N){L($(N,true),this);return this;});});Element.implement({set:function(O,M){switch($type(O)){case"object":for(var N in O){this.set(N,O[N]);
}break;case"string":var L=Element.Properties.get(O);(L&&L.set)?L.set.apply(this,Array.slice(arguments,1)):this.setProperty(O,M);}return this;},get:function(M){var L=Element.Properties.get(M);
return(L&&L.get)?L.get.apply(this,Array.slice(arguments,1)):this.getProperty(M);},erase:function(M){var L=Element.Properties.get(M);(L&&L.erase)?L.erase.apply(this):this.removeProperty(M);
return this;},setProperty:function(M,N){var L=E[M];if(N==undefined){return this.removeProperty(M);}if(L&&B[M]){N=!!N;}(L)?this[L]=N:this.setAttribute(M,""+N);
return this;},setProperties:function(L){for(var M in L){this.setProperty(M,L[M]);}return this;},getProperty:function(M){var L=E[M];var N=(L)?this[L]:this.getAttribute(M,2);
return(B[M])?!!N:(L)?N:N||null;},getProperties:function(){var L=$A(arguments);return L.map(this.getProperty,this).associate(L);},removeProperty:function(M){var L=E[M];
(L)?this[L]=(L&&B[M])?false:"":this.removeAttribute(M);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this;
},hasClass:function(L){return this.className.contains(L," ");},addClass:function(L){if(!this.hasClass(L)){this.className=(this.className+" "+L).clean();
}return this;},removeClass:function(L){this.className=this.className.replace(new RegExp("(^|\\s)"+L+"(?:\\s|$)"),"$1");return this;},toggleClass:function(L){return this.hasClass(L)?this.removeClass(L):this.addClass(L);
},adopt:function(){Array.flatten(arguments).each(function(L){L=$(L,true);if(L){this.appendChild(L);}},this);return this;},appendText:function(M,L){return this.grab(this.getDocument().newTextNode(M),L);
},grab:function(M,L){A[L||"bottom"]($(M,true),this);return this;},inject:function(M,L){A[L||"bottom"](this,$(M,true));return this;},replaces:function(L){L=$(L,true);
L.parentNode.replaceChild(this,L);return this;},wraps:function(M,L){M=$(M,true);return this.replaces(M).grab(M,L);},getPrevious:function(L,M){return J(this,"previousSibling",null,L,false,M);
},getAllPrevious:function(L,M){return J(this,"previousSibling",null,L,true,M);},getNext:function(L,M){return J(this,"nextSibling",null,L,false,M);},getAllNext:function(L,M){return J(this,"nextSibling",null,L,true,M);
},getFirst:function(L,M){return J(this,"nextSibling","firstChild",L,false,M);},getLast:function(L,M){return J(this,"previousSibling","lastChild",L,false,M);
},getParent:function(L,M){return J(this,"parentNode",null,L,false,M);},getParents:function(L,M){return J(this,"parentNode",null,L,true,M);},getChildren:function(L,M){return J(this,"nextSibling","firstChild",L,true,M);
},getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;},getElementById:function(O,N){var M=this.ownerDocument.getElementById(O);
if(!M){return null;}for(var L=M.parentNode;L!=this;L=L.parentNode){if(!L){return null;}}return $.element(M,N);},getSelected:function(){return new Elements($A(this.options).filter(function(L){return L.selected;
}));},getComputedStyle:function(M){if(this.currentStyle){return this.currentStyle[M.camelCase()];}var L=this.getDocument().defaultView.getComputedStyle(this,null);
return(L)?L.getPropertyValue([M.hyphenate()]):null;},toQueryString:function(){var L=[];this.getElements("input, select, textarea",true).each(function(M){if(!M.name||M.disabled){return ;
}var N=(M.tagName.toLowerCase()=="select")?Element.getSelected(M).map(function(O){return O.value;}):((M.type=="radio"||M.type=="checkbox")&&!M.checked)?null:M.value;
$splat(N).each(function(O){if(typeof O!="undefined"){L.push(M.name+"="+encodeURIComponent(O));}});});return L.join("&");},clone:function(O,L){O=O!==false;
var R=this.cloneNode(O);var N=function(V,U){if(!L){V.removeAttribute("id");}if(Browser.Engine.trident){V.clearAttributes();V.mergeAttributes(U);V.removeAttribute("uid");
if(V.options){var W=V.options,S=U.options;for(var T=W.length;T--;){W[T].selected=S[T].selected;}}}var X=I[U.tagName.toLowerCase()];if(X&&U[X]){V[X]=U[X];
}};if(O){var P=R.getElementsByTagName("*"),Q=this.getElementsByTagName("*");for(var M=P.length;M--;){N(P[M],Q[M]);}}N(R,this);return $(R);},destroy:function(){Element.empty(this);
Element.dispose(this);G(this,true);return null;},empty:function(){$A(this.childNodes).each(function(L){Element.destroy(L);});return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this;
},hasChild:function(L){L=$(L,true);if(!L){return false;}if(Browser.Engine.webkit&&Browser.Engine.version<420){return $A(this.getElementsByTagName(L.tagName)).contains(L);
}return(this.contains)?(this!=L&&this.contains(L)):!!(this.compareDocumentPosition(L)&16);},match:function(L){return(!L||(L==this)||(Element.get(this,"tag")==L));
}});Native.implement([Element,Window,Document],{addListener:function(O,N){if(O=="unload"){var L=N,M=this;N=function(){M.removeListener("unload",N);L();
};}else{H[this.uid]=this;}if(this.addEventListener){this.addEventListener(O,N,false);}else{this.attachEvent("on"+O,N);}return this;},removeListener:function(M,L){if(this.removeEventListener){this.removeEventListener(M,L,false);
}else{this.detachEvent("on"+M,L);}return this;},retrieve:function(M,L){var O=C(this.uid),N=O[M];if(L!=undefined&&N==undefined){N=O[M]=L;}return $pick(N);
},store:function(M,L){var N=C(this.uid);N[M]=L;return this;},eliminate:function(L){var M=C(this.uid);delete M[L];return this;}});window.addListener("unload",D);
})();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;},get:function(){return this.style.cssText;},erase:function(){this.style.cssText="";
}};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};Element.Properties.html=(function(){var C=document.createElement("div");
var A={table:[1,"<table>","</table>"],select:[1,"<select>","</select>"],tbody:[2,"<table><tbody>","</tbody></table>"],tr:[3,"<table><tbody><tr>","</tr></tbody></table>"]};
A.thead=A.tfoot=A.tbody;var B={set:function(){var E=Array.flatten(arguments).join("");var F=Browser.Engine.trident&&A[this.get("tag")];if(F){var G=C;G.innerHTML=F[1]+E+F[2];
for(var D=F[0];D--;){G=G.firstChild;}this.empty().adopt(G.childNodes);}else{this.innerHTML=E;}}};B.erase=B.set;return B;})();if(Browser.Engine.webkit&&Browser.Engine.version<420){Element.Properties.text={get:function(){if(this.innerText){return this.innerText;
}var A=this.ownerDocument.newElement("div",{html:this.innerHTML}).inject(this.ownerDocument.body);var B=A.innerText;A.destroy();return B;}};}Element.Properties.events={set:function(A){this.addEvents(A);
}};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this;
}H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J);
}return true;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F];if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow());
if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(C,B){var A=this.retrieve("events");if(!A||!A[C]){return this;
}var F=A[C].keys.indexOf(B);if(F==-1){return this;}A[C].keys.splice(F,1);var E=A[C].values.splice(F,1)[0];var D=Element.Events.get(C);if(D){if(D.onRemove){D.onRemove.call(this,B);
}C=D.base||C;}return(Element.NativeEvents[C])?this.removeListener(C,E):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;
},removeEvents:function(A){if($type(A)=="object"){for(var C in A){this.removeEvent(C,A[C]);}return this;}var B=this.retrieve("events");if(!B){return this;
}if(!A){for(var C in B){this.removeEvents(C);}this.eliminate("events");}else{if(B[A]){while(B[A].keys[0]){this.removeEvent(A,B[A].keys[0]);}B[A]=null;}}return this;
},fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})();
},this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E);
},this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};
(function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C));
};Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}});
})();Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden";
}}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")";
}this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true);
},getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat";
}B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E;
}).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity");
case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue;
}for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/);
if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0;
B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px";
}if((Browser.Engine.presto)&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]);
}return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"});
Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles;
var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color";
F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(H,I){if(B(this)){this.getWindow().scrollTo(H,I);
}else{this.scrollLeft=H;this.scrollTop=I;}return this;},getSize:function(){if(B(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight};
},getScrollSize:function(){if(B(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(B(this)){return this.getWindow().getScroll();
}return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var I=this,H={x:0,y:0};while(I&&!B(I)){H.x+=I.scrollLeft;H.y+=I.scrollTop;I=I.parentNode;
}return H;},getOffsetParent:function(){var H=this;if(B(H)){return null;}if(!Browser.Engine.trident){return H.offsetParent;}while((H=H.parentNode)&&!B(H)){if(D(H,"position")!="static"){return H;
}}return null;},getOffsets:function(){if(Browser.Engine.trident){var L=this.getBoundingClientRect(),J=this.getDocument().documentElement;return{x:L.left+J.scrollLeft-J.clientLeft,y:L.top+J.scrollTop-J.clientTop};
}var I=this,H={x:0,y:0};if(B(this)){return H;}while(I&&!B(I)){H.x+=I.offsetLeft;H.y+=I.offsetTop;if(Browser.Engine.gecko){if(!F(I)){H.x+=C(I);H.y+=G(I);
}var K=I.parentNode;if(K&&D(K,"overflow")!="visible"){H.x+=C(K);H.y+=G(K);}}else{if(I!=this&&Browser.Engine.webkit){H.x+=C(I);H.y+=G(I);}}I=I.offsetParent;
}if(Browser.Engine.gecko&&!F(this)){H.x-=C(this);H.y-=G(this);}return H;},getPosition:function(K){if(B(this)){return{x:0,y:0};}var L=this.getOffsets(),I=this.getScrolls();
var H={x:L.x-I.x,y:L.y-I.y};var J=(K&&(K=$(K)))?K.getPosition():{x:0,y:0};return{x:H.x-J.x,y:H.y-J.y};},getCoordinates:function(J){if(B(this)){return this.getWindow().getCoordinates();
}var H=this.getPosition(J),I=this.getSize();var K={left:H.x,top:H.y,width:I.x,height:I.y};K.right=K.left+K.width;K.bottom=K.top+K.height;return K;},computePosition:function(H){return{left:H.x-E(this,"margin-left"),top:H.y-E(this,"margin-top")};
},position:function(H){return this.setStyles(this.computePosition(H));}});Native.implement([Document,Window],{getSize:function(){var I=this.getWindow();
if(Browser.Engine.presto||Browser.Engine.webkit){return{x:I.innerWidth,y:I.innerHeight};}var H=A(this);return{x:H.clientWidth,y:H.clientHeight};},getScroll:function(){var I=this.getWindow();
var H=A(this);return{x:I.pageXOffset||H.scrollLeft,y:I.pageYOffset||H.scrollTop};},getScrollSize:function(){var I=A(this);var H=this.getSize();return{x:Math.max(I.scrollWidth,H.x),y:Math.max(I.scrollHeight,H.y)};
},getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var H=this.getSize();return{top:0,left:0,bottom:H.y,right:H.x,height:H.y,width:H.x};
}});var D=Element.getComputedStyle;function E(H,I){return D(H,I).toInt()||0;}function F(H){return D(H,"-moz-box-sizing")=="border-box";}function G(H){return E(H,"border-top-width");
}function C(H){return E(H,"border-left-width");}function B(H){return(/^(?:body|html)$/i).test(H.tagName);}function A(H){var I=H.getDocument();return(!I.compatMode||I.compatMode=="CSS1Compat")?I.html:I.body;
}})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y;
},getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x;
},getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(",");
var C,E={};for(var D=0,B=H.length;D<B;D++){var A=H[D],F=Selectors.Utils.search(this,A,E);if(D!=0&&F.item){F=$A(F);}C=(D==0)?F:(C.item)?$A(C).concat(F):C.concat(F);
}return new Elements(C,{ddup:(H.length>1),cash:!G});}});Element.implement({match:function(B){if(!B||(B==this)){return true;}var D=Selectors.Utils.parseTagAndID(B);
var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true;
}});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)};
Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F];
}var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0;
if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"};
break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"};
break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E];
}var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[5],C=D[6],J=D[7];if(I){H.classes.push(I);
}else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B});
}}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null;
}return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false];
},filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length;
D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D];
if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=(B.getElementById)?B.getElementById(D,true):Element.getElementById(B,D,true);
return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(I,H,N){var B=[];var C=H.trim().replace(Selectors.RegExps.splitter,function(Y,X,W){B.push(X);
return":)"+W;}).split(":)");var J,E,U;for(var T=0,P=C.length;T<P;T++){var S=C[T];if(T==0&&Selectors.RegExps.quick.test(S)){J=I.getElementsByTagName(S);
continue;}var A=B[T-1];var K=Selectors.Utils.parseTagAndID(S);var V=K[0],L=K[1];if(T==0){J=Selectors.Utils.getByTagAndID(I,V,L);}else{var D={},G=[];for(var R=0,Q=J.length;
R<Q;R++){G=Selectors.Getters[A](G,J[R],V,L,D);}J=G;}var F=Selectors.Utils.parseSelector(S);if(F){E=[];for(var O=0,M=J.length;O<M;O++){U=J[O];if(Selectors.Utils.filter(U,F,N)){E.push(U);
}}J=E;}}return J;}};Selectors.Getters={" ":function(H,G,I,A,E){var D=Selectors.Utils.getByTagAndID(G,I,A);for(var C=0,B=D.length;C<B;C++){var F=D[C];if(Selectors.Utils.chk(F,E)){H.push(F);
}}return H;},">":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;E<D;E++){var B=C[E];if(B.parentNode==G&&Selectors.Utils.chk(B,F)){H.push(B);
}}return H;},"+":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(Selectors.Utils.chk(B,D)&&Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}break;}}return C;},"~":function(C,B,A,E,D){while((B=B.nextSibling)){if(B.nodeType==1){if(!Selectors.Utils.chk(B,D)){break;}if(Selectors.Filters.byTag(B,A)&&Selectors.Filters.byID(B,E)){C.push(B);
}}}return C;}};Selectors.Filters={byTag:function(B,A){return(A=="*"||(B.tagName&&B.tagName.toLowerCase()==A));},byID:function(A,B){return(!B||(A.id&&A.id==B));
},byClass:function(B,A){return(B.className&&B.className.contains(A," "));},byPseudo:function(A,D,C,B){return D.call(A,C,B);},byAttribute:function(C,D,B,E){var A=Element.prototype.getProperty.call(C,D);
if(!A){return(B=="!=");}if(!B||E==undefined){return true;}switch(B){case"=":return(A==E);case"*=":return(A.contains(E));case"^=":return(A.substr(0,E.length)==E);
case"$=":return(A.substr(A.length-E.length)==E);case"!=":return(A!=E);case"~=":return A.contains(E," ");case"|=":return A.contains(E,"-");}return false;
}};Selectors.Pseudo=new Hash({checked:function(){return this.checked;},empty:function(){return !(this.innerText||this.textContent||"").length;},not:function(A){return !Element.match(this,A);
},contains:function(A){return(this.innerText||this.textContent||"").contains(A);},"first-child":function(){return Selectors.Pseudo.index.call(this,0);},"last-child":function(){var A=this;
while((A=A.nextSibling)){if(A.nodeType==1){return false;}}return true;},"only-child":function(){var B=this;while((B=B.previousSibling)){if(B.nodeType==1){return false;
}}var A=this;while((A=A.nextSibling)){if(A.nodeType==1){return false;}}return true;},"nth-child":function(G,E){G=(G==undefined)?"n":G;var C=Selectors.Utils.parseNthArgument(G);
if(C.special!="n"){return Selectors.Pseudo[C.special].call(this,C.a,E);}var F=0;E.positions=E.positions||{};var D=$uid(this);if(!E.positions[D]){var B=this;
while((B=B.previousSibling)){if(B.nodeType!=1){continue;}F++;var A=E.positions[$uid(B)];if(A!=undefined){F=A+F;break;}}E.positions[D]=F;}return(E.positions[D]%C.a==C.b);
},index:function(A){var B=this,C=0;while((B=B.previousSibling)){if(B.nodeType==1&&++C>A){return false;}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A);
},odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);}});Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this);
}}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;window.fireEvent("domready");document.fireEvent("domready");};if(Browser.Engine.trident){var A=document.createElement("div");
(function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();}))?B():arguments.callee.delay(50);})();
}else{if(Browser.Engine.webkit&&Browser.Engine.version<525){(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50);
})();}else{window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}}})();var JSON=new Hash({$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16);
},encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]";
case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);}});return"{"+A+"}";case"number":case"boolean":return String(B);
case false:return"null";}return null;},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null;
}return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B;
this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path;
}if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure";
}this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)");
return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C);
};Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object;
},initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={};
var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments);
};})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";
E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J='<object id="'+B+'"';for(var I in H){J+=" "+I+'="'+H[I]+'"';}J+=">";for(var C in E){if(E[C]){J+='<param name="'+C+'" value="'+E[C]+'" />';
}}J+="</object>";this.object=((A)?A.empty():new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A);
return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments));
}});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction('<invoke name="'+fn+'" returntype="javascript">'+__flash__argumentsToXML(arguments,2)+"</invoke>");
return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore"},initialize:function(A){this.subject=this.subject||this;
this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();var B=this.options.wait;if(B===false){this.options.link="cancel";
}},getTransition:function(){return function(A){return -(Math.cos(Math.PI*A)-1)/2;};},step:function(){var A=$time();if(A<this.time+this.options.duration){var B=this.transition((A-this.time)/this.options.duration);
this.set(this.compute(this.from,this.to,B));}else{this.set(this.compute(this.from,this.to,1));this.complete();}},set:function(A){return A;},compute:function(C,B,A){return Fx.compute(C,B,A);
},check:function(A){if(!this.timer){return true;}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));
return false;}return false;},start:function(B,A){if(!this.check(arguments.callee,B,A)){return this;}this.from=B;this.to=A;this.time=0;this.transition=this.getTransition();
this.startTimer();this.onStart();return this;},complete:function(){if(this.stopTimer()){this.onComplete();}return this;},cancel:function(){if(this.stopTimer()){this.onCancel();
}return this;},onStart:function(){this.fireEvent("start",this.subject);},onComplete:function(){this.fireEvent("complete",this.subject);if(!this.callChain()){this.fireEvent("chainComplete",this.subject);
}},onCancel:function(){this.fireEvent("cancel",this.subject).clearChain();},pause:function(){this.stopTimer();return this;},resume:function(){this.startTimer();
return this;},stopTimer:function(){if(!this.timer){return false;}this.time=$time()-this.time;this.timer=$clear(this.timer);return true;},startTimer:function(){if(this.timer){return false;
}this.time=$time()-this.time;this.timer=this.step.periodical(Math.round(1000/this.options.fps),this);return true;}});Fx.compute=function(C,B,A){return(B-C)*A+C;
};Fx.Durations={"short":250,normal:500,"long":1000};Fx.CSS=new Class({Extends:Fx,prepare:function(D,E,B){B=$splat(B);var C=B[1];if(!$chk(C)){B[1]=B[0];
B[0]=D.getStyle(E);}var A=B.map(this.parse);return{from:A[0],to:A[1]};},parse:function(A){A=$lambda(A)();A=(typeof A=="string")?A.split(" "):$splat(A);
return A.map(function(C){C=String(C);var B=false;Fx.CSS.Parsers.each(function(F,E){if(B){return ;}var D=F.parse(C);if($chk(D)){B={value:D,parser:F};}});
B=B||{value:C,parser:Fx.CSS.Parsers.String};return B;});},compute:function(D,C,B){var A=[];(Math.min(D.length,C.length)).times(function(E){A.push({value:D[E].parser.compute(D[E].value,C[E].value,B),parser:D[E].parser});
});A.$family={name:"fx:css:value"};return A;},serve:function(C,B){if($type(C)!="fx:css:value"){C=this.parse(C);}var A=[];C.each(function(D){A=A.concat(D.parser.serve(D.value,B));
});return A;},render:function(A,D,C,B){A.setStyle(D,this.serve(C,B));},search:function(A){if(Fx.CSS.Cache[A]){return Fx.CSS.Cache[A];}var B={};Array.each(document.styleSheets,function(E,D){var C=E.href;
if(C&&C.contains("://")&&!C.contains(document.domain)){return ;}var F=E.rules||E.cssRules;Array.each(F,function(I,G){if(!I.style){return ;}var H=(I.selectorText)?I.selectorText.replace(/^\w+/,function(J){return J.toLowerCase();
}):null;if(!H||!H.test("^"+A+"$")){return ;}Element.Styles.each(function(K,J){if(!I.style[J]||Element.ShortStyles[J]){return ;}K=String(I.style[J]);B[J]=(K.test(/^rgb/))?K.rgbToHex():K;
});});});return Fx.CSS.Cache[A]=B;}});Fx.CSS.Cache={};Fx.CSS.Parsers=new Hash({Color:{parse:function(A){if(A.match(/^#[0-9a-f]{3,6}$/i)){return A.hexToRgb(true);
}return((A=A.match(/(\d+),\s*(\d+),\s*(\d+)/)))?[A[1],A[2],A[3]]:false;},compute:function(C,B,A){return C.map(function(E,D){return Math.round(Fx.compute(C[D],B[D],A));
});},serve:function(A){return A.map(Number);}},Number:{parse:parseFloat,compute:Fx.compute,serve:function(B,A){return(A)?B+A:B;}},String:{parse:$lambda(false),compute:$arguments(1),serve:$arguments(0)}});
Fx.Tween=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(B,A){if(arguments.length==1){A=B;
B=this.property||this.options.property;}this.render(this.element,B,A,this.options.unit);return this;},start:function(C,E,D){if(!this.check(arguments.callee,C,E,D)){return this;
}var B=Array.flatten(arguments);this.property=this.options.property||B.shift();var A=this.prepare(this.element,this.property,B);return this.parent(A.from,A.to);
}});Element.Properties.tween={set:function(A){var B=this.retrieve("tween");if(B){B.cancel();}return this.eliminate("tween").store("tween:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("tween")){if(A||!this.retrieve("tween:options")){this.set("tween",A);}this.store("tween",new Fx.Tween(this,this.retrieve("tween:options")));
}return this.retrieve("tween");}};Element.implement({tween:function(A,C,B){this.get("tween").start(arguments);return this;},fade:function(C){var E=this.get("tween"),D="opacity",A;
C=$pick(C,"toggle");switch(C){case"in":E.start(D,1);break;case"out":E.start(D,0);break;case"show":E.set(D,1);break;case"hide":E.set(D,0);break;case"toggle":var B=this.retrieve("fade:flag",this.get("opacity")==1);
E.start(D,(B)?0:1);this.store("fade:flag",!B);A=true;break;default:E.start(D,arguments);}if(!A){this.eliminate("fade:flag");}return this;},highlight:function(C,A){if(!A){A=this.retrieve("highlight:original",this.getStyle("background-color"));
A=(A=="transparent")?"#fff":A;}var B=this.get("tween");B.start("background-color",C||"#ffff88",A).chain(function(){this.setStyle("background-color",this.retrieve("highlight:original"));
B.callChain();}.bind(this));return this;}});Fx.Morph=new Class({Extends:Fx.CSS,initialize:function(B,A){this.element=this.subject=$(B);this.parent(A);},set:function(A){if(typeof A=="string"){A=this.search(A);
}for(var B in A){this.render(this.element,B,A[B],this.options.unit);}return this;},compute:function(E,D,C){var A={};for(var B in E){A[B]=this.parent(E[B],D[B],C);
}return A;},start:function(B){if(!this.check(arguments.callee,B)){return this;}if(typeof B=="string"){B=this.search(B);}var E={},D={};for(var C in B){var A=this.prepare(this.element,C,B[C]);
E[C]=A.from;D[C]=A.to;}return this.parent(E,D);}});Element.Properties.morph={set:function(A){var B=this.retrieve("morph");if(B){B.cancel();}return this.eliminate("morph").store("morph:options",$extend({link:"cancel"},A));
},get:function(A){if(A||!this.retrieve("morph")){if(A||!this.retrieve("morph:options")){this.set("morph",A);}this.store("morph",new Fx.Morph(this,this.retrieve("morph:options")));
}return this.retrieve("morph");}};Element.implement({morph:function(A){this.get("morph").start(A);return this;}});Fx.implement({getTransition:function(){var A=this.options.transition||Fx.Transitions.Sine.easeInOut;
if(typeof A=="string"){var B=A.split(":");A=Fx.Transitions;A=A[B[0]]||A[B[0].capitalize()];if(B[1]){A=A["ease"+B[1].capitalize()+(B[2]?B[2].capitalize():"")];
}}return A;}});Fx.Transition=function(B,A){A=$splat(A);return $extend(B,{easeIn:function(C){return B(C,A);},easeOut:function(C){return 1-B(1-C,A);},easeInOut:function(C){return(C<=0.5)?B(2*C,A)/2:(2-B(2*(1-C),A))/2;
}});};Fx.Transitions=new Hash({linear:$arguments(0)});Fx.Transitions.extend=function(A){for(var B in A){Fx.Transitions[B]=new Fx.Transition(A[B]);}};Fx.Transitions.extend({Pow:function(B,A){return Math.pow(B,A[0]||6);
},Expo:function(A){return Math.pow(2,8*(A-1));},Circ:function(A){return 1-Math.sin(Math.acos(A));},Sine:function(A){return 1-Math.sin((1-A)*Math.PI/2);
},Back:function(B,A){A=A[0]||1.618;return Math.pow(B,2)*((A+1)*B-A);},Bounce:function(D){var C;for(var B=0,A=1;1;B+=A,A/=2){if(D>=(7-4*B)/11){C=A*A-Math.pow((11-6*B-11*D)/4,2);
break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]);
});});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request();
this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ;
}this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML};
this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300));
},processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts);
},success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain();
},failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B);
return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(A){if(!this.running){return true;
}switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));return false;}return false;
},send:function(I){if(!this.check(arguments.callee,I)){return this;}this.running=true;var G=$type(I);if(G=="string"||G=="element"){I={data:I};}var D=this.options;
I=$extend({data:D.data,url:D.url,method:D.method},I);var E=I.data,B=I.url,A=I.method;switch($type(E)){case"element":E=$(E).toQueryString();break;case"object":case"hash":E=Hash.toQueryString(E);
}if(this.options.format){var H="format="+this.options.format;E=(E)?H+"&"+E:H;}if(this.options.emulation&&["put","delete"].contains(A)){var F="_method="+A;
E=(E)?F+"&"+E:F;A="post";}if(this.options.urlEncoded&&A=="post"){var C=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+C);
}if(E&&A=="get"){B=B+(B.contains("?")?"&":"?")+E;E=null;}this.xhr.open(A.toUpperCase(),B,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this);
this.headers.each(function(K,J){try{this.xhr.setRequestHeader(J,K);}catch(L){this.fireEvent("exception",[J,K]);}},this);this.fireEvent("request");this.xhr.send(E);
if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty;
this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var A={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined});
return this.send($extend(C,{method:B.toLowerCase()}));};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send");
if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A));
},get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options")));
}return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D="<root>"+C+"</root>",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM");
G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length;
F<E;F++){var H=Element.clone(D.childNodes[F],true,true);if(H){A.grab(H);}}return A;})||A.set("html",C);},success:function(D){var C=this.options,B=this.response;
B.html=D.stripScripts(function(E){B.javascript=E;});var A=this.processHTML(B.html);B.tree=A.childNodes;B.elements=A.getElements("*");if(C.filter){B.tree=B.elements.filter(C.filter);
}if(C.update){$(C.update).empty().set("html",B.html);}if(C.evalScripts){$exec(B.javascript);}this.onSuccess(B.tree,B.elements,B.html,B.javascript);}});
Element.Properties.load={set:function(A){var B=this.retrieve("load");if(B){B.cancel();}return this.eliminate("load").store("load:options",$extend({data:this,link:"cancel",update:this,method:"get"},A));
},get:function(A){if(A||!this.retrieve("load")){if(A||!this.retrieve("load:options")){this.set("load",A);}this.store("load",new Request.HTML(this.retrieve("load:options")));
}return this.retrieve("load");}};Element.implement({load:function(){this.get("load").send(Array.link(arguments,{data:Object.type,url:String.type}));return this;
}});Request.JSON=new Class({Extends:Request,options:{secure:true},initialize:function(A){this.parent(A);this.headers.extend({Accept:"application/json","X-Request":"JSON"});
},success:function(A){this.response.json=JSON.decode(A,this.options.secure);this.onSuccess(this.response.json,A);}});

//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

/*
Script: Fx.Slide.js
	Effect to slide an element in and out of view.

License:
	MIT-style license.
*/

Fx.Slide = new Class({

	Extends: Fx,

	options: {
		mode: 'vertical'
	},

	initialize: function(element, options){
		this.addEvent('complete', function(){
			this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
			if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);
		}, true);
		this.element = this.subject = $(element);
		this.parent(options);
		var wrapper = this.element.retrieve('wrapper');
		this.wrapper = wrapper || new Element('div', {
			styles: $extend(this.element.getStyles('margin', 'position'), {'overflow': 'hidden'})
		}).wraps(this.element);
		this.element.store('wrapper', this.wrapper).setStyle('margin', 0);
		this.now = [];
		this.open = true;
	},

	vertical: function(){
		this.margin = 'margin-top';
		this.layout = 'height';
		this.offset = this.element.offsetHeight;
	},

	horizontal: function(){
		this.margin = 'margin-left';
		this.layout = 'width';
		this.offset = this.element.offsetWidth;
	},

	set: function(now){
		this.element.setStyle(this.margin, now[0]);
		this.wrapper.setStyle(this.layout, now[1]);
		return this;
	},

	compute: function(from, to, delta){
		var now = [];
		var x = 2;
		x.times(function(i){
			now[i] = Fx.compute(from[i], to[i], delta);
		});
		return now;
	},

	start: function(how, mode){
		if (!this.check(arguments.callee, how, mode)) return this;
		this[mode || this.options.mode]();
		var margin = this.element.getStyle(this.margin).toInt();
		var layout = this.wrapper.getStyle(this.layout).toInt();
		var caseIn = [[margin, layout], [0, this.offset]];
		var caseOut = [[margin, layout], [-this.offset, 0]];
		var start;
		switch (how){
			case 'in': start = caseIn; break;
			case 'out': start = caseOut; break;
			case 'toggle': start = (this.wrapper['offset' + this.layout.capitalize()] == 0) ? caseIn : caseOut;
		}
		return this.parent(start[0], start[1]);
	},

	slideIn: function(mode){
		return this.start('in', mode);
	},

	slideOut: function(mode){
		return this.start('out', mode);
	},

	hide: function(mode){
		this[mode || this.options.mode]();
		this.open = false;
		return this.set([-this.offset, 0]);
	},

	show: function(mode){
		this[mode || this.options.mode]();
		this.open = true;
		return this.set([0, this.offset]);
	},

	toggle: function(mode){
		return this.start('toggle', mode);
	}

});

Element.Properties.slide = {

	set: function(options){
		var slide = this.retrieve('slide');
		if (slide) slide.cancel();
		return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
	},
	
	get: function(options){
		if (options || !this.retrieve('slide')){
			if (options || !this.retrieve('slide:options')) this.set('slide', options);
			this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
		}
		return this.retrieve('slide');
	}

};

Element.implement({

	slide: function(how, mode){
		how = how || 'toggle';
		var slide = this.get('slide'), toggle;
		switch (how){
			case 'hide': slide.hide(mode); break;
			case 'show': slide.show(mode); break;
			case 'toggle':
				var flag = this.retrieve('slide:flag', slide.open);
				slide[(flag) ? 'slideOut' : 'slideIn'](mode);
				this.store('slide:flag', !flag);
				toggle = true;
			break;
			default: slide.start(how, mode);
		}
		if (!toggle) this.eliminate('slide:flag');
		return this;
	}

});


/*
Script: Fx.Scroll.js
	Effect to smoothly scroll any element, including the window.

License:
	MIT-style license.
*/

Fx.Scroll = new Class({

	Extends: Fx,

	options: {
		offset: {'x': 0, 'y': 0},
		wheelStops: true
	},

	initialize: function(element, options){
		this.element = this.subject = $(element);
		this.parent(options);
		var cancel = this.cancel.bind(this, false);

		if ($type(this.element) != 'element') this.element = $(this.element.getDocument().body);

		var stopper = this.element;

		if (this.options.wheelStops){
			this.addEvent('start', function(){
				stopper.addEvent('mousewheel', cancel);
			}, true);
			this.addEvent('complete', function(){
				stopper.removeEvent('mousewheel', cancel);
			}, true);
		}
	},

	set: function(){
		var now = Array.flatten(arguments);
		this.element.scrollTo(now[0], now[1]);
	},

	compute: function(from, to, delta){
		var now = [];
		var x = 2;
		x.times(function(i){
			now.push(Fx.compute(from[i], to[i], delta));
		});
		return now;
	},

	start: function(x, y){
		if (!this.check(arguments.callee, x, y)) return this;
		var offsetSize = this.element.getSize(), scrollSize = this.element.getScrollSize();
		var scroll = this.element.getScroll(), values = {x: x, y: y};
		for (var z in values){
			var max = scrollSize[z] - offsetSize[z];
			if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z].limit(0, max) : max;
			else values[z] = scroll[z];
			values[z] += this.options.offset[z];
		}
		return this.parent([scroll.x, scroll.y], [values.x, values.y]);
	},

	toTop: function(){
		return this.start(false, 0);
	},

	toLeft: function(){
		return this.start(0, false);
	},

	toRight: function(){
		return this.start('right', false);
	},

	toBottom: function(){
		return this.start(false, 'bottom');
	},

	toElement: function(el){
		var position = $(el).getPosition(this.element);
		return this.start(position.x, position.y);
	}

});


/*
Script: Fx.Elements.js
	Effect to change any number of CSS properties of any number of Elements.

License:
	MIT-style license.
*/

Fx.Elements = new Class({

	Extends: Fx.CSS,

	initialize: function(elements, options){
		this.elements = this.subject = $$(elements);
		this.parent(options);
	},

	compute: function(from, to, delta){
		var now = {};
		for (var i in from){
			var iFrom = from[i], iTo = to[i], iNow = now[i] = {};
			for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);
		}
		return now;
	},

	set: function(now){
		for (var i in now){
			var iNow = now[i];
			for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit);
		}
		return this;
	},

	start: function(obj){
		if (!this.check(arguments.callee, obj)) return this;
		var from = {}, to = {};
		for (var i in obj){
			var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {};
			for (var p in iProps){
				var parsed = this.prepare(this.elements[i], p, iProps[p]);
				iFrom[p] = parsed.from;
				iTo[p] = parsed.to;
			}
		}
		return this.parent(from, to);
	}

});

/*
Script: Drag.js
	The base Drag Class. Can be used to drag and resize Elements using mouse events.

License:
	MIT-style license.
*/

var Drag = new Class({

	Implements: [Events, Options],

	options: {/*
		onBeforeStart: $empty,
		onStart: $empty,
		onDrag: $empty,
		onCancel: $empty,
		onComplete: $empty,*/
		snap: 6,
		unit: 'px',
		grid: false,
		style: true,
		limit: false,
		handle: false,
		invert: false,
		preventDefault: false,
		modifiers: {x: 'left', y: 'top'}
	},

	initialize: function(){
		var params = Array.link(arguments, {'options': Object.type, 'element': $defined});
		this.element = $(params.element);
		this.document = this.element.getDocument();
		this.setOptions(params.options || {});
		var htype = $type(this.options.handle);
		this.handles = (htype == 'array' || htype == 'collection') ? $$(this.options.handle) : $(this.options.handle) || this.element;
		this.mouse = {'now': {}, 'pos': {}};
		this.value = {'start': {}, 'now': {}};
		
		this.selection = (Browser.Engine.trident) ? 'selectstart' : 'mousedown';
		
		this.bound = {
			start: this.start.bind(this),
			check: this.check.bind(this),
			drag: this.drag.bind(this),
			stop: this.stop.bind(this),
			cancel: this.cancel.bind(this),
			eventStop: $lambda(false)
		};
		this.attach();
	},

	attach: function(){
		this.handles.addEvent('mousedown', this.bound.start);
		return this;
	},

	detach: function(){
		this.handles.removeEvent('mousedown', this.bound.start);
		return this;
	},

	start: function(event){
		if (this.options.preventDefault) event.preventDefault();
		this.fireEvent('beforeStart', this.element);
		this.mouse.start = event.page;
		var limit = this.options.limit;
		this.limit = {'x': [], 'y': []};
		for (var z in this.options.modifiers){
			if (!this.options.modifiers[z]) continue;
			if (this.options.style) this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt();
			else this.value.now[z] = this.element[this.options.modifiers[z]];
			if (this.options.invert) this.value.now[z] *= -1;
			this.mouse.pos[z] = event.page[z] - this.value.now[z];
			if (limit && limit[z]){
				for (var i = 2; i--; i){
					if ($chk(limit[z][i])) this.limit[z][i] = $lambda(limit[z][i])();
				}
			}
		}
		if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid};
		this.document.addEvents({mousemove: this.bound.check, mouseup: this.bound.cancel});
		this.document.addEvent(this.selection, this.bound.eventStop);
	},

	check: function(event){
		if (this.options.preventDefault) event.preventDefault();
		var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2)));
		if (distance > this.options.snap){
			this.cancel();
			this.document.addEvents({
				mousemove: this.bound.drag,
				mouseup: this.bound.stop
			});
			this.fireEvent('start', this.element).fireEvent('snap', this.element);
		}
	},

	drag: function(event){
		if (this.options.preventDefault) event.preventDefault();
		this.mouse.now = event.page;
		for (var z in this.options.modifiers){
			if (!this.options.modifiers[z]) continue;
			this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z];
			if (this.options.invert) this.value.now[z] *= -1;
			if (this.options.limit && this.limit[z]){
				if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){
					this.value.now[z] = this.limit[z][1];
				} else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){
					this.value.now[z] = this.limit[z][0];
				}
			}
			if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]);
			if (this.options.style) this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit);
			else this.element[this.options.modifiers[z]] = this.value.now[z];
		}
		this.fireEvent('drag', this.element);
	},

	cancel: function(event){
		this.document.removeEvent('mousemove', this.bound.check);
		this.document.removeEvent('mouseup', this.bound.cancel);
		if (event){
			this.document.removeEvent(this.selection, this.bound.eventStop);
			this.fireEvent('cancel', this.element);
		}
	},

	stop: function(event){
		this.document.removeEvent(this.selection, this.bound.eventStop);
		this.document.removeEvent('mousemove', this.bound.drag);
		this.document.removeEvent('mouseup', this.bound.stop);
		if (event) this.fireEvent('complete', this.element);
	}

});

Element.implement({
	
	makeResizable: function(options){
		return new Drag(this, $merge({modifiers: {'x': 'width', 'y': 'height'}}, options));
	}

});

/*
Script: Drag.Move.js
	A Drag extension that provides support for the constraining of draggables to containers and droppables.

License:
	MIT-style license.
*/

Drag.Move = new Class({

	Extends: Drag,

	options: {
		droppables: [],
		container: false
	},

	initialize: function(element, options){
		this.parent(element, options);
		this.droppables = $$(this.options.droppables);
		this.container = $(this.options.container);
		if (this.container && $type(this.container) != 'element') this.container = $(this.container.getDocument().body);
		element = this.element;
		
		var current = element.getStyle('position');
		var position = (current != 'static') ? current : 'absolute';
		if (element.getStyle('left') == 'auto' || element.getStyle('top') == 'auto') element.position(element.getPosition(element.offsetParent));
		
		element.setStyle('position', position);
		
		this.addEvent('start', function(){
			this.checkDroppables();
		}, true);
	},

	start: function(event){
		if (this.container){
			var el = this.element, cont = this.container, ccoo = cont.getCoordinates(el.offsetParent), cps = {}, ems = {};

			['top', 'right', 'bottom', 'left'].each(function(pad){
				cps[pad] = cont.getStyle('padding-' + pad).toInt();
				ems[pad] = el.getStyle('margin-' + pad).toInt();
			}, this);

			var width = el.offsetWidth + ems.left + ems.right, height = el.offsetHeight + ems.top + ems.bottom;
			var x = [ccoo.left + cps.left, ccoo.right - cps.right - width];
			var y = [ccoo.top + cps.top, ccoo.bottom - cps.bottom - height];

			this.options.limit = {x: x, y: y};
		}
		this.parent(event);
	},

	checkAgainst: function(el){
		el = el.getCoordinates();
		var now = this.mouse.now;
		return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top);
	},

	checkDroppables: function(){
		var overed = this.droppables.filter(this.checkAgainst, this).getLast();
		if (this.overed != overed){
			if (this.overed) this.fireEvent('leave', [this.element, this.overed]);
			if (overed){
				this.overed = overed;
				this.fireEvent('enter', [this.element, overed]);
			} else {
				this.overed = null;
			}
		}
	},

	drag: function(event){
		this.parent(event);
		if (this.droppables.length) this.checkDroppables();
	},

	stop: function(event){
		this.checkDroppables();
		this.fireEvent('drop', [this.element, this.overed]);
		this.overed = null;
		return this.parent(event);
	}

});

Element.implement({

	makeDraggable: function(options){
		return new Drag.Move(this, options);
	}

});


/*
Script: Hash.Cookie.js
	Class for creating, reading, and deleting Cookies in JSON format.

License:
	MIT-style license.
*/

Hash.Cookie = new Class({

	Extends: Cookie,

	options: {
		autoSave: true
	},

	initialize: function(name, options){
		this.parent(name, options);
		this.load();
	},

	save: function(){
		var value = JSON.encode(this.hash);
		if (!value || value.length > 4096) return false; //cookie would be truncated!
		if (value == '{}') this.dispose();
		else this.write(value);
		return true;
	},

	load: function(){
		this.hash = new Hash(JSON.decode(this.read(), true));
		return this;
	}

});

Hash.Cookie.implement((function(){
	
	var methods = {};
	
	Hash.each(Hash.prototype, function(method, name){
		methods[name] = function(){
			var value = method.apply(this.hash, arguments);
			if (this.options.autoSave) this.save();
			return value;
		};
	});
	
	return methods;
	
})());

/*
Script: Color.js
	Class for creating and manipulating colors in JavaScript. Supports HSB -> RGB Conversions and vice versa.

License:
	MIT-style license.
*/

var Color = new Native({
  
	initialize: function(color, type){
		if (arguments.length >= 3){
			type = "rgb"; color = Array.slice(arguments, 0, 3);
		} else if (typeof color == 'string'){
			if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);
			else if (color.match(/hsb/)) color = color.hsbToRgb();
			else color = color.hexToRgb(true);
		}
		type = type || 'rgb';
		switch (type){
			case 'hsb':
				var old = color;
				color = color.hsbToRgb();
				color.hsb = old;
			break;
			case 'hex': color = color.hexToRgb(true); break;
		}
		color.rgb = color.slice(0, 3);
		color.hsb = color.hsb || color.rgbToHsb();
		color.hex = color.rgbToHex();
		return $extend(color, this);
	}

});

Color.implement({

	mix: function(){
		var colors = Array.slice(arguments);
		var alpha = ($type(colors.getLast()) == 'number') ? colors.pop() : 50;
		var rgb = this.slice();
		colors.each(function(color){
			color = new Color(color);
			for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
		});
		return new Color(rgb, 'rgb');
	},

	invert: function(){
		return new Color(this.map(function(value){
			return 255 - value;
		}));
	},

	setHue: function(value){
		return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
	},

	setSaturation: function(percent){
		return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
	},

	setBrightness: function(percent){
		return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
	}

});

function $RGB(r, g, b){
	return new Color([r, g, b], 'rgb');
};

function $HSB(h, s, b){
	return new Color([h, s, b], 'hsb');
};

function $HEX(hex){
	return new Color(hex, 'hex');
};

Array.implement({

	rgbToHsb: function(){
		var red = this[0], green = this[1], blue = this[2];
		var hue, saturation, brightness;
		var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
		var delta = max - min;
		brightness = max / 255;
		saturation = (max != 0) ? delta / max : 0;
		if (saturation == 0){
			hue = 0;
		} else {
			var rr = (max - red) / delta;
			var gr = (max - green) / delta;
			var br = (max - blue) / delta;
			if (red == max) hue = br - gr;
			else if (green == max) hue = 2 + rr - br;
			else hue = 4 + gr - rr;
			hue /= 6;
			if (hue < 0) hue++;
		}
		return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
	},

	hsbToRgb: function(){
		var br = Math.round(this[2] / 100 * 255);
		if (this[1] == 0){
			return [br, br, br];
		} else {
			var hue = this[0] % 360;
			var f = hue % 60;
			var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
			var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
			var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
			switch (Math.floor(hue / 60)){
				case 0: return [br, t, p];
				case 1: return [q, br, p];
				case 2: return [p, br, t];
				case 3: return [p, q, br];
				case 4: return [t, p, br];
				case 5: return [br, p, q];
			}
		}
		return false;
	}

});

String.implement({

	rgbToHsb: function(){
		var rgb = this.match(/\d{1,3}/g);
		return (rgb) ? hsb.rgbToHsb() : null;
	},
	
	hsbToRgb: function(){
		var hsb = this.match(/\d{1,3}/g);
		return (hsb) ? hsb.hsbToRgb() : null;
	}

});


/*
Script: Group.js
	Class for monitoring collections of events

License:
	MIT-style license.
*/

var Group = new Class({

	initialize: function(){
		this.instances = Array.flatten(arguments);
		this.events = {};
		this.checker = {};
	},

	addEvent: function(type, fn){
		this.checker[type] = this.checker[type] || {};
		this.events[type] = this.events[type] || [];
		if (this.events[type].contains(fn)) return false;
		else this.events[type].push(fn);
		this.instances.each(function(instance, i){
			instance.addEvent(type, this.check.bind(this, [type, instance, i]));
		}, this);
		return this;
	},

	check: function(type, instance, i){
		this.checker[type][i] = true;
		var every = this.instances.every(function(current, j){
			return this.checker[type][j] || false;
		}, this);
		if (!every) return;
		this.checker[type] = {};
		this.events[type].each(function(event){
			event.call(this, this.instances, instance);
		}, this);
	}

});


/*
Script: Assets.js
	Provides methods to dynamically load JavaScript, CSS, and Image files into the document.

License:
	MIT-style license.
*/

var Asset = new Hash({

	javascript: function(source, properties){
		properties = $extend({
			onload: $empty,
			document: document,
			check: $lambda(true)
		}, properties);
		
		var script = new Element('script', {'src': source, 'type': 'text/javascript'});
		
		var load = properties.onload.bind(script), check = properties.check, doc = properties.document;
		delete properties.onload; delete properties.check; delete properties.document;
		
		script.addEvents({
			load: load,
			readystatechange: function(){
				if (['loaded', 'complete'].contains(this.readyState)) load();
			}
		}).setProperties(properties);
		
		
		if (Browser.Engine.webkit419) var checker = (function(){
			if (!$try(check)) return;
			$clear(checker);
			load();
		}).periodical(50);
		
		return script.inject(doc.head);
	},

	css: function(source, properties){
		return new Element('link', $merge({
			'rel': 'stylesheet', 'media': 'screen', 'type': 'text/css', 'href': source
		}, properties)).inject(document.head);
	},

	image: function(source, properties){
		properties = $merge({
			'onload': $empty,
			'onabort': $empty,
			'onerror': $empty
		}, properties);
		var image = new Image();
		var element = $(image) || new Element('img');
		['load', 'abort', 'error'].each(function(name){
			var type = 'on' + name;
			var event = properties[type];
			delete properties[type];
			image[type] = function(){
				if (!image) return;
				if (!element.parentNode){
					element.width = image.width;
					element.height = image.height;
				}
				image = image.onload = image.onabort = image.onerror = null;
				event.delay(1, element, element);
				element.fireEvent(name, element, 1);
			};
		});
		image.src = element.src = source;
		if (image && image.complete) image.onload.delay(1);
		return element.setProperties(properties);
	},

	images: function(sources, options){
		options = $merge({
			onComplete: $empty,
			onProgress: $empty
		}, options);
		if (!sources.push) sources = [sources];
		var images = [];
		var counter = 0;
		sources.each(function(source){
			var img = new Asset.image(source, {
				'onload': function(){
					options.onProgress.call(this, counter, sources.indexOf(source));
					counter++;
					if (counter == sources.length) options.onComplete();
				}
			});
			images.push(img);
		});
		return new Elements(images);
	}

});

/*
Script: Sortables.js
	Class for creating a drag and drop sorting interface for lists of items.

License:
	MIT-style license.
*/

var Sortables = new Class({

	Implements: [Events, Options],

	options: {/*
		onSort: $empty,
		onStart: $empty,
		onComplete: $empty,*/
		snap: 4,
		opacity: 1,
		clone: false,
		revert: false,
		handle: false,
		constrain: false
	},

	initialize: function(lists, options){
		this.setOptions(options);
		this.elements = [];
		this.lists = [];
		this.idle = true;
		
		this.addLists($$($(lists) || lists));
		if (!this.options.clone) this.options.revert = false;
		if (this.options.revert) this.effect = new Fx.Morph(null, $merge({duration: 250, link: 'cancel'}, this.options.revert));
	},

	attach: function(){
		this.addLists(this.lists);
		return this;
	},

	detach: function(){
		this.lists = this.removeLists(this.lists);
		return this;
	},

	addItems: function(){
		Array.flatten(arguments).each(function(element){
			this.elements.push(element);
			var start = element.retrieve('sortables:start', this.start.bindWithEvent(this, element));
			(this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start);
		}, this);
		return this;
	},

	addLists: function(){
		Array.flatten(arguments).each(function(list){
			this.lists.push(list);
			this.addItems(list.getChildren());
		}, this);
		return this;
	},

	removeItems: function(){
		var elements = [];
		Array.flatten(arguments).each(function(element){
			elements.push(element);
			this.elements.erase(element);
			var start = element.retrieve('sortables:start');
			(this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start);
		}, this);
		return $$(elements);
	},

	removeLists: function(){
		var lists = [];
		Array.flatten(arguments).each(function(list){
			lists.push(list);
			this.lists.erase(list);
			this.removeItems(list.getChildren());
		}, this);
		return $$(lists);
	},

	getClone: function(event, element){
		if (!this.options.clone) return new Element('div').inject(document.body);
		if ($type(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list);
		return element.clone(true).setStyles({
			'margin': '0px',
			'position': 'absolute',
			'visibility': 'hidden',
			'width': element.getStyle('width')
		}).inject(this.list).position(element.getPosition(element.getOffsetParent()));
	},

	getDroppables: function(){
		var droppables = this.list.getChildren();
		if (!this.options.constrain) droppables = this.lists.concat(droppables).erase(this.list);
		return droppables.erase(this.clone).erase(this.element);
	},

	insert: function(dragging, element){
		var where = 'inside';
		if (this.lists.contains(element)){
			this.list = element;
			this.drag.droppables = this.getDroppables();
		} else {
			where = this.element.getAllPrevious().contains(element) ? 'before' : 'after';
		}
		this.element.inject(element, where);
		this.fireEvent('sort', [this.element, this.clone]);
	},

	start: function(event, element){
		if (!this.idle) return;
		this.idle = false;
		this.element = element;
		this.opacity = element.get('opacity');
		this.list = element.getParent();
		this.clone = this.getClone(event, element);
		
		this.drag = new Drag.Move(this.clone, {
			snap: this.options.snap,
			container: this.options.constrain && this.element.getParent(),
			droppables: this.getDroppables(),
			onSnap: function(){
				event.stop();
				this.clone.setStyle('visibility', 'visible');
				this.element.set('opacity', this.options.opacity || 0);
				this.fireEvent('start', [this.element, this.clone]);
			}.bind(this),
			onEnter: this.insert.bind(this),
			onCancel: this.reset.bind(this),
			onComplete: this.end.bind(this)
		});
		
		this.clone.inject(this.element, 'before');
		this.drag.start(event);
	},

	end: function(){
		this.drag.detach();
		this.element.set('opacity', this.opacity);
		if (this.effect){
			var dim = this.element.getStyles('width', 'height');
			var pos = this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));
			this.effect.element = this.clone;
			this.effect.start({
				top: pos.top,
				left: pos.left,
				width: dim.width,
				height: dim.height,
				opacity: 0.25
			}).chain(this.reset.bind(this));
		} else {
			this.reset();
		}
	},

	reset: function(){
		this.idle = true;
		this.clone.destroy();
		this.fireEvent('complete', this.element);
	},

	serialize: function(){
		var params = Array.link(arguments, {modifier: Function.type, index: $defined});
		var serial = this.lists.map(function(list){
			return list.getChildren().map(params.modifier || function(element){
				return element.get('id');
			}, this);
		}, this);
		
		var index = params.index;
		if (this.lists.length == 1) index = 0;
		return $chk(index) && index >= 0 && index < this.lists.length ? serial[index] : serial;
	}

});

/*
Script: Tips.js
	Class for creating nice tips that follow the mouse cursor when hovering an element.

License:
	MIT-style license.
*/

var Tips = new Class({

	Implements: [Events, Options],

	options: {
		onShow: function(tip){
			tip.setStyle('visibility', 'visible');
		},
		onHide: function(tip){
			tip.setStyle('visibility', 'hidden');
		},
		showDelay: 100,
		hideDelay: 100,
		className: null,
		offsets: {x: 16, y: 16},
		fixed: false
	},

	initialize: function(){
		var params = Array.link(arguments, {options: Object.type, elements: $defined});
		this.setOptions(params.options || null);
		
		this.tip = new Element('div').inject(document.body);
		
		if (this.options.className) this.tip.addClass(this.options.className);
		
		var top = new Element('div', {'class': 'tip-top'}).inject(this.tip);
		this.container = new Element('div', {'class': 'tip'}).inject(this.tip);
		var bottom = new Element('div', {'class': 'tip-bottom'}).inject(this.tip);

		this.tip.setStyles({position: 'absolute', top: 0, left: 0, visibility: 'hidden'});
		
		if (params.elements) this.attach(params.elements);
	},
	
	attach: function(elements){
		$$(elements).each(function(element){
			var title = element.retrieve('tip:title', element.get('title'));
			var text = element.retrieve('tip:text', element.get('rel') || element.get('href'));
			var enter = element.retrieve('tip:enter', this.elementEnter.bindWithEvent(this, element));
			var leave = element.retrieve('tip:leave', this.elementLeave.bindWithEvent(this, element));
			element.addEvents({mouseenter: enter, mouseleave: leave});
			if (!this.options.fixed){
				var move = element.retrieve('tip:move', this.elementMove.bindWithEvent(this, element));
				element.addEvent('mousemove', move);
			}
			element.store('tip:native', element.get('title'));
			element.erase('title');
		}, this);
		return this;
	},
	
	detach: function(elements){
		$$(elements).each(function(element){
			element.removeEvent('mouseenter', element.retrieve('tip:enter') || $empty);
			element.removeEvent('mouseleave', element.retrieve('tip:leave') || $empty);
			element.removeEvent('mousemove', element.retrieve('tip:move') || $empty);
			element.eliminate('tip:enter').eliminate('tip:leave').eliminate('tip:move');
			var original = element.retrieve('tip:native');
			if (original) element.set('title', original);
		});
		return this;
	},
	
	elementEnter: function(event, element){
		
		$A(this.container.childNodes).each(Element.dispose);
		
		var title = element.retrieve('tip:title');
		
		if (title){
			this.titleElement = new Element('div', {'class': 'tip-title'}).inject(this.container);
			this.fill(this.titleElement, title);
		}
		
		var text = element.retrieve('tip:text');
		if (text){
			this.textElement = new Element('div', {'class': 'tip-text'}).inject(this.container);
			this.fill(this.textElement, text);
		}
		
		this.timer = $clear(this.timer);
		this.timer = this.show.delay(this.options.showDelay, this);

		this.position((!this.options.fixed) ? event : {page: element.getPosition()});
	},
	
	elementLeave: function(event){
		$clear(this.timer);
		this.timer = this.hide.delay(this.options.hideDelay, this);
	},
	
	elementMove: function(event){
		this.position(event);
	},
	
	position: function(event){
		var size = window.getSize(), scroll = window.getScroll();
		var tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight};
		var props = {x: 'left', y: 'top'};
		for (var z in props){
			var pos = event.page[z] + this.options.offsets[z];
			if ((pos + tip[z] - scroll[z]) > size[z]) pos = event.page[z] - this.options.offsets[z] - tip[z];
			this.tip.setStyle(props[z], pos);
		}
	},
	
	fill: function(element, contents){
		(typeof contents == 'string') ? element.set('html', contents) : element.adopt(contents);
	},

	show: function(){
		this.fireEvent('show', this.tip);
	},

	hide: function(){
		this.fireEvent('hide', this.tip);
	}

});

/*
Script: SmoothScroll.js
	Class for creating a smooth scrolling effect to all internal links on the page.

License:
	MIT-style license.
*/

var SmoothScroll = new Class({

	Extends: Fx.Scroll,

	initialize: function(options, context){
		context = context || document;
		var doc = context.getDocument(), win = context.getWindow();
		this.parent(doc, options);
		this.links = (this.options.links) ? $$(this.options.links) : $$(doc.links);
		var location = win.location.href.match(/^[^#]*/)[0] + '#';
		this.links.each(function(link){
			if (link.href.indexOf(location) != 0) return;
			var anchor = link.href.substr(location.length);
			if (anchor && $(anchor)) this.useLink(link, anchor);
		}, this);
		if (!Browser.Engine.webkit419) this.addEvent('complete', function(){
			win.location.hash = this.anchor;
		}, true);
	},

	useLink: function(link, anchor){
		link.addEvent('click', function(event){
			this.anchor = anchor;
			this.toElement(anchor);
			event.stop();
		}.bind(this));
	}

});

/*
Script: Slider.js
	Class for creating horizontal and vertical slider controls.

License:
	MIT-style license.
*/

var Slider = new Class({

	Implements: [Events, Options],

	options: {/*
		onChange: $empty,
		onComplete: $empty,*/
		onTick: function(position){
			if(this.options.snap) position = this.toPosition(this.step);
			this.knob.setStyle(this.property, position);
		},
		snap: false,
		offset: 0,
		range: false,
		wheel: false,
		steps: 100,
		mode: 'horizontal'
	},

	initialize: function(element, knob, options){
		this.setOptions(options);
		this.element = $(element);
		this.knob = $(knob);
		this.previousChange = this.previousEnd = this.step = -1;
		this.element.addEvent('mousedown', this.clickedElement.bind(this));
		if (this.options.wheel) this.element.addEvent('mousewheel', this.scrolledElement.bindWithEvent(this));
		var offset, limit = {}, modifiers = {'x': false, 'y': false};
		switch (this.options.mode){
			case 'vertical':
				this.axis = 'y';
				this.property = 'top';
				offset = 'offsetHeight';
				break;
			case 'horizontal':
				this.axis = 'x';
				this.property = 'left';
				offset = 'offsetWidth';
		}
		this.half = this.knob[offset] / 2;
		this.full = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
		this.min = $chk(this.options.range[0]) ? this.options.range[0] : 0;
		this.max = $chk(this.options.range[1]) ? this.options.range[1] : this.options.steps;
		this.range = this.max - this.min;
		this.steps = this.options.steps || this.full;
		this.stepSize = Math.abs(this.range) / this.steps;
		this.stepWidth = this.stepSize * this.full / Math.abs(this.range) ;
		
		this.knob.setStyle('position', 'relative').setStyle(this.property, - this.options.offset);
		modifiers[this.axis] = this.property;
		limit[this.axis] = [- this.options.offset, this.full - this.options.offset];
		this.drag = new Drag(this.knob, {
			snap: 0,
			limit: limit,
			modifiers: modifiers,
			onDrag: this.draggedKnob.bind(this),
			onStart: this.draggedKnob.bind(this),
			onComplete: function(){
				this.draggedKnob();
				this.end();
			}.bind(this)
		});
		if (this.options.snap) {
			this.drag.options.grid = Math.ceil(this.stepWidth);
			this.drag.options.limit[this.axis][1] = this.full;
		}
	},

	set: function(step){
		if (!((this.range > 0) ^ (step < this.min))) step = this.min;
		if (!((this.range > 0) ^ (step > this.max))) step = this.max;
		
		this.step = Math.round(step);
		this.checkStep();
		this.end();
		this.fireEvent('tick', this.toPosition(this.step));
		return this;
	},

	clickedElement: function(event){
		var dir = this.range < 0 ? -1 : 1;
		var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half;
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		
		this.step = Math.round(this.min + dir * this.toStep(position));
		this.checkStep();
		this.end();
		this.fireEvent('tick', position);
	},
	
	scrolledElement: function(event){
		var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);
		this.set(mode ? this.step - this.stepSize : this.step + this.stepSize);
		event.stop();
	},

	draggedKnob: function(){
		var dir = this.range < 0 ? -1 : 1;
		var position = this.drag.value.now[this.axis];
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		this.step = Math.round(this.min + dir * this.toStep(position));
		this.checkStep();
	},

	checkStep: function(){
		if (this.previousChange != this.step){
			this.previousChange = this.step;
			this.fireEvent('change', this.step);
		}
	},

	end: function(){
		if (this.previousEnd !== this.step){
			this.previousEnd = this.step;
			this.fireEvent('complete', this.step + '');
		}
	},

	toStep: function(position){
		var step = (position + this.options.offset) * this.stepSize / this.full * this.steps;
		return this.options.steps ? Math.round(step -= step % this.stepSize) : step;
	},

	toPosition: function(step){
		return (this.full * Math.abs(this.min - step)) / (this.steps * this.stepSize) - this.options.offset;
	}

});

/*
Script: Scroller.js
	Class which scrolls the contents of any Element (including the window) when the mouse reaches the Element's boundaries.

License:
	MIT-style license.
*/

var Scroller = new Class({

	Implements: [Events, Options],

	options: {
		area: 20,
		velocity: 1,
		onChange: function(x, y){
			this.element.scrollTo(x, y);
		}
	},

	initialize: function(element, options){
		this.setOptions(options);
		this.element = $(element);
		this.listener = ($type(this.element) != 'element') ? $(this.element.getDocument().body) : this.element;
		this.timer = null;
		this.coord = this.getCoords.bind(this);
	},

	start: function(){
		this.listener.addEvent('mousemove', this.coord);
	},

	stop: function(){
		this.listener.removeEvent('mousemove', this.coord);
		this.timer = $clear(this.timer);
	},

	getCoords: function(event){
		this.page = (this.listener.get('tag') == 'body') ? event.client : event.page;
		if (!this.timer) this.timer = this.scroll.periodical(50, this);
	},

	scroll: function(){
		var size = this.element.getSize(), scroll = this.element.getScroll(), pos = this.element.getPosition(), change = {'x': 0, 'y': 0};
		for (var z in this.page){
			if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0)
				change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
			else if (this.page[z] + this.options.area > (size[z] + pos[z]) && size[z] + size[z] != scroll[z])
				change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity;
		}
		if (change.y || change.x) this.fireEvent('change', [scroll.x + change.x, scroll.y + change.y]);
	}

});

/*
Script: Accordion.js
	An Fx.Elements extension which allows you to easily create accordion type controls.

License:
	MIT-style license.
*/

var Accordion = new Class({

	Extends: Fx.Elements,

	options: {/*
		onActive: $empty,
		onBackground: $empty,*/
		display: 0,
		show: false,
		height: true,
		width: false,
		opacity: true,
		fixedHeight: false,
		fixedWidth: false,
		wait: false,
		alwaysHide: false
	},

	initialize: function(){
		var params = Array.link(arguments, {'container': Element.type, 'options': Object.type, 'togglers': $defined, 'elements': $defined});
		this.parent(params.elements, params.options);
		this.togglers = $$(params.togglers);
		this.container = $(params.container);
		this.previous = -1;
		if (this.options.alwaysHide) this.options.wait = true;
		if ($chk(this.options.show)){
			this.options.display = false;
			this.previous = this.options.show;
		}
		if (this.options.start){
			this.options.display = false;
			this.options.show = false;
		}
		this.effects = {};
		if (this.options.opacity) this.effects.opacity = 'fullOpacity';
		if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';
		if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';
		for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]);
		this.elements.each(function(el, i){
			if (this.options.show === i){
				this.fireEvent('active', [this.togglers[i], el]);
			} else {
				for (var fx in this.effects) el.setStyle(fx, 0);
			}
		}, this);
		if ($chk(this.options.display)) this.display(this.options.display);
	},

	addSection: function(toggler, element, pos){
		toggler = $(toggler);
		element = $(element);
		var test = this.togglers.contains(toggler);
		var len = this.togglers.length;
		this.togglers.include(toggler);
		this.elements.include(element);
		if (len && (!test || pos)){
			pos = $pick(pos, len - 1);
			toggler.inject(this.togglers[pos], 'before');
			element.inject(toggler, 'after');
		} else if (this.container && !test){
			toggler.inject(this.container);
			element.inject(this.container);
		}
		var idx = this.togglers.indexOf(toggler);
		toggler.addEvent('click', this.display.bind(this, idx));
		if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});
		if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});
		element.fullOpacity = 1;
		if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;
		if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;
		element.setStyle('overflow', 'hidden');
		if (!test){
			for (var fx in this.effects) element.setStyle(fx, 0);
		}
		return this;
	},

	display: function(index){
		index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
		if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this;
		this.previous = index;
		var obj = {};
		this.elements.each(function(el, i){
			obj[i] = {};
			var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
			this.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]);
			for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]];
		}, this);
		return this.start(obj);
	}

});

/*
	Class: FormCheck
		Performs different tests on forms and indicates errors.
		
	Usage:
		Works with these types of fields :
		- input (text, radio, checkbox)
		- textarea
		- select
		
		You just need to add a specific class to each fields you want to check. 
		For example, if you add the class
			(code)
			validate['required','length[4, -1]','differs[email]','digit']
			(end code)
		the value's field must be set (required) with a minimum length of four chars (4, -1), 
		must differs of the input named email (differs[email]), and must be digit. 
		
		You can perform check during the datas entry or on the submit action, shows errors as tips or in a div before or after the field, 
		show errors one by one or all together, show a list of all errors at the top of the form, localize error messages, add new regex check, ...
		
		The layout is design only with css. Now I added a hack to use transparent png with IE6, so you can use png images in formcheck.css (works only for theme, so the file must be named formcheck.css). It can also works with multiple forms on a single html page.
		The class supports now internationalization. To use it, simply specify a new <script> element in your html head, like this : <script type="text/javascript" src="formcheck/lang/fr.js"></script>.

		If you add the class
			(code)
			validate['submit']
			(end code)
		to an element like an anchor (or anything else), this element will act as a submit button.
		
		N.B. : you must load the language script before the formcheck and this method overpass the old way. You can create new languages following existing ones. You can otherwise still specifiy the alerts' strings when you initialize the Class, with options.
		If you don't use a language script, the alert will be displayed in english.
	
	Test type:
		You can perform various test on fields by addind them to the validate class. Be careful to *not use space chars*. Here is the list of them.
			
		required 					- The field becomes required. This is a regex, you can change it with class options.
		alpha 						- The value is restricted to alphabetic chars. This is a regex, you can change it with class options.
		alphanum 					- The value is restricted to alphanumeric characters only. This is a regex, you can change it with class options.
		nodigit 					- The field doesn't accept digit chars. This is a regex, you can change it with class options.
		digit 						- The value is restricted to digit (no floating point number) chars, you can pass two arguments (f.e. digit[21,65]) to limit the number between them. Use -1 as second argument to not set a maximum.
		number 						- The value is restricted to number, including floating point number. This is a regex, you can change it with class options.
		email 						- The value is restricted to valid email. This is a regex, you can change it with class options.
		phone 						- The value is restricted to phone chars. This is a regex, you can change it with class options.
		url: 						- The value is restricted to url. This is a regex, you can change it with class options.
		confirm 					- The value has to be the same as the one passed in argument. f.e. confirm[password].
		differs 					- The value has to be diferent as the one passed in argument. f.e. differs[user].
		length 						- The value length is restricted by argument (f.e. length[6,10]). Use -1 as second argument to not set a maximum.
		
		You can also use a custom function to check a field. For example, if you have a field with class
			(code)
			validate['required','%customCheck']
			(end code)
		the function customCheck(el) will be called to validate the field. '%customcheck' works with other validate(s) together, and '~customcheck' works if the element pass the other validate(s). 
		Here is an example of what customCheck could look : 
			(code)
			function customCheck(el){
				if (!el.value.test(/^[A-Z]/)) {
					el.errors.push("Username should begin with an uppercase letter"); 
					return false;
				} else {
					return true;
				}
			}
			(end code)
		
		It is now possible to register new fields after a new FormCheck call by using <FormCheck::register> (see <FormCheck::dispose> too).
		
	Parameters:
		When you initialize the class with addEvent, you can set some options. If you want to modify regex, you must do it in a hash, like for display or alert. You can also add new regex check method by adding the regex and an alert with the same name.
		
		Required:
			
			form_id - The id of the formular. This is required.
			
		Optional:
			
			submitByAjax 			- you can set this to true if you want to submit your form with ajax. You should use provided events to handle the ajax request (see below). By default it is false.
			ajaxResponseDiv 		- id of element to inject ajax response into (can also use onAjaxSuccess). By default it is false.
			ajaxEvalScripts 		- use evalScripts in the Request response. Can be true or false, by default it is false.
			onAjaxRequest 			- Function to fire when the Request event starts.
			onAjaxSuccess 			- Function to fire when the Request receives .  Args: response [the request response] - see Mootools docs for Request.onSuccess.
			onAjaxFailure 			- Function to fire if the Request fails.
			
			tipsClass 				- The class to apply to tipboxes' errors. By default it is 'fc-tbx'.
			errorClass 				- The class to apply to alertbox (not tips). By default it is 'fc-error'.
			fieldErrorClass 		- The class to apply to fields with errors, except for radios. You should also turn on  options.addClassErrorToField. By default it is 'fc-field-error'
			
			trimValue				- If set to true, strip whitespace (or other characters) from the beginning and end of values. By default it is false.
			validateDisabled		- If set to true, disabled input will be validated too, otherwise not.

		Display:
			This is a hash of display settings. in here you can modify.
			
			showErrors 				- 0 : onSubmit, 1 : onSubmit & onBlur, by default it is 1.
			titlesInsteadNames		- 0 : When you do a check using differs or confirm, it takes the field name for the alert. If it's set to 1, it will use the title instead of the name.
			errorsLocation 			- 1 : tips, 2 : before, 3 : after, by default it is 1.
			indicateErrors 			- 0 : none, 1 : one by one, 2 : all, by default it is 1.
			indicateErrorsInit		- 0 : determine if the form must be checked on initialize. Could be usefull to force the user to update fields that don't validate.
			keepFocusOnError 		- 0 : normal behaviour, 1 : the current field keep the focus as it remain errors. By default it is 0.
			checkValueIfEmpty 		- 0 : When you leave a field and you have set the showErrors option to 1, the value is tested only if a value has been set. 1 : The value is tested  in any case.  By default it is 1.
			addClassErrorToField 	- 0 : no class is added to the field, 1 : the options.fieldErrorClass is added to the field with an error (except for radio). By default it is 0.

			fixPngForIe 			- 0 : do nothing, 1 : fix png alpha for IE6 in formcheck.css. By default it is 1.
			replaceTipsEffect 		- 0 : No effect on tips replace when we resize the broswer, 1: tween transition on browser resize;
			closeTipsButton 		- 0 : the close button of the tipbox is hidden, 1 : the close button of the tipbox is visible. By default it is 1.
			flashTips 				- 0 : normal behaviour, 1 : the tipbox "flash" (disappear and reappear) if errors remain when the form is submitted. By default it is 0.
			tipsPosition 			- 'right' : the tips box is placed on the right part of the field, 'left' to place it on the left part. By default it is 'right'.
			tipsOffsetX 			- Horizontal position of the tips box (margin-left), , by default it is 100 (px).
			tipsOffsetY				- Vertical position of the tips box (margin-bottom), , by default it is -10 (px).
			
			listErrorsAtTop 		- List all errors at the top of the form, , by default it is false.
			scrollToFirst 			- Smooth scroll the page to first error and focus on it, by default it is true.
			fadeDuration 			- Transition duration (in ms), by default it is 300.
		
		Alerts:
			This is a hash of alerts settings. in here you can modify strings to localize or wathever else. %0 and %1 represent the argument.
			
			required 				- "This field is required."
			alpha 					- "This field accepts alphabetic characters only."
			alphanum 				- "This field accepts alphanumeric characters only."
			nodigit 				- "No digits are accepted."
			digit 					- "Please enter a valid integer."
			digitmin 				- "The number must be at least %0"
			digitltd 				- "The value must be between %0 and %1"
			number 					- "Please enter a valid number."
			email 					- "Please enter a valid email: <br /><span>E.g. yourname@domain.com</span>"
			phone 					- "Please enter a valid phone."
			url 					- "Please enter a valid url: <br /><span>E.g. http://www.domain.com</span>"
			confirm 				- "This field is different from %0"
			differs 				- "This value must be different of %0"
			length_str 				- "The length is incorrect, it must be between %0 and %1"
			length_fix 				- "The length is incorrect, it must be exactly %0 characters"
			lengthmax 				- "The length is incorrect, it must be at max %0"
			lengthmin 				- "The length is incorrect, it must be at least %0"
			checkbox 				- "Please check the box"
			radios 					- "Please select a radio"
			select 					- "Please choose a value"
		
	Example:
		You can initialize a formcheck (no scroll, custom classes and alert) by adding for example this in your html head this code :
		
		(code)
		<script type="text/javascript">
			window.addEvent('domready', function() {
				var myCheck = new FormCheck('form_id', {
					tipsClass : 'tips_box',
					display : {
						scrollToFirst : false
					},
					alerts : {
						required : 'This field is ablolutely required! Please enter a value'
					}
				})
			});
		</script>
		(end code)
	
	About:
		formcheck.js v.1.4.2 for mootools v1.2 - 12 / 2008
		
		by Floor SA (http://www.floor.ch) MIT-style license
		
		Created by Luca Pillonel, last modified by Luca Pillonel
		
	Credits:
		This class was inspired by fValidator by Fabio Zendhi Nagao (http://zend.lojcomm.com.br)
		
		Thanks to oneZ, Blots, huughelmink, chdeliens, and everyone who contribute to this project...
*/

var FormCheck = new Class({
	
	Implements: [Options, Events],

	options : {
		
		tipsClass: 'fc-tbx',				//tips error class
		errorClass: 'fc-error',				//div error class
		fieldErrorClass: 'fc-field-error',	//error class for elements
		
		trimValue : false,					//trim (remove whitespaces before and after) the value
		validateDisabled : false,			//skip validation on disabled input if set to false.
		
		submitByAjax : false,				//false : standard submit way, true : submit by ajax
		ajaxResponseDiv : false,			//element to inject ajax response into (can also use onAjaxSuccess) [cronix] 
		ajaxEvalScripts : false,			//use evalScripts in the Request response [cronix] 
		onAjaxRequest : $empty,				//Function to fire when the Request event starts 
		onAjaxSuccess : $empty,				//Function to fire when the Request receives .  Args: response [the request response] - see Mootools docs for Request.onSuccess 
		onAjaxFailure : $empty,				//Function to fire if the Request fails 

		display : {
			showErrors : 0,
			titlesInsteadNames : 0,
			errorsLocation : 1,
			indicateErrors : 1,
			indicateErrorsInit : 0,
			keepFocusOnError : 0,
			checkValueIfEmpty : 1,
			addClassErrorToField : 0,
			fixPngForIe : 1,
			replaceTipsEffect : 1,
			flashTips : 0,
			closeTipsButton : 1,
			tipsPosition : "right",
			tipsOffsetX : -45,
			tipsOffsetY : 0,
			listErrorsAtTop : false,
			scrollToFirst : true,
			fadeDuration : 300
		},
		
		alerts : {
			required: "This field is required.",
			alpha: "This field accepts alphabetic characters only.",
			alphanum: "This field accepts alphanumeric characters only.",
			nodigit: "No digits are accepted.",
			digit: "Please enter a valid integer.",
			digitltd: "The value must be between %0 and %1",
			number: "Please enter a valid number.",
			email: "Please enter a valid email.",
			phone: "Please enter a valid phone.",
			url: "Please enter a valid url. eg. http://www.example.com.au",
			
			confirm: "This field is different from %0",
			differs: "This value must be different to %0",
			length_str: "The length is incorrect, it must be between %0 and %1",
			length_fix: "The length is incorrect, it must be exactly %0 characters",
			lengthmax: "The length is incorrect, it must be at max %0",
			lengthmin: "The length is incorrect, it must be at least %0",
			checkbox: "Please check the box",
			radios: "Please select a radio",
			select: "Please choose a value"
		},
		
		regexp : {
			required : /[^.*]/,
			alpha : /^[a-z ._-]+$/i,
			alphanum : /^[a-z0-9 ._-]+$/i,
			digit : /^[-+]?[0-9]+$/,
			nodigit : /^[^0-9]+$/,
			number : /^[-+]?\d*\.?\d+$/,
			email : /^[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i,
			phone : /^[\d\s ().-]+$/,
			url : /^(http|https|ftp)\:\/\/[a-z0-9\-\.]+\.[a-z]{2,3}(:[a-z0-9]*)?\/?([a-z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*$/i
		}
	},
	
	/*
	Constructor: initialize
		Constructor
	
		Add event on formular and perform some stuff, you now, like settings, ...
	*/
	initialize : function(form, options) {
		if (this.form = $(form)) {
			this.form.isValid = true;
			this.regex = ['length'];
			this.setOptions(options);
			
			//internalization
			if (typeof(formcheckLanguage) != 'undefined') this.options.alerts = $merge(this.options.alerts, formcheckLanguage);
			
			this.validations = [];
			this.alreadyIndicated = false;
			this.firstError = false;
			
			var regex = new Hash(this.options.regexp);
			regex.each(function(el, key) {
				this.regex.push(key);
			}, this);

			this.form.getElements("*[class*=validate]").each(function(el) {
				this.register(el);
			}, this);
			
			this.form.addEvents({
				"submit": this.onSubmit.bind(this)
			});
			
			if(this.options.display.fixPngForIe) this.fixIeStuffs();
			document.addEvent('mousewheel', function(){
				this.isScrolling = false;
			}.bind(this));
		}
	},
	
	/*
	Function: register
		Allows you to declare afterward new fields to the formcheck, to check dynamically loaded fields for example.
	
	Example:
		(code)
		<script type="text/javascript">
			window.addEvent('domready', function() {
				formcheck = new FormCheck('form_id');
			});
			
			// ...some code...
			
			var newField = new Element('input', {
				class	: "validate['required']",
				name	: "new-field"
			}).inject('form_id');
			formcheck.register(newField);
			
			new Element('input', {
				class	: "validate['required']",
				name	: "another-field",
				id		: "another-field"
			}).inject('form_id');
			formcheck.register($('another-field'));
		</script>
		(end code)
	
	See also:
		<FormCheck::dispose>
	*/
	register : function(el) {
		el.validation = [];
		el.getProperty("class").split(' ').each(function(classX) {
			if(classX.match(/^validate(\[.+\])$/)) {
				var validators = eval(classX.match(/^validate(\[.+\])$/)[1]);
				for(var i = 0; i < validators.length; i++) {
					el.validation.push(validators[i]);
					if (validators[i].match(/^confirm\[/)) {
						var field = eval(validators[i].match(/^.+(\[.+\])$/)[1].replace(/([A-Z0-9\._-]+)/i, "'$1'"));
						if (this.form[field].validation.contains('required')){
							el.validation.push('required');
						}
							
					}
				}
				this.addListener(el);
			}
		}, this);
	},
	
	/*
	Function: dispose
		Allows you to remove a declared field from formCheck
	
	Example:
		(code)
		<script type="text/javascript">
			window.addEvent('domready', function() {
				formcheck = new FormCheck('form_id');
			});
			
			// ...some code...
			
			formcheck.dispose($('obsolete-field'));
		</script>
		(end code)
	
	See also:
		<FormCheck::register>
	*/
	dispose : function(element) {
		this.validations.erase(element);
	},
	
	/*
	Function: addListener
		Private method
		
		Add listener on fields
	*/
	addListener : function(el) {
		this.validations.push(el);
		el.errors = [];
		
		if (this.options.display.indicateErrorsInit) {
			this.validations.each(function(el) {
				if(!this.manageError(el,'submit')) this.form.isValid = false;
			}, this);
			return true;
		} 
	
		if (el.validation[0] == 'submit') {
			el.addEvent('click', function(e){
				this.onSubmit(e);
			}.bind(this));
			return true;
		}

		if (this.isChildType(el) == false) el.addEvent('blur', function() {
			(function(){
				if(!this.fxRunning && (el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value))
				this.manageError(el, 'blur')
			}.bind(this)).delay(100);
		}.bind(this))
		//We manage errors on radio
		else if (this.isChildType(el) == true) {
			//We get all radio from the same group and add a blur option
			var nlButtonGroup = this.form.getElements('input[name="'+ el.getProperty("name") +'"]');
			nlButtonGroup.each(function(radio){
				radio.addEvent('blur', function(){
					(function(){
						if((el.element || this.options.display.showErrors == 1) && (this.options.display.checkValueIfEmpty || el.value)) this.manageError(el, 'click');
					}.bind(this)).delay(100);
				}.bind(this))
			},this);
		}
	},
	
	/*
	Function: validate
		Private method
		
		Dispatch check to other methods
	*/
	validate : function(el) {
		el.errors = [];
		el.isOk = true;
		
		//skip validation and trim if specified
		if (!this.options.validateDisabled && el.get('disabled')) return true;
		if (this.options.trimValue && el.value) el.value = el.value.trim();
		
		el.validation.each(function(rule) {
			if(this.isChildType(el)) {
				if (this.validateGroup(el) == false) {
					el.isOk = false;
				}
			} else {
				var ruleArgs = [];
				
				if(rule.match(/^.+\[/)) {
					var ruleMethod = rule.split('[')[0];
					ruleArgs = eval(rule.match(/^.+(\[.+\])$/)[1].replace(/([A-Z0-9\._-]+)/i, "'$1'"));
				} else var ruleMethod = rule;
				
				if (this.regex.contains(ruleMethod) && el.get('tag') != "select") {
					if (this.validateRegex(el, ruleMethod, ruleArgs) == false) {
						el.isOk = false;
					}
				}
				
				if (ruleMethod == 'confirm') {
					if (this.validateConfirm(el, ruleArgs) == false) {
						el.isOk = false;
					}
				}
				if (ruleMethod == 'differs') {
					if (this.validateDiffers(el, ruleArgs) == false) {
						el.isOk = false;
					}
				}
				if (el.get('tag') == "select" || (el.type == "checkbox" && ruleMethod == 'required')) {
					if (this.simpleValidate(el) == false) {
						el.isOk = false;
					}
				}
				if(rule.match(/%[A-Z0-9\._-]+$/i) || (el.isOk && rule.match(/~[A-Z0-9\._-]+$/i))) {
					if(eval(rule.slice(1)+'(el)') == false) {
						el.isOk = false;
					}
				}
			}
		}, this);
		
		if (el.isOk) return true;
		else return false;
	},
	
	/*
	Function: simpleValidate
		Private method
		
		Perform simple check for select fields and checkboxes
	*/
	simpleValidate : function(el) {
		if (el.get('tag') == 'select' && el.selectedIndex <= 0) {
			el.errors.push(this.options.alerts.select);
			return false;
		} else if (el.type == "checkbox" && el.checked == false) {
			el.errors.push(this.options.alerts.checkbox);
			return false;
		}
		return true;
	},
	
	/*
	Function: validateRegex
		Private method
		
		Perform regex validations
	*/
	validateRegex : function(el, ruleMethod, ruleArgs) {
		var msg = "";
		if (ruleArgs[1] && ruleMethod == 'length') {
			if (ruleArgs[1] == -1) {
				this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +",}$");
				msg = this.options.alerts.lengthmin.replace("%0",ruleArgs[0]);
			} else if(ruleArgs[0] == ruleArgs[1]) {
				this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +"}$");
				msg = this.options.alerts.length_fix.replace("%0",ruleArgs[0]);
			} else {
				this.options.regexp.length = new RegExp("^[\\s\\S]{"+ ruleArgs[0] +","+ ruleArgs[1] +"}$");
				msg = this.options.alerts.length_str.replace("%0",ruleArgs[0]).replace("%1",ruleArgs[1]);
			}
		} else if (ruleArgs[0] && ruleMethod == 'length') {
			this.options.regexp.length = new RegExp("^.{0,"+ ruleArgs[0] +"}$");
			msg = this.options.alerts.lengthmax.replace("%0",ruleArgs[0]);
		} else {
			msg = this.options.alerts[ruleMethod];
		}
		if (ruleArgs[1] && ruleMethod == 'digit') {
			var regres = true;
			if (!this.options.regexp.digit.test(el.value)) {
				el.errors.push(this.options.alerts[ruleMethod]);
				regres = false;
			}
			if (ruleArgs[1] == -1) {
				if (el.value >= ruleArgs[0]) var valueres = true; else var valueres = false;
				msg = this.options.alerts.digitmin.replace("%0",ruleArgs[0]);
			} else {
				if (el.value >= ruleArgs[0] && el.value <= ruleArgs[1]) var valueres = true; else var valueres = false;
				msg = this.options.alerts.digitltd.replace("%0",ruleArgs[0]).replace("%1",ruleArgs[1]);
			}
			if (regres == false || valueres == false) {
				el.errors.push(msg);
				return false;
			}
		} else if (this.options.regexp[ruleMethod].test(el.value) == false)  {
			el.errors.push(msg);
			return false;
		}
		return true;
	},

	/*
	Function: validateConfirm
		Private method
		
		Perform confirm validations
	*/
	validateConfirm: function(el,ruleArgs) {
		
		var confirm = ruleArgs[0];
		if(el.value != this.form[confirm].value){
			if (this.options.display.titlesInsteadNames)
				var msg = this.options.alerts.confirm.replace("%0",this.form[confirm].getProperty('title'));
			else
				var msg = this.options.alerts.confirm.replace("%0",confirm);
			el.errors.push(msg);
			return false;
		}
		return true;
	},
	
	/*
	Function: validateDiffers
		Private method
		
		Perform differs validations
	*/
	validateDiffers: function(el,ruleArgs) {
		var differs = ruleArgs[0];
		if(el.value == this.form[differs].value){
			if (this.options.display.titlesInsteadNames)
				var msg = this.options.alerts.differs.replace("%0",this.form[differs].getProperty('title'));
			else
				var msg = this.options.alerts.differs.replace("%0",differs);
			el.errors.push(msg);
			return false;
		}
		return true;
	},
	
	/*
	Function: isChildType
		Private method
		
		Determine if the field is a group of radio or not.
	*/
	isChildType: function(el) {
		return ($defined(el.type) && el.type == 'radio') ? true : false;
	},
	
	/*
	Function: validateGroup
		Private method
		
		Perform radios validations
	*/
	validateGroup : function(el) {
		el.errors = [];
		var nlButtonGroup = this.form[el.getProperty("name")];
		el.group = nlButtonGroup;
		var cbCheckeds = false;
		
		for(var i = 0; i < nlButtonGroup.length; i++) {
			if(nlButtonGroup[i].checked) {
				cbCheckeds = true;
			}
		}
		if(cbCheckeds == false) {
			el.errors.push(this.options.alerts.radios);
			return false;
		} else {
			return true;	
		}
	},
	
	/*
	Function: listErrorsAtTop
		Private method
		
		Display errors
	*/
	listErrorsAtTop : function(obj) {
		if(!this.form.element) {
			 this.form.element = new Element('div', {'id' : 'errorlist', 'class' : this.options.errorClass}).injectTop(this.form);
		}
		if ($type(obj) == 'collection') {
			new Element('p').set('html',"<span>" + obj[0].name + " : </span>" + obj[0].errors[0]).injectInside(this.form.element);
		} else {
			if ((obj.validation.contains('required') && obj.errors.length > 0) || (obj.errors.length > 0 && obj.value && obj.validation.contains('required') == false)) {
				obj.errors.each(function(error) {
					new Element('p').set('html',"<span>" + obj.name + " : </span>" + error).injectInside(this.form.element);
				}, this);
			}
		}
	},
	
	/*
	Function: manageError
		Private method
		
		Manage display of errors boxes
	*/
	manageError : function(el, method) {
		var isValid = this.validate(el);
		if ((!isValid && el.validation.flatten()[0].contains('confirm[')) || (!isValid && el.validation.contains('required')) || (!el.validation.contains('required') && el.value && !isValid)) {
			if(this.options.display.listErrorsAtTop == true && method == 'submit')
				this.listErrorsAtTop(el, method);
			if (this.options.display.indicateErrors == 2 ||this.alreadyIndicated == false || el.name == this.alreadyIndicated.name)
			{
				if(!this.firstError) this.firstError = el;
				
				this.alreadyIndicated = el;
				
				if (this.options.display.keepFocusOnError && el.name == this.firstError.name) (function(){el.focus()}).delay(20);
				this.addError(el);
				return false;
			}
		} else if ((isValid || (!el.validation.contains('required') && !el.value)) && el.element) {
			this.removeError(el);
			return true;
		}
		return true;
	},
	
	/*
	Function: addError
		Private method
		
		Add error message
	*/
	addError : function(obj) {
		if(!obj.element && this.options.display.indicateErrors != 0) {
			if (this.options.display.errorsLocation == 1) {
				var pos = (this.options.display.tipsPosition == 'left') ? obj.getCoordinates().left : obj.getCoordinates().right;
				var options = {
					'opacity' : 0,
					'position' : 'absolute',
					'float' : 'left',
					'left' : pos + this.options.display.tipsOffsetX
				}
				obj.element = new Element('div', {'class' : this.options.tipsClass, 'styles' : options}).injectInside(document.body);
				this.addPositionEvent(obj);
			} else if (this.options.display.errorsLocation == 2){
				obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}}).injectBefore(obj);
			} else if (this.options.display.errorsLocation == 3){
				obj.element = new Element('div', {'class' : this.options.errorClass, 'styles' : {'opacity' : 0}});
				if ($type(obj.group) == 'object' || $type(obj.group) == 'collection')
					obj.element.injectAfter(obj.group[obj.group.length-1]);
				else
					obj.element.injectAfter(obj);
			}
		}					
		if (obj.element && obj.element != true) {
			obj.element.empty();
			if (this.options.display.errorsLocation == 1) {
				var errors = [];
				obj.errors.each(function(error) {
					errors.push(new Element('p').set('html', error));
				});
				var tips = this.makeTips(errors).injectInside(obj.element);
				if(this.options.display.closeTipsButton) {
					tips.getElements('a.close').addEvent('mouseup', function(){
						this.removeError(obj);
					}.bind(this));
				}
				obj.element.setStyle('top', obj.getCoordinates().top - tips.getCoordinates().height + this.options.display.tipsOffsetY);
			} else {
				obj.errors.each(function(error) {
					new Element('p').set('html',error).injectInside(obj.element);
				});
			}
			
			if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation < 2) {
				obj.element.setStyle('opacity', 1);
			} else {
				obj.fx = new Fx.Tween(obj.element, {
					'duration' : this.options.display.fadeDuration,
					'ignore' : true,
					'onStart' : function(){
						this.fxRunning = true;
					}.bind(this),
					'onComplete' : function() {
						this.fxRunning = false;
						if (obj.element && obj.element.getStyle('opacity').toInt() == 0) {
							obj.element.destroy();
							obj.element = false;
						}
					}.bind(this)
				})
				if(obj.element.getStyle('opacity').toInt() != 1) obj.fx.start('opacity', 1);
			}
		}
		if (this.options.display.addClassErrorToField && this.isChildType(obj) == false){
			obj.addClass(this.options.fieldErrorClass);
			obj.element = obj.element || true;
		}
			
	},
	
	/*
	Function: addPositionEvent
		
		Update tips position after a browser resize
	*/
	addPositionEvent : function(obj) {
		if(this.options.display.replaceTipsEffect) {
			obj.event = function(){
				new Fx.Morph(obj.element, {
					'duration' : this.options.display.fadeDuration
				}).start({ 
					'left':[obj.element.getStyle('left'), obj.getCoordinates().right + this.options.display.tipsOffsetX],
					'top':[obj.element.getStyle('top'), obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY]
				});
			}.bind(this);
			
		} else {
			obj.event = function(){
				obj.element.setStyles({ 
					'left':obj.getCoordinates().right + this.options.display.tipsOffsetX,
					'top':obj.getCoordinates().top - obj.element.getCoordinates().height + this.options.display.tipsOffsetY
				});
			}.bind(this)
		}
		window.addEvent('resize', obj.event);
	},
	
	/*
	Function: removeError
		Private method
		
		Remove the error display
	*/
	removeError : function(obj) {
		this.alreadyIndicated = false;
		obj.errors = [];
		obj.isOK = true;
		window.removeEvent('resize', obj.event);
		if (this.options.display.errorsLocation >= 2 && obj.element) {
			new Fx.Tween(obj.element, {
				'duration': this.options.display.fadeDuration
			}).start('height', 0);
		}
		if (!this.options.display.fadeDuration || Browser.Engine.trident && Browser.Engine.version == 5 && this.options.display.errorsLocation == 1 && obj.element) {
			this.fxRunning = true;
			obj.element.destroy();
			obj.element = false;
			(function(){this.fxRunning = false}.bind(this)).delay(200);
		} else if (obj.element && obj.element != true) {
			obj.fx.start('opacity', 0);
		}
		
		if (this.options.display.addClassErrorToField && !this.isChildType(obj))
			obj.removeClass(this.options.fieldErrorClass);
	},
	
	/*
	Function: focusOnError
		Private method
		
		Create set the focus to the first field with an error if needed
	*/
	focusOnError : function (obj) {
		if (this.options.display.scrollToFirst && !this.alreadyFocused && !this.isScrolling) {
			if (!this.options.display.indicateErrors || !this.options.display.errorsLocation) {
				var dest = obj.getCoordinates().top-30;
			} else if (this.alreadyIndicated.element) {
				switch (this.options.display.errorsLocation){
					case 1 : 
						var dest = obj.element.getCoordinates().top;
						break;
					case 2 :
						var dest = obj.element.getCoordinates().top-30;
						break;
					case 3 :
						var dest = obj.getCoordinates().top-30;
						break;
				}
				this.isScrolling = true;
			}
			if (window.getScroll.y != dest) {
				new Fx.Scroll(window, {
					onComplete : function() {
						this.isScrolling = false;
						obj.focus();
					}.bind(this)
				}).start(0,dest);
			} else {
				this.isScrolling = false;
				obj.focus();
			}
			this.alreadyFocused = true;
		}
	},
	
	/*
	Function: fixIeStuffs
		Private method
		
		Fix png for IE6
	*/
	fixIeStuffs : function () {
		if (Browser.Engine.trident4) {
			//We fix png stuffs
			var rpng = new RegExp('url\\(([\.a-zA-Z0-9_/:-]+\.png)\\)');
			var search = new RegExp('(.+)formcheck\.css');
			for (var i = 0; i < document.styleSheets.length; i++){
				if (document.styleSheets[i].href.match(/formcheck\.css$/)) {
					var root = document.styleSheets[i].href.replace(search, '$1');
					var count = document.styleSheets[i].rules.length;
					for (var j = 0; j < count; j++){
						var cssstyle = document.styleSheets[i].rules[j].style;
						var bgimage = root + cssstyle.backgroundImage.replace(rpng, '$1');
						if (bgimage && bgimage.match(/\.png/i)){
							var scale = (cssstyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
							cssstyle.filter =  'progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, src=\'' + bgimage + '\', sizingMethod=\''+ scale +'\')';
							cssstyle.backgroundImage = "none";
						}
					}
				}
			}
		}
	},
	
	/*
	Function: makeTips
		Private method
		
		Create tips boxes
	*/
	makeTips : function(txt) {
		var table = new Element('table');
			table.cellPadding ='0';
			table.cellSpacing ='0';
			table.border ='0';
			
			var tbody = new Element('tbody').injectInside(table);
				var tr1 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'tl'}).injectInside(tr1);
					new Element('td', {'class' : 't'}).injectInside(tr1);
					new Element('td', {'class' : 'tr'}).injectInside(tr1);
				var tr2 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'l'}).injectInside(tr2);
					var cont = new Element('td', {'class' : 'c'}).injectInside(tr2);
						var errors = new Element('div', {'class' : 'err'}).injectInside(cont);
						txt.each(function(error) {
							error.injectInside(errors);
						});
						if (this.options.display.closeTipsButton) new Element('a',{'class' : 'close'}).injectInside(cont);
					new Element('td', {'class' : 'r'}).injectInside(tr2);
				var tr3 = new Element('tr').injectInside(tbody);
					new Element('td', {'class' : 'bl'}).injectInside(tr3);
					new Element('td', {'class' : 'b'}).injectInside(tr3);
					new Element('td', {'class' : 'br'}).injectInside(tr3);			
		return table;
	},
	
	/*
	Function: reinitialize
		Private method		
		
		Reinitialize form before submit check
	*/
	reinitialize: function() {
		this.validations.each(function(el) {
			if (el.element) {
				el.errors = [];
				el.isOK = true;
				if(this.options.display.flashTips == 1) {
					el.element.destroy();
					el.element = false;
				}
			}
		}, this);
		if (this.form.element) this.form.element.empty();
		this.alreadyFocused = false;
		this.firstError = false;
		this.elementToRemove = this.alreadyIndicated;
		this.alreadyIndicated = false;
		this.form.isValid = true;
	},
	
	/*
	Function: submitByAjax
		Private method		
		
		Send the form by ajax, and replace the form with response
	*/
	
	submitByAjax: function() {
		var url = this.form.getProperty('action');
		this.fireEvent('ajaxRequest');
		new Request({
			url: url,
			method: this.form.getProperty('method'),
			data : this.form.toQueryString(),
			evalScripts: this.options.ajaxEvalScripts,
			onFailure: function(instance){
				this.fireEvent('ajaxFailure', instance);
			}.bind(this),
			onSuccess: function(result){
				this.fireEvent('ajaxSuccess', result);
				if(this.options.ajaxResponseDiv) $(this.options.ajaxResponseDiv).set('html',result);
			}.bind(this)
		}).send();
	},
	
	/*
	Function: onSubmit
		Private method		
		
		Perform check on submit action
	*/
	onSubmit: function(event) {
		this.reinitialize();
	
		this.validations.each(function(el) {
			var validation = this.manageError(el,'submit');
			if(!validation) this.form.isValid = false;
		}, this);
	    
		if (this.form.isValid) {
			if (this.options.submitByAjax) {
				new Event(event).stop();
				this.submitByAjax();
			}
		} else {
			new Event(event).stop();
			if (this.elementToRemove && this.elementToRemove != this.firstError && this.options.display.indicateErrors == 1) {
				this.removeError(this.elementToRemove);
			}
			this.focusOnError(this.firstError)
		}
	}
});

Cufon.replace('h3');

window.addEvent('domready', function() {
    new FormCheck('form-subscribe', {
		display : {
			indicateErrors	: 2,
			closeTipsButton : 0,
			flashTips 		: 0
		}
	});
	
	$('first-name').focus();
	
	/*$('country').addEvent('change', function(e) {
		alert('aa');
		
		if (this.value==1) {
			$('state').setProperty('disabled', 'true');
		} else $('state').setProperty('disabled', 'false');
	});*/
});

Cufon.replace('legend');

function minchecked(el) {
	// block the default validates
	el.errors	= [];
	el.isOk		= true;
	var total	= 0;

	$('industries').getElements('input[type="checkbox"]').each(function(el) {
		if (el.get('checked')) {
			total	++;
		}
	});
	
	if (total>0) {
		return true;
	} else {
		el.errors.push("Please choose at least 1 category.");
	    return false;
	}
}