if(typeof $N == "undefined") {
var $N = {
	initialize: function() {
		if(cssQuery == 'undefined') throw('requires the cssQuery.js');
	}
};
$N.initialize();

$N.element = {
	show: function(selector) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			elements[i].style.display = 'block';
		}
	},
	
	hide: function(selector) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			elements[i].style.display = 'none';
		}
	},
	
	toggle: function(selector) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			elements[i].style.display = (elements[i].style.display == 'none' ? 'block' : 'none');
		}
	},
	
	className: {
		has: function(element, className) {
			if(element.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) return true;
			return false;
		},
		
		add: function(element, className) {
			if(this.has(element, className)) return;
			element.className += ' ' + (className.trim()).clean();
			element.className = element.className.trim();
		},
		
		remove: function(element, className) {
			if(!this.has(element, className)) return;
			element.className = element.className.replace(className.trim(), '').clean();
		},
		
		toggle: function(element, className) {
			if(this.has(element, className)) this.remove(element, className);
			else this.add(element, className);
		}
	},
	
	addClass: function(selector, className) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			this.className.add(elements[i], className);
		}
	},
	
	removeClass: function(selector, className) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			this.className.remove(elements[i], className);
		}
	},
	
	toggleClass: function(selector, className) {
		var elements = cssQuery(selector);
		for(var i=0; i<elements.length; i++) {
			this.className.toggle(elements[i], className);
		}
	}
};

new function() {
	var e = ('blur,focus,load,resize,scroll,unload,click,dblclick,' + 
			 'mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select,' + 
			 'submit,keydown,keypress,keyup,error').split(',');
	for(var i=0; i<e.length; i++) new function() {
		var handler = e[i];
		$N.element[handler] = function(obj, fn) { $N.event.addEvent(obj, handler, fn) };
	}
};


$N.event = {
	/**
	 * onContent
	 * (C)webreflection.blogspot.com
	 */
	onDomReady: function(f){
		var a,b=navigator.userAgent,d=document,w=window,
		c="__onContent__",e="addEventListener",o="opera",r="readyState",
		s="<scr".concat("ipt defer src='//:' on",r,"change='if(this.",r,"==\"complete\"){this.parentNode.removeChild(this);",c,"()}'></scr","ipt>");
		w[c]=(function(o){return function(){w[c]=function(){};for(a=arguments.callee;!a.done;a.done=1)f(o?o():o)}})(w[c]);
		if(d[e]&&!/MSIE.+Win/i.test(b)) this.addEvent(d, "DOMContentLoaded", w[c], false)
		if(/WebKit|Khtml/i.test(b)||(w[o]&&parseInt(w[o].version())<9))
		(function(){/loaded|complete/.test(d[r])?w[c]():setTimeout(arguments.callee,1)})();
		else if(/MSIE.+Win/i.test(b))d.write(s);
		else if(/MSIE 5.+Mac/i.test(b)) this.onLoad(f);
	},
	
	onLoad: function(fn) { this.addEvent(window, 'load', fn); },
	
	/**
	 * addEvent
	 * http://ejohn.org/projects/flexible-javascript-events/
	 */
	addEvent: function( obj, type, fn ) {
		if (obj.addEventListener) {
			obj.addEventListener( type, fn, false );
			this.eventCache.add(obj, type, fn);
		} else if (obj.attachEvent) {
			obj["e"+type+fn] = fn;
			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
			obj.attachEvent( "on"+type, obj[type+fn] );
			this.eventCache.add(obj, type, fn);
		} else {
			var prev = obj['on' + type];
			obj['on' + type] = prev ? function() { prev(); fn() } : fn;
		}
	},
	
	removeEvent: function( obj, type, fn ) {
		if (obj.removeEventListener)
			obj.removeEventListener( type, fn, false );
		else if (obj.detachEvent) {
			obj.detachEvent( "on"+type, obj[type+fn] );
			obj[type+fn] = null;
			obj["e"+type+fn] = null;
		}
	},
	
	stop: function(event) {
		if (event.preventDefault) { 
			event.preventDefault(); 
			event.stopPropagation(); 
		} else {
			event.returnValue = false;
			event.cancelBubble = true;
		}
	},
	
	/**
	 * EventCache Version 1.0
	 * Copyright 2005 Mark Wubben
	 * This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
	 */
	eventCache: function(){
		var listEvents = [];
		return {
			listEvents : listEvents,
			add : function(node, sEventName, fHandler){
				listEvents.push(arguments);
			},
			flush : function(){
				var i, item;
				for(i = listEvents.length - 1; i >= 0; i = i - 1){
					item = listEvents[i];
					if(item[0].removeEventListener){
						item[0].removeEventListener(item[1], item[2], item[3]);
					};
					if(item[1].substring(0, 2) != "on"){
						item[1] = "on" + item[1];
					};
					if(item[0].detachEvent){
						item[0].detachEvent(item[1], item[2]);
					};
					item[0][item[1]] = null;
				};
			}
		};
	}()
};
$N.event.addEvent(window, 'unload', $N.event.eventCache.flush);
}

String.prototype.trim = function() {
	return this.replace(/^\s*|\s*$/g, '');
}

String.prototype.clean = function() {
	return this.replace(/\s\s/g, ' ').trim();
}

