if(!window.console)
	var console = {
		log: function(str){ window.status = str; },
		info: function(str){ window.status = str; }
	}

String.implement({
	decode64: function(){ // Base 64 decoding
		var _this = this;
		var output = '';
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
		_this = _this.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		do {
			enc1 = keyStr.indexOf(this.charAt(i++));
			enc2 = keyStr.indexOf(this.charAt(i++));
			enc3 = keyStr.indexOf(this.charAt(i++));
			enc4 = keyStr.indexOf(this.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
			output = output + String.fromCharCode(chr1);
			if (enc3 != 64) output = output + String.fromCharCode(chr2);
			if (enc4 != 64) output = output + String.fromCharCode(chr3);
		} while (i < this.length);
		return output;
	},
	encode64: function() { // Base 64 encoding
		var _this = this;
		var output = '';
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
		var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

		do {
			chr1 = this.charCodeAt(i++);
			chr2 = this.charCodeAt(i++);
			chr3 = this.charCodeAt(i++);
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
			if (isNaN(chr2)) enc3 = enc4 = 64;
			else if (isNaN(chr3)) enc4 = 64;
			output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
			 keyStr.charAt(enc3) + keyStr.charAt(enc4);
		} while (i < this.length);
		return output;
	},
	stripTags: function(){ // Just like in PHP
		var re = /(<([^>]+)>)/gi;
		return this.replace(re, "");
	},
	toHash: function(separator, equal){
		var obj = new $H();
		var pairs = this.split(separator);
		pairs.each(function(pair){
			KV = pair.split(equal);
			obj.set(KV[0], KV[1]);
		});
		return obj;
	},
	setParam: function(param, value){
		var _this = this; // url.split(?)
		if(_this.test(/\?/)) {
			if(!_this.test(param)){
				_this += '&' + param + '=' + value;
				return _this;
			}
			else {
				URI = _this.split('?');
				queryString = URI[1];
				pairs = queryString.split('&');
				str = '?';
				pairs.each(function(pair, i){
					ar = pair.split('=');
					str += ar[0] + '=';
					if(ar[0] == param) str += value;
					else str += ar[1];
					if(pairs.length > i + 1) str += '&';
				});
				return URI[0] + str;
			}
		}
		else{
			_this += '?' + param + '=' + value;
			return _this;
		}
	}
});
Array.implement({
	unique: function () {
		var r = [];
		o:for(var i = 0, n = this.length; i < n; i++)
		{
			for(var x = 0, y = r.length; x < y; x++)
			{
				if(r[x]==this[i])
				{
					continue o;
				}
			}
			r[r.length] = this[i];
		}
		return r;
	}
});
Element.implement({
	toggle: function() {
		if (this.getStyle('display') == 'none')
		this.open();
		else this.close();
		this.fireEvent('onToggle');
	},
	open: function() {
		this.setStyles({'display': 'block', 'opacity': 0});
		this.set({'tween': {
			duration: 200,
			onComplete: (function(){
				this.setStyle('display', 'block');
				this.fireEvent('onOpen');
			}).bind(this)
		}});
		this.fade(1);
	},
	close: function() {
		this.set({'tween': {
			duration: 200,
			onComplete: (function(){
				this.setStyle('display', 'none');
				this.fireEvent('onClose');
			}).bind(this)
		}});
		this.fade(0);
	},
	appendHTML: function(HTML){
		return this.innerHTML = this.innerHTML + HTML;
	},
	getRelativePosition: function(){
		return this.getPosition(this.getOffsetParent());
	}
});

window.addEvents({
	'mousedown': function(e){
		if(e.target.get('tag') == 'input' || e.target.get('tag') == 'textarea') {
			//document.body.setStyle('-moz-user-select', 'none');
			document.onselectstart = '';
		} else {
			//document.body.setStyle('-moz-user-select', 'none');
			document.onselectstart = function(){ return false; };
		}
	}
});
window.addEvents({
	'load': function(){
		$$('button', 'a').each(function(el){
			el.addEvent('focus',function(){el.blur();});
		});
	}
});
var site = {
	start: function(){
		var scrCook = new Hash.Cookie('scrBar', {duration: 5, path: '/home', autoSave: false});
		if(!scrCook.get('width')){
			scrCook.set('width', document.getElement('.mainContainer').getWidth());
			scrCook.save();
		}
		$$('.mainContainer').each(function(cont){
			cont.scrBar = new Element('div', {
				'class': 'scrollBar',
				'html': '<div>Drag me to scroll content.<br /> Double-click to hide me.</div>',
				'events': {
					'dblclick': function(){
						if(cont.scrBar.getStyle('width') == '30px'){
							var w = cont.getWidth();
							var c = '#fff';
							cont.scrBar.setStyles({'width': w, 'color': c});
						} else {
							var w = 30;
							var c = '#666';
							cont.scrBar.setStyles({'width': w, 'color': c});
						}
						scrCook.set('width', w);
						scrCook.set('color', c);
						scrCook.save();
					},
					'mouseenter': function(){
						this.getFirst().open();
						this.fade(0.2);
					},
					'mouseleave': function(){
						this.getFirst().close();
						this.fade(0.1);
					}
				}
			});
			cont.scrBar.scr = new Fx.Scroll(cont, {
				transition: Fx.Transitions.Circ.easeOut,
				duration: 700,
				wheelStops: true
			});
			var ratio = function(){
				return (cont.scrBar.getPosition(cont).y / (cont.getHeight() - cont.scrBar.getHeight()));
			}
			var ratio2 = function(){
				return (cont.getHeight() - cont.scrBar.getHeight()) / (cont.getScrollSize().y - cont.getHeight());
			}
			//if(cont.getScrollSize().y > cont.getHeight()) cont.scrBar.fade(0.1);
			cont.set({
				tween: {
					onComplete: function(el){
						if(cont.getScrollSize().y > cont.getHeight()){
							cont.scrBar.setStyle('top', ratio2() * cont.getScroll().y);
							cont.scrBar.inject(cont).setStyles({
								'width': scrCook.get('width'), 'color': scrCook.get('color')
							}).fade(0.1).makeDraggable({
								limit: {x: [0, 0], y: [0, cont.getHeight() - cont.scrBar.getHeight()]},
								onStart: function(){
									cont.scrBar.scr.cancel();
									cont.scrBar.setStyle('cursor', 'url(/asset/img/cursor/grabdown.png), move');
								},
								onComplete: function(){
									cont.scrBar.scr.start(0, ratio() * (cont.getScrollSize().y - cont.getHeight()));
									cont.scrBar.setStyle('cursor', 'url(/asset/img/cursor/grab.png), move');
								}
							});
						} else {
							cont.scrBar.fade(0);
							cont.scrBar.setStyle('top', 0);
						}
					}
				},
				'events': {
					'mousewheel': function(e){
						var n = e.wheel * 30;
						cont.scrollTo(0, cont.getScroll().y - n);
						cont.scrBar.setStyle('top', ratio2() * cont.getScroll().y);
					}
				}
			});
		});
		window.addEvent('resize', function(){
			$$('.OPEN .mainContainer').each(function(openContainer){
				openContainer.tween('height', window.getHeight() - 36);
			});
			$('mainMenu').tween('left', (window.getWidth() - $('mainMenu').getWidth()) / 4);
		});
		site.caca = new MenuSite({
			menuId: 'mainMenu'
		});
		site.caca.addEvents({
			'onOpen': function(){
				window.fireEvent('resize');
				$$('a').each(function(el){
					el.removeEvents('focus');
					el.addEvent('focus', function(){el.blur();});
				});
			},
			'onBeforeClose': function(i){
				this.frames[i].scrBar.fade(0);
			}
		});
		site.caca.absorb($('TMP'), $('TMP').getFirst().get('title'));
	},
	spinnerURL: '/asset/img/spinner.gif',
	history: []
}
