/* -------------------------------------------------------------------------- */
/** 
 *    @fileoverview
 *       Common Script Libraries.
 *
 *    @version rev002 2009/10/4
 */
/* -------------------------------------------------------------------------- */

/*@cc_on _d=document;eval('var document=_d')@*/
window.undefined = window.undefined;

var CWJ;
var CWJ_STATUSMSG;



/* ============================== Common preparations ============================== */

/* --------------- Constructor : CWJEnvironment --------------- */

function CWJEnvironment() {
	this.debugMode = false;
	this.except = {};
	this.except.MacIE   = false;
	this.except.WinIE50 = false;
	this.except.WinIE55 = false;

	var d  = document;
	var di = d.implementation;
	var de = d.documentElement;
	var ua = navigator.userAgent;
	var lp = location.protocol;
	var lh = location.hostname;

	this.url = {};
	this.url.commonDir = CWJGetCommonDir('common') || CWJGetCommonDir('shared');
	this.url.imgDir    = this.url.commonDir + 'img/';
	this.url.cssDir    = this.url.commonDir + 'css/';
	this.url.jsDir     = this.url.commonDir + 'js/';

	this.ns = {};
	this.ns.defaultNS  = (de && de.namespaceURI) ? de.namespaceURI : (de && de.tagUrn) ? de.tagUrn : '';
	this.ns.xhtml1     = 'http://www.w3.org/1999/xhtml';
	this.ns.xhtml2     = 'http://www.w3.org/2002/06/xhtml2';
	this.ns.cwj        = 'urn:cwj';

	this.ua = {};
	this.ua.isGecko    = /Gecko\//    .test(ua);
	this.ua.isSafari   = /AppleWebKit/.test(ua);
	this.ua.isOpera    = Boolean(window.opera);
	this.ua.isIE       = (d.all && !this.ua.isGecko && !this.ua.isSafari && !this.ua.isOpera);
	this.ua.isIE40     = (this.ua.isIE && /MSIE 4\.0/.test(ua));     // IE 4.0x
	this.ua.isIE45     = (this.ua.isIE && /MSIE 4\.5/.test(ua));     // IE 4.5x
	this.ua.isIE50     = (this.ua.isIE && /MSIE 5\.0/.test(ua));     // IE 5.0x
	this.ua.isIE55     = (this.ua.isIE && /MSIE 5\.5/.test(ua));     // IE 5.5x
	this.ua.isIE60     = (this.ua.isIE && /MSIE 6\.0/.test(ua));     // IE 6.0x
	this.ua.isIE70     = (this.ua.isIE && /MSIE 7\.0/.test(ua));     // IE 7.0x
	this.ua.isIE80     = (this.ua.isIE && /MSIE 8\.0/.test(ua));     // IE 8.0x
	this.ua.isNN4      = Boolean(d.layers);                          // NN 4.x
	this.ua.isMac      = /Mac/.test(ua);
	this.ua.isWin      = /Win/.test(ua);
	this.ua.isWinIE    = (this.ua.isWin && this.ua.isIE);
	this.ua.isMacIE    = (this.ua.isMac && this.ua.isIE);
	this.ua.isWinIEQM  = this.ua.isWinIE && (!document.compatMode || document.compatMode == 'BackCompat');
	this.ua.IEDocMode  = (this.ua.isIE   &&  d.documentMode   ) ? d.documentMode :
	                     (this.ua.isIE70 && !this.ua.isWinIEQM) ? 7              :
	                     (this.ua.isIE60 && !this.ua.isWinIEQM) ? 6              :
	                     (                   this.ua.isWinIEQM) ? 5              :
	                                                              0              ;
	this.ua.isDOMReady = (this.except.MacIE   && this.ua.isMacIE                  ) ? false                        :
	                     (this.except.WinIE50 && this.ua.isWinIE && this.ua.isIE50) ? false                        :
	                     (this.except.WinIE55 && this.ua.isWinIE && this.ua.isIE55) ? false                        :
	                     (di                                                      ) ? di.hasFeature('HTML', '1.0') :
	                                                                                  (this.ua.isIE && de)         ;
	this.ua.revision   = (this.ua.isIE    ) ? parseFloat(ua.match(/MSIE ([\d\.]+)/)[1])         :
	                     (this.ua.isGecko ) ? parseFloat(ua.match(/; rv:([\d\.]+)/)[1])         :
	                     (this.ua.isSafari) ? parseFloat(ua.match(/AppleWebKit\/([\d\.]+)/)[1]) :
	                     (this.ua.isOpera ) ? parseFloat(ua.match(/Opera.([\d\.]+)/)[1])        :
	                                          0                                                 ;

	this.env = {};
	this.env.isOnline   = (lp == 'http:' || lp == 'https:');
	this.env.referer    = (typeof document.referrer == 'string') ? document.referrer : '';
	this.env.isDOMReady = false;
}



/* --------------- EventHandler : window.onerror --------------- */

window.onerror = function(message, fileName, lineNumber) {
	if (typeof CWJ == 'object') {
		if (CWJ.debugMode) {
			var msg = 'Error: ' + message  + '\n' +
			          'File: '  + fileName + '\n' + 
			          'Line: '  + lineNumber;
			alert(msg);
		}
		return true;
	}
}



/* ==================== Custom methods / Shortage methods of built-in objects ==================== */

/* ----- Function.apply() ----- */

if (!window.encodeURIComponent) {
	window.encodeURIComponent = function(str) {
		return escape(str);
	}
}



/* ----- Function.apply() ----- */

if (!Function.prototype.apply) {
	Function.prototype.apply = function(aThisObject, anArray) {
		if (typeof anArray != 'null' && typeof anArray != 'undefined' && typeof anArray != 'object') {
			throw 'Function.apply: second argument must be an array.';
		} else {
			if (typeof aThisObject != 'object' || !aThisObject) {
				aThisObject = window;
			}
			if (!anArray) {
				anArray = [];
			}
			var prop = '__Function_Apply_stored__';
			var args = [];
			for (var i = 0, n = anArray.length; i < n; i++) {
				args.push('anArray[' + i + ']');
			}

			aThisObject[prop] = this;
			var ret = eval('aThisObject.' + prop + '(' + args.join(',') + ')');
			try {
				delete aThisObject[prop];
			} catch(err) {
				aThisObject[prop] = null;
			}
			return ret;
		}
	}
}

/* ----- Function.call() ----- */

if (!Function.prototype.call) {
	Function.prototype.call = function(aThisObject /* , arg1, arg2 ... */) {
		var args = [];
		for (var i = 1, n = arguments.length; i < n; i++) {
			args.push(arguments[i]);
		}
		return this.apply(aThisObject, args);
	}
}

/* ----- Array.pop() ----- */

if (!Array.prototype.pop) {
	Array.prototype.pop = function() {
		if (!this.length) {
			return null;
		} else {
			var last = this[this.length - 1];
			--this.length;
			return last;
		}
	}
}

/* ----- Array.push() ----- */

if (!Array.prototype.push) {
	Array.prototype.push = function(args) {
		for (var i = 0, n = arguments.length; i < n; i++) {
			this[this.length] = arguments[i];
		}
		return this.length;
	}
}

/* ----- Array.shift() ----- */

if (!Array.prototype.shift) {
	Array.prototype.shift = function() {
		if (!this.length) {
			return null;
		} else {
			this.reverse();
			var ret = this.pop();
			this.reverse();
			return ret;
		}
	}
}

/* ----- Array.unshift() ----- */

if (!Array.prototype.unshift) {
	Array.prototype.unshift = function(args) {
		this.reverse();
		for (var i = arguments.length - 1; i >= 0; i--) {
			this.push(arguments[i]);
		}
		this.reverse();
		return this.length;
	}
}

/* ----- Array.splice() ----- */

if (!Array.prototype.splice) {
	Array.prototype.splice = function(index, howMany /* , element1, element2 ... */) {
		index     = (index < 0) ? Math.max(index + this.length, 0) : Math.min(index, this.length);
		howMany   = Math.min(Math.max(howMany || this.length, 0), this.length - index);
		var left  = this.slice(0, index);
		var right = this.slice(index + howMany);
		var ret   = this.slice(index, index + howMany);
		Array.prototype.slice.call(arguments, 2).forEach(function(item) { left.push(item) });
		this.length = 0;
		this.push.apply(this, left );
		this.push.apply(this, right);
		return ret;
	}
}

/* ----- Array.indexOf() ----- */

if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(aSearchElement, aFromIndex) {
		if (typeof aFromIndex != 'number') {
			aFromIndex = 0;
		} else if (aFromIndex < 0) {
			aFromIndex = this.length + aFromIndex;
		}
		for (var i = aFromIndex, n = this.length; i < n; i++) {
			if (this[i] === aSearchElement) {
				return i;
			}
		}
		return -1;
	}
}

/* ----- Array.lastIndexOf() ----- */

if (!Array.prototype.lastIndexOf) {
	Array.prototype.lastIndexOf = function(aSearchElement, aFromIndex) {
		if (typeof aFromIndex != 'number') {
			aFromIndex = this.length - 1;
		} else if (aFromIndex < 0) {
			aFromIndex = this.length + aFromIndex;
		}
		for (var i = aFromIndex; i >= 0; i--) {
			if (this[i] === aSearchElement) {
				return i;
			}
		}
		return -1;
	}
}

/* ----- Array.forEach() ----- */

if (!Array.prototype.forEach) {
	Array.prototype.forEach = function(aCallBack, aThisObject) {
		for (var i = 0, n = this.length; i < n; i++) {
			aCallBack.call(aThisObject, this[i], i, this);
		}
	}
}

/* ----- Array.map() ----- */

if (!Array.prototype.map) {
	Array.prototype.map = function(aCallBack, aThisObject) {
		var ret = [];
		for (var i = 0, n = this.length; i < n; i++) {
			ret.push(aCallBack.call(aThisObject, this[i], i, this));
		}
		return ret;
	}
}

/* ----- Array.filter() ----- */

if (!Array.prototype.filter) {
	Array.prototype.filter = function(aCallBack, aThisObject) {
		var ret = [];
		for (var i = 0, n = this.length; i < n; i++) {
			if (aCallBack.call(aThisObject, this[i], i, this)) {
				ret.push(this[i]);
			}
		}
		return ret;
	}
}

/* ----- Array.some() ----- */

if (!Array.prototype.some) {
	Array.prototype.some = function(aCallBack, aThisObject){
		for (var i = 0, n = this.length; i < n; i++) {
			if (aCallBack.call(aThisObject, this[i], i, this)) return true;
		}
		return false;
	}
}

/* ----- Array.every() ----- */

if (!Array.prototype.every) {
	Array.prototype.every = function(aCallBack, aThisObject){
		for (var i = 0, n = this.length; i < n; i++) {
			if(!aCallBack.call(aThisObject, this[i], i, this)) return false;
		}
		return true;
	}
}

/* ----- Array.equal() ----- */

if (!Array.prototype.equal) {
	Array.prototype.equal = function(anArray) {
		if (!anArray || this.length != anArray.length) {
			return false;
		} else {
			return this.every(function(value, i) {
				return (value === anArray[i]);
			});
		}
	}
}

/* ----- Number.formatNumberCWJ() ----- */

Number.prototype.formatNumberCWJ = function(format) {
	if (!format || typeof format != 'string') {
		throw 'Number.formatNumberCWJ: first argument must be a formatting string.';
	} else {
		var ret       = [];
		var intFormat = format.split('.')[0].split('');
		var decFormat = format.split('.')[1] || '';
		var value     = (decFormat) ? Math.abs(this) : Math.round(Math.abs(this));
		var sign      = (this < 0) ? '-' : '';
		var intValue  = value.toString().split('.')[0].split('');
		do {
			var _value  = intValue .pop() || '';
			var _format = intFormat.pop() || '';
			switch (_format) {
				case '0' : ret.push(_value  ? _value : '0');                        break;
				case '#' : ret.push(_value  ? _value : '' );                        break;
				case ''  : /* exit do-while loop */          intValue = [];         break;
				default  : ret.push(_format               ); intValue.push(_value); break;
			}
		} while (intValue.length > 0 || intFormat.length > 0);
		ret = ret.reverse().join('').replace(/^\D+/, '');
		if (decFormat) {
			var scale     = Math.pow(10, decFormat.length);
			var rounded   = Math.round(value * scale) / scale;
			if (rounded - ret == 1) {
				ret++;
			}
			var decValue  = rounded.toString().split('.')[1] || '0';
			    decValue  = decValue .split('').reverse().join('');
			    decFormat = decFormat.split('').reverse().join('');
			    ret       = ret + '.' + decValue.formatNumberCWJ(decFormat).split('').reverse().join('');
		}
		if (decFormat.startsWithCWJ('#') && ret.endsWithCWJ('.0')) {
			ret = ret.getBeforeCWJ('.0');
		}
		return sign + ret;
	}
}

/* ----- String.formatNumberCWJ() ----- */

String.prototype.formatNumberCWJ = function(format) {
	var num = parseFloat(this, 10);
	if (isNaN(num)) {
		throw 'String.formatNumberCWJ: this string is not a number string.';
	} else {
		return num.formatNumberCWJ(format);
	}
}

/* ----- String.formatTextCWJ() ----- */

String.prototype.formatTextCWJ = function(strArray) {
	var str = this;
	if (strArray && strArray.constructor == Array) {
		for (var i = 0, n = strArray.length; i < n; i++) {
			str = str.replace(new RegExp('\\$\\{' + i + '\\}', 'g'), strArray[i]);
		}
	}
	return str;
}

/* ----- String.getBeforeCWJ() ----- */

String.prototype.getBeforeCWJ = function(str, include) {
	if (typeof str != 'string') {
		throw 'String.getBeforeCWJ: first argument must be a string.';
	} else if (!str) {
		return this;
	} else {
		var idx = this.indexOf(str);
		return (idx == -1) ? '' : this.substring(0, idx) + (include ? str : '');
	}
}

/* ----- String.getAfterCWJ() ----- */

String.prototype.getAfterCWJ = function(str, include) {
	if (typeof str != 'string') {
		throw 'String.getAfterCWJ: first argument must be a string.';
	} else if (!str) {
		return this;
	} else {
		var idx = this.indexOf(str);
		return (idx == -1) ? '' : (include ? str : '') + this.substring(idx + str.length, this.length);
	}
}

/* ----- String.startsWithCWJ() ----- */

String.prototype.startsWithCWJ = function(str) {
	return (this.indexOf(str) == 0);
}

/* ----- String.endsWithCWJ() ----- */

String.prototype.endsWithCWJ = function(str) {
	var idx = this.lastIndexOf(str);
	return (idx > -1 && idx + str.length == this.length);
}

/* ----- String.relToAbsCWJ() ----- */

String.prototype.relToAbsCWJ = function(base) {
	var b   = base.split('/');
	var t   = this.split('/');
	var ptn = /^(\/|\w+:)/;
	if (!base.match(ptn)) {
		throw 'String.relToAbsCWJ: first argument must be an absolute path/URL.';
	} else if (this.match(ptn)) {
		return this;
	} else if (this.charAt(0) == '#' || this.charAt(0) == '?') {
		return base + this;
	} else if (t[0] == '.' || t[0] == '..') {
		return t.slice(1, t.length).join('/').relToAbsCWJ(b.slice(0, b.length - t[0].length).join('/') + '/');
	} else {
		return b.slice(0, b.length - 1).join('/') + '/' + this;
	}
}

/* ----- String.absToRelCWJ() ----- */

String.prototype.absToRelCWJ = function(base) {
	var ptn = /^(\/|\w+:)/;
	if (!base.match(ptn)) {
		throw 'String.absToRelCWJ: first argument must be an absolute path/URL.';
	} else if (!this.match(ptn)) {
		throw 'String.absToRelCWJ: String must be an absolute path/URL.';
	} else {
		return _compare(base, this) || base;
	}

	function _compare(base, trgt) {
		var b = base.split('/');
		var t = trgt.split('/');
		if (!base) {
			return trgt;
		} else if (!trgt) {
			return _goup(base);
		} else if (b[0] != t[0]) {
			return _goup(base) + trgt;
		} else {
			return arguments.callee(b.slice(1, b.length).join('/'), t.slice(1, t.length).join('/'));
		}
	}
	
	function _goup(path) {
		path = path.split('/');
		path.shift();
		path.forEach(function(elem, idx) { path[idx] = '..' });
		return path.join('/') + '/';
	}
}

/* ----- String.getSanitizedStringCWJ() ----- */

String.prototype.getSanitizedStringCWJ = function() {
	var pairs = {
		  '&'      : '&amp;'
		, '<'      : '&lt;'
		, '>'      : '&gt;'
		, '\u0022' : '&quot;'
		, '\u0027' : '&apos;'
	};
	var ret = this;
	for (var key in pairs) {
		ret = ret.replace(new RegExp(key, 'g'), pairs[key]);
	}
	return ret;
}






/* ==================== Custom DOM methods for built-in DOM objects ==================== */

/* ---------- Constructor : CWJDOM (Abstract Class) ---------- */

function CWJDOM() {
	this.instanceOf = 'CWJElement';
}

/* ----- CWJDOM.addEventListenerCWJ() ----- */

CWJDOM.prototype.addEventListenerCWJ = function(type, listener, aThisObject) {
	// preparations.
	if (!type || typeof type != 'string') {
		throw 'CWJDOM.addEventListenerCWJ: first argument must be a string (event type).';
	} else if (!listener || typeof listener != 'function') {
		throw 'CWJDOM.addEventListenerCWJ: second argument must be a function (event listener).';
	} else if (CWJ.ua.isOpera && CWJ.ua.revision < 9.02 && type == 'mousewheel') {
		// Opera before 9.02 has a bug on 'mousewheel' event (user cannot scroll-up by mousewheel).
		return;
	}

	var pType = type;  // 'pseudo event type name'
	switch (pType) {
		case 'mousewheel' : if (CWJ.ua.isGecko) type = 'DOMMouseScroll'; break;
		case 'mouseenter' :                    type = 'mouseover'     ; break;
		case 'mouseleave' :                    type = 'mouseout'      ; break;
		default           :                                           ; break;
	}

	// create event caller.
	if (!this.__callListenersCWJ__) {
		this.__callListenersCWJ__ = function(e) {
			var _this = arguments.callee;
			if (CWJ.ua.isIE) {
				var _e = e || window.event;
				e = {};
				var _de = document.documentElement;
				var _db = document.body;
				e.currentTarget = _this.node;
				if (_e) {
					e.type            = _e.type;
					e.target          = _e.srcElement;
					e.relatedTarget   = (_e.srcElement == _e.toElement) ? _e.fromElement : _e.toElement;
					e.clientX         = _e.clientX;
					e.clientY         = _e.clientY;
					e.pageX           = (_de.scrollLeft ? _de.scrollLeft : (_db ? _db.scrollLeft : 0)) + _e.clientX;
					e.pageY           = (_de.scrollTop  ? _de.scrollTop  : (_db ? _db.scrollTop  : 0)) + _e.clientY;
					e.charCode        = /* (this.type == 'keypress') ? */ _e.keyCode /* : 0 */;
					e.keyCode         = /* (this.type != 'keypress') ? */ _e.keyCode /* : 0 */;
					e.ctrlKey         = _e.ctrlKey;
					e.shiftKey        = _e.shiftKey;
					e.altKey          = _e.altKey;
					e.metaKey         = _e.metaKey;
					e.detail          = _e.detail;
					e.wheelDelta      = _e.wheelDelta;
					e.stopPropagation = function() { _e.cancelBubble = true  };
					e.preventDefault  = function() { _e.returnValue  = false };
				}
			}

			if (e.target && e.target.nodeType == 3 && CWJ.ua.isSafari) {
				// in earlier Safari (before 2.0?), a text node is treated as 'event target'...
				e.target.parentNode.dispatchEvent(e);
			} else {
				// append custom DOM methods.
				if (typeof CWJ == 'object' && typeof CWJRegisterDOMMethodsTo == 'function') {
					CWJRegisterDOMMethodsTo(e.target);
					CWJRegisterDOMMethodsTo(e.currentTarget);
					CWJRegisterDOMMethodsTo(e.relatedTarget);
				}

				// preventDefault() doesn't work on Safari before 2.0.4...
				if (CWJ.ua.isSafari && CWJ.ua.revision < 412) {
					e.preventDefault = function() { this.currentTarget['on' + this.type] = function() { return false } };
				}

				// iterate calling listeners
				(_this.listeners[e.type] || []).filter(function(_listener) {
					var _rel   = e.relatedTarget;
					var _pType = _listener.pseudoType;
					switch (_pType) {
						case 'mouseenter' : return (_rel && _this.node != _rel && !_this.node.isAncestorOfCWJ(_rel));
						case 'mouseleave' : return (_rel && _this.node != _rel && !_this.node.isAncestorOfCWJ(_rel));
						case 'mousewheel' : if (e.type == 'DOMMouseScroll') { e.wheelDelta = e.detail * -40 } return true;
						default           : return true;
					};
				}).forEach(function(_listener) {
					_listener.func.call(_listener.aThisObject, e);
				});
			}
		}
		this.__callListenersCWJ__.node      = this;
		this.__callListenersCWJ__.listeners = {};
	}

	// register an event handler as the trigger to call registered all event listeners.
	if (!this.__callListenersCWJ__.listeners[type]) {
		this.__callListenersCWJ__.listeners[type] = [];

		if (this.addEventListener) {
			// standard compliant browsers
			if (this == window && type == 'load' && CWJ.ua.isSafari && CWJ.ua.revision >= 412) {
				// create pseudo 'DOMContentLoaded' event for Safari2.0 or greater
				var timer = new CWJSetInterval(function() {
					if (document.readyState == 'loaded' || document.readyState == 'complete') {
						timer.clearTimer();
						window.__callListenersCWJ__({ type : 'load', target : window, currentTarget : window });
					}
				}, 100);
			} else {
				// other events
				this.addEventListener(type, this.__callListenersCWJ__, false);
			}
		} else if (this.attachEvent) {
			// WinIE
			if (type == 'load' && this.window == window) {
				// create pseudo 'DOMContentLoaded' event
				var tag = new CWJTag('script');
				tag.setAttributeCWJ('type' , 'text/javascript');
				tag.setAttributeCWJ('src'  , '//:'  );
				tag.setAttributeCWJ('defer', 'defer');
				tag.setAttributeCWJ('id'   , '__addEventListenerCWJ_readyDetector__');
				tag.appendChildCWJ('');
				document.write(tag);
				document.getElementByIdCWJ('__addEventListenerCWJ_readyDetector__').addEventListenerCWJ('readystatechange', function() {
					if (this.readyState == 'complete') {
						window.__callListenersCWJ__({ type : 'load', target : window, currentTarget : window });
						this.parentNode.removeChild(this);
					}
				});
			} else {
				// other events
				this.attachEvent('on' + type, this.__callListenersCWJ__);
			}
		} else {
			// old browsers (typically for MacIE)
			var inhabitant = this['on' + type];
			if (inhabitant) {
				this.__callListenersCWJ__.listeners[type].push({ func : inhabitant, aThisObject : this });
			}
			this['on' + type] = this.__callListenersCWJ__;
		}
	}

	// register event listener.
	this.__callListenersCWJ__.listeners[type].push({ func : listener, aThisObject : aThisObject || this, pseudoType : pType });

	// preparations for CWJCleanUpEventListeners()
	var nodes = window.CWJ_EVENTLISTENER_STORED_NODES;
	if (!nodes) {
		nodes = window.CWJ_EVENTLISTENER_STORED_NODES = [];
	}
	if (nodes.indexOf(this) == -1) {
		nodes.push(this);
	}
}



/* ----- CWJDOM.removeEventListenerCWJ() ----- */

CWJDOM.prototype.removeEventListenerCWJ = function(type, listener, aThisObject) {
	// preparations.
	if (!type || typeof type != 'string') {
		throw 'CWJDOM.removeEventListenerCWJ: first argument must be a string (event type).';
	} else if (!listener || typeof listener != 'function') {
		throw 'CWJDOM.removeEventListenerCWJ: second argument must be a function (event listener).';
	} else if (CWJ.ua.isGecko && type == 'mousewheel') {
		type = 'DOMMouseScroll';
	}

	// remove event listener.
	if (!aThisObject) {
		aThisObject = this;
	}

	var listeners;
	if (this.__callListenersCWJ__ && (listeners = this.__callListenersCWJ__.listeners[type])) {
		this.__callListenersCWJ__.listeners[type] = listeners.filter(function(_listener) {
			return (_listener.func !== listener || _listener.aThisObject !== aThisObject);
		});
	}
}



/* ----- CWJDOM.dispatchEventCWJ() ----- */

CWJDOM.prototype.dispatchEventCWJ = function(e) {
	if (!e || typeof e != 'object') {
		throw 'CWJDOM.dispatchEventCWJ: first argument must be an Event object.';
	} else if (this.dispatchEvent) {
		this.dispatchEvent(e);
	} else if (this.fireEvent) {
		this.fireEvent('on' + e.type);
	} else if (this['on' + e.type]) {
		this['on' + e.type]();
	}
}



/* ---------- Constructor : CWJWindow (Abstract Class) inherits CWJDOM ---------- */

function CWJWindow() { }

CWJWindow.prototype = new CWJDOM;



/* ---------- Constructor : CWJDocument (Abstract Class) inherits CWJDOM ---------- */

function CWJDocument() { }

CWJDocument.prototype = new CWJDOM;

CWJDocument.prototype.getElementsByTagNameCWJ = function(tagName) {
	var ret = [];
	if (!tagName || typeof tagName != 'string') {
		throw 'CWJDocument.getElementsByTagNameCWJ: first argument must be a string (tagName).';
	} else if (tagName == '*') {
		ret = this.getElementsByTagName(tagName);
		if (CWJ.ua.isIE || ret.length == 0) {
			ret = (document.all && this === document) ?
                  	document.all :
                  	(function(_node) {
                  		var _nodes = _node.childNodes;
                  		var _ret   = [];
                  		for (var i = 0, n = _nodes.length; i < n; i++) {
                  			var __node = _nodes[i];
                  			if (__node.nodeType == 1 && __node.nodeName != '!') {
                  				_ret.push(__node);
                  			}
                  			_ret = _ret.concat(arguments.callee(__node));
                  		}
                  		return _ret;
                  	})(this);
		}
	} else if (tagName.indexOf(':') > -1) {
		var prfx = tagName.split(':')[0];
		var name = tagName.split(':')[1];
		     ret = (CWJ.ns.defaultNS && this.getElementsByTagNameNS) ?
		           	this.getElementsByTagNameNS(CWJ.ns[prfx], name) :
		           	this.getElementsByTagName(tagName) ;
		if (ret.length == 0) {
			       ret = (name == '*') ? this.getElementsByTagNameCWJ(name) : this.getElementsByTagName(name);
			var _nodes = [];
			for (var i = 0, n = ret.length; i < n; i++){
				var _node = ret[i];
				if (CWJ.ns.defaultNS && _node.namespaceURI == CWJ.ns[prfx] || _node.tagUrn == CWJ.ns[prfx]) {
					_nodes.push(_node);
				}
			}
			if (_nodes.length == 0) {
				       ret = (name == '*') ? ret : this.getElementsByTagNameCWJ('*');
				var _nodes = [];
				for (var i = 0, n = ret.length; i < n; i++) {
					var _node = ret[i];
					var _prfx = _node.nodeName.split(':')[0];
					var _name = _node.nodeName.split(':')[1];
					if (_name && _prfx == prfx && (name == '*' || _name.toLowerCase() == name.toLowerCase())) {
						_nodes.push(_node);
					}
				}
			}
			ret = _nodes;
		}
	} else {
		ret = (CWJ.ns.defaultNS && this.getElementsByTagNameNS) ?
		      	this.getElementsByTagNameNS(CWJ.ns.defaultNS, tagName) :
		      	(tagName.match(/^body$/i) && document.body) ?
		      		/* workaround for Netscape7.1 */ [document.body] :
		      		this.getElementsByTagName(tagName) ;
		if (typeof document.documentElement.tagUrn == 'string') {
			var _nodes = [];
			for (var i = 0, n = ret.length; i < n; i++){
				var _node = ret[i];
				if (!_node.tagUrn || _node.tagUrn == CWJ.ns.defaultNS) {
					_nodes.push(_node);
				}
			}
			ret = _nodes;
		}
	}

	if (ret.constructor != Array) {
		ret = CWJConcatNodeList(ret);
	}
	ret.forEach(CWJRegisterDOMMethodsTo);
	return ret;
}

/* ----- CWJDocument.getElementsByClassNameCWJ() ----- */

CWJDocument.prototype.getElementsByClassNameCWJ = function(className, tagName) {
	if (!className || typeof className != 'string') {
		throw 'CWJDocument.getElementsByClassNameCWJ: first argument must be a string (className).';
	} else if (tagName && typeof tagName != 'string') {
		throw 'CWJDocument.getElementsByClassNameCWJ: second argument must be a string (tagName).';
	} else if (this.getElementsByClassName && (!tagName || tagName.indexOf(':') == -1)) {
		var ret = Array.prototype.filter.call(this.getElementsByClassName(className), function(node) {
			return (!tagName || node.nodeName.toLowerCase() == tagName.toLowerCase())
		});
		ret.forEach(CWJRegisterDOMMethodsTo);
		return ret;
	} else {
		return this.getElementsByTagNameCWJ(tagName || '*').filter(function(node) {
			return node.hasClassNameCWJ(className);
		});
	}
}

/* ----- CWJDocument.getElementsByNameCWJ() ----- */

CWJDocument.prototype.getElementsByNameCWJ = function(name) {
	if (!name || typeof name != 'string') {
		throw 'CWJDocument.getElementsByNameCWJ: first argument must be a string (name attribute).';
	} else {
		var ret = document.getElementsByName(name);
		if (ret.constructor != Array) {
			ret = CWJConcatNodeList(ret);
			if (CWJ.ua.isWinIE) {
				var _nodes = ret;
				ret = [];
				for (var i = 0, n = _nodes.length; i < n; i++) {
					if (_nodes[i].getAttributeCWJ('name') == name) {
						ret.push(_nodes[i]);
					}
				}
			}
		}
		ret.forEach(CWJRegisterDOMMethodsTo);
		return ret;
	}
}

/* ----- CWJDocument.getElementByIdCWJ() ----- */

CWJDocument.prototype.getElementByIdCWJ = function(id) {
	if (!id || typeof id != 'string') {
		throw 'CWJDocument.getElementByIdCWJ: first argument must be a string (fragment id).';
	} else {
		return CWJRegisterDOMMethodsTo(document.getElementById(id));
	}
}

/* ----- CWJDocument.createElementCWJ() ----- */

CWJDocument.prototype.createElementCWJ = function(tagName) {
	if (!tagName || typeof tagName != 'string') {
		throw 'CWJDocument.createElementCWJ: first argument must be a string (tagName).';
	} else {
		var node = (CWJ.ns.defaultNS && document.createElementNS && tagName.match(/:/)) ?
		           	document.createElementNS(CWJ.ns[tagName.split(':')[0]], tagName.split(':')[1]) :
		           	(CWJ.ns.defaultNS && document.createElementNS) ?
		           		document.createElementNS(CWJ.ns.defaultNS, tagName) : 
		           		document.createElement(tagName) ;
		return CWJRegisterDOMMethodsTo(node);
	}
}

/* ----- CWJDocument.createDocumentFragmentCWJ() ----- */

CWJDocument.prototype.createDocumentFragmentCWJ = function() {
	if (!document.createDocumentFragment || !CWJ.ua.isMacIE) {
		return CWJRegisterDOMMethodsTo(document.createDocumentFragment());
	} else {
		var node = document.createElementCWJ('ins');
		node.__DOCUMENT_FRAGMENT_CWJ_NODE__ = true;
		return node;
	}
}

/* ----- CWJDocument.isAncestorOfCWJ() ----- */

CWJDocument.prototype.isAncestorOfCWJ = function(node) {
	if (!node || typeof node.nodeType != 'number') {
		throw 'CWJDocument.isAncestorOfCWJ: first argument must be a DOM node.';
	} else {
		var _node = node;
		while ((_node = _node.parentNode)) {
			if (_node === this) return true;
		}
		return false;
	}
}

/* ----- CWJDocument.getStyleSheetsCWJ() ----- */

CWJDocument.prototype.getStyleSheetsCWJ = function() {
	return CWJGetStyleSheets();
}



/* ---------- Constructor : CWJElement (Abstract Class) inherits CWJDocument ---------- */

function CWJElement() { }

CWJElement.prototype = new CWJDocument;

/** this method is unavailable. @private */
CWJElement.prototype.createElementCWJ = function() { }

/** this method is unavailable. @private */
CWJElement.prototype.createDocumentFragmentCWJ = function() { };

/** this method is unavailable. @private */
CWJElement.prototype.getStyleSheetsCWJ = function() { };

/* ----- CWJElement.getAncestorsByTagNameCWJ() ----- */

CWJElement.prototype.getAncestorsByTagNameCWJ = function(tagName) {
	if (!tagName || typeof tagName != 'string') {
		throw 'CWJElement.getAncestorsByTagNameCWJ: first argument must be a string (tagName).';
	} else if (tagName.indexOf(':') > -1) {
		throw 'CWJElement.getAncestorsByTagNameCWJ: namespace handling is not implemented yet.';
	} else {
		var ret  = [];
		var node = this.parentNode;
		while (node && node != document) {
			ret.push(node);
			node = node.parentNode;
		}
		if (tagName != '*') {
			tagName = tagName.toLowerCase();
			ret     = ret.filter(function(node) { return (tagName == node.nodeName.toLowerCase()) });
		}
		ret.forEach(CWJRegisterDOMMethodsTo);
		return ret;
	}
}

/* ----- CWJElement.getAncestorsByClassNameCWJ() ----- */

CWJElement.prototype.getAncestorsByClassNameCWJ = function(className, tagName) {
	if (!className || typeof className != 'string') {
		throw 'CWJElement.getAncestorsByClassNameCWJ: first argument must be a string (className).';
	} else {
		return this.getAncestorsByTagNameCWJ(tagName || '*').filter(function(node) { 
			return node.hasClassNameCWJ(className);
		});
	}
}

/* ----- CWJElement.getParentNodeCWJ() ----- */

CWJElement.prototype.getParentNodeCWJ = function() {
	return CWJRegisterDOMMethodsTo(this.parentNode);
}

/* ----- CWJElement.getChildNodesCWJ() ----- */

CWJElement.prototype.getChildNodesCWJ = function() {
	var ret   = [];
	var nodes = this.childNodes;
	for (var i = 0, n = nodes.length; i < n; i++) {
		ret.push(CWJRegisterDOMMethodsTo(nodes[i]));
	}
	return ret;
}

/* ----- CWJElement.appendChildCWJ() ----- */

CWJElement.prototype.appendChildCWJ = function(content, forceAsHTML) {
	if (typeof content == 'undefined' || typeof content == 'object' && !content) {
		throw 'CWJElement.appendChildCWJ: first argument must be a node or a string or a CWJTag instance.';
	} else if (content.nodeType == 1 || content.nodeType == 3 || content.nodeType == 11) {
		if (content.__DOCUMENT_FRAGMENT_CWJ_NODE__) {
			while (content.hasChildNodes()) {
				this.appendChild(content.firstChild);
			}
			return content;
		} else {
			return this.appendChild(content);
		}
	} else if (content.instanceOf == 'CWJTag' || forceAsHTML) {
		content = content.toString();
		if (document.createRange) {            // Gecko/Safari
			var range = document.createRange();
			range.selectNode(this);
			content = range.createContextualFragment(content); // createContextualFragment() is not standard-DOM?
			this.appendChild(content);
		} else if (this.insertAdjacentHTML) {  // WinIE/MacIE
			this.insertAdjacentHTML('beforeEnd', content);
		} else {                               // Others
			this.innerHTML += content;
		}
		CWJRegisterDOMMethodsTo(this, true);
		return content;
	} else if (content.toString) {
		content  = content.toString();
		var node = document.createTextNode(content);
		if (this.insertAdjacentText) {         // WinIE/MacIE
			this.insertAdjacentText('beforeEnd', content);
			return node;
		} else {                               // Others
			return this.appendChild(node);
		}
	}
}

/* ----- CWJElement.removeChildCWJ() ----- */

CWJElement.prototype.removeChildCWJ = function(node) {
	if (!node || typeof node.nodeType != 'number') {
		throw 'CWJElement.removeChildCWJ: first argument must be a DOM node.';
	} else {
		return CWJRegisterDOMMethodsTo(this.removeChild(node));
	}
}

/* ----- CWJElement.removeAllChildrenCWJ() ----- */

CWJElement.prototype.removeAllChildrenCWJ = function() {
	var ret = [];
	while (this.hasChildNodes()) {
		ret.push(this.removeChildCWJ(this.firstChild));
	}
	return ret;
}

/* ----- CWJElement.isDescendantOfCWJ() ----- */

CWJElement.prototype.isDescendantOfCWJ = function(node) {
	if (!node || typeof node.nodeType != 'number') {
		throw 'CWJElement.isDescendantOfCWJ: first argument must be a DOM node.';
	} else {
		return CWJRegisterDOMMethodsTo(node).isAncestorOfCWJ(this);
	}
}

/* ----- CWJElement.getInnerTextCWJ() ----- */

CWJElement.prototype.getInnerTextCWJ = function(includeAlt) {
	var flag = Boolean(includeAlt);
	var txt  = (flag) ? '' : this.innerText || this.textContent || '';
	if (!txt) {
		var ret = [];
		this.getChildNodesCWJ().forEach(function(node) {
			if (node.hasChildNodes()) {
				ret.push(node.getInnerTextCWJ());
			} else if (node.nodeType == 3) {
				ret.push(node.nodeValue);
			} else if (flag && node.alt) {
				ret.push(node.alt);
			}
		});
		txt = ret.join('');
	}
	return txt.replace(/\s+/g, ' ');
}

/* ----- CWJElement.getAttributeCWJ() ----- */

CWJElement.prototype.getAttributeCWJ = function(attr) {
	if (!attr || typeof attr != 'string') {
		throw 'CWJElement.getAttributeCWJ: first argument must be a string (atribute name).';
	} else {
		if (CWJ.ua.isIE && attr == 'class' && (CWJ.ua.revision < 8 || CWJ.ua.IEDocMode < 8)) {
			attr += 'Name';
		}
		var ret = this.getAttribute(attr);
		if (!ret && this.getAttributeNS && attr.match(/:/)) {
			var prfx = attr.split(':')[0];
			var attr = attr.split(':')[1];
			return this.getAttributeNS(CWJ.ns[prfx], attr)
		}
		return ret;
	}
}

/* ----- CWJElement.setAttributeCWJ() ----- */

CWJElement.prototype.setAttributeCWJ = function(attr, value) {
	if (!attr || typeof attr != 'string') {
		throw 'CWJElement.setAttributeCWJ: first argument must be a string (atribute name).';
	} else if (attr.match(/:/)) {
		var prfx = attr.split(':')[0];
		var attr = attr.split(':')[1];
		if (this.setAttributeNS && this.namespaceURI || CWJ.ua.isSafari) {
			this.setAttributeNS(CWJ.ns[prfx], attr, value);
		} else {
			this.setAttribute('xmlns:' + prfx, CWJ.ns[prfx]);
			this.setAttribute(prfx + ':' + attr, value);
		}
	} else {
		if (CWJ.ua.isIE && attr == 'class' && (CWJ.ua.revision < 8 || CWJ.ua.IEDocMode < 8)) attr += 'Name';
		this.setAttribute(attr, value);
	}
}

/* ----- CWJElement.hasClassNameCWJ() ----- */

CWJElement.prototype.hasClassNameCWJ = function(className) {
	if (!className || typeof className != 'string') {
		throw 'CWJElement.hasClassNameCWJ: first argument must be a string (className).';
	} else if (this.nodeType != 1) {
		return false;
	} else {
		return (this.getAttributeCWJ('class') || '').split(' ').some(function(name) { return (name == className) });
	}
}

/* ----- CWJElement.appendClassNameCWJ() ----- */

CWJElement.prototype.appendClassNameCWJ = function(className) {
	if (!className || typeof className != 'string') {
		throw 'CWJElement.appendClassNameCWJ: first argument must be a string (className).';
	} else if (!this.hasClassNameCWJ(className)) {
		var cname = (this.getAttributeCWJ('class') || '').split(' ');
		cname.push(className);
		this.setAttributeCWJ('class', cname.join(' '));
	}
}

/* ----- CWJElement.removeClassNameCWJ() ----- */

CWJElement.prototype.removeClassNameCWJ = function(className) {
	if (!className || typeof className != 'string') {
		throw 'CWJElement.removeClassNameCWJ: first argument must be a string (className).';
	} else if (this.hasClassNameCWJ(className)) {
		var cname = this.getAttributeCWJ('class').split(' ');
		var index = cname.indexOf(className);
		if (index > -1) {
			cname.splice(index, 1);
			this.setAttributeCWJ('class', cname.join(' '));
		}
	}
}

/* ----- CWJElement.normalizeTextNodeCWJ() ----- */

CWJElement.prototype.normalizeTextNodeCWJ = function(deep) {
	this.getChildNodesCWJ().forEach(function(node) {
		if (node && node.nodeType == 3) {
			node.nodeValue = node.nodeValue.replace(/^\s+/ , '');
			node.nodeValue = node.nodeValue.replace(/\s+$/ , '');
			if (/^\s*$/.test(node.nodeValue)) {  // workaround for Safari2.x
				node.parentNode.removeChild(node);
			}
		} else if (deep && node.nodeType == 1 && node.hasChildNodes()) {
			node.normalizeTextNodeCWJ(deep);
		}
	});
}

/* ----- CWJElement.getAbsoluteOffsetCWJ() ----- */

CWJElement.prototype.getAbsoluteOffsetCWJ = function() {
	var offset = { X : this.offsetLeft, Y : this.offsetTop };
	if (this.offsetParent) {
		var op = CWJRegisterDOMMethodsTo(this.offsetParent).getAbsoluteOffsetCWJ();
		// IE returns wrong value if 'offsetParent block' is position-relative...
		offset.X += op.X;
		offset.Y += op.Y;
	}
	return offset;
}

/* ----- CWJElement.getCurrentStyleCWJ() ----- */

CWJElement.prototype.getCurrentStyleCWJ = function(property, pseudo) {
	if (!property || typeof property != 'string') {
		throw 'CWJElement.getCurrentStyleCWJ: first argument must be a string (property name).';
	} else {
		try {
			var value = (window.getComputedStyle) ?
				window.getComputedStyle(this, pseudo)[property] : (document.defaultView && document.defaultView.getComputedStyle) ? 
					document.defaultView.getComputedStyle(this, pseudo)[property] : (this.currentStyle) ?
					this.currentStyle[property] : '';

			// workaroud for wrong border-width value in WinIE
			var ptn = /^border(.*)Width$/;
			if (ptn.test(property) && this.getCurrentStyleCWJ('border' + property.match(ptn)[1] + 'Style', pseudo) == 'none') {
				value = '0px';
			}
			return value;
		} catch (err) { // netscape 7.0x causes exception above.
			return '';
		}
	}
}

/* ----- CWJElement.setPositionFixedCWJ() ----- */

CWJElement.prototype.setPositionFixedCWJ = function(ignoreX, ignoreY, autoHide) {
	if (this.__setPositionFixedCWJ_applied__) return;
	this.__setPositionFixedCWJ_applied__ = true;

	ignoreX  = Boolean(ignoreX );
	ignoreY  = Boolean(ignoreY );
	autoHide = Boolean(autoHide);

	var reviseLeft = 0;
	var reviseTop  = 0;
	var oDisplay   = this.getCurrentStyleCWJ('display');

	if (CWJ.ua.isWinIE) {
		this.style.display = 'block';
	} else if (CWJ.ua.isMacIE) {
		var paddingLeft = this.getCurrentStyleCWJ('paddingLeft');
		var paddingTop  = this.getCurrentStyleCWJ('paddingTop' );
		if (/px$/.test(paddingLeft)) reviseLeft = -1 * parseFloat(paddingLeft);
		if (/px$/.test(paddingTop )) reviseTop  = -1 * parseFloat(paddingTop );
	}

	this.style.position = (ignoreX || ignoreY || (CWJ.ua.isWinIE && CWJ.ua.revision < 7)) ? 'absolute' : 'fixed';
	this.style.left     = (this.getAbsoluteOffsetCWJ().X + reviseLeft) + 'px';
	this.style.top      = (this.getAbsoluteOffsetCWJ().Y + reviseTop ) + 'px';
	this.style.right    = 'auto';
	this.style.bottom   = 'auto';
	this.style.margin   = '0';
	if (oDisplay) {
		this.style.display = oDisplay;
	}

	var node = this;
	var timer;
	_movePosition();
	window.addEventListenerCWJ('scroll', _movePosition);

	function _movePosition() {
		if (timer) timer.clearTimer();
		var geom = CWJGetGeometry();
		if (!ignoreX && node.style.position == 'absolute') node.style.marginLeft = geom.scrollX + 'px';
		if (!ignoreY && node.style.position == 'absolute') node.style.marginTop  = geom.scrollY + 'px';
		if (autoHide) {
			node.style.visibility = 'hidden'
			timer = new CWJSetTimeout(function() { node.style.visibility = 'visible' }, 100);
		}
	}
}






/* ---------- Constructor : CWJStyleSheet (Abstract Class) ---------- */

function CWJStyleSheet() {
	this.instanceOf = 'CWJStyleSheet';
}

/* ----- CWJStyleSheet.getTitleCWJ() ----- */

CWJStyleSheet.prototype.getTitleCWJ = function() {
	return this.title || this.__CWJStyleTitle__ || '';
}

/* ----- CWJStyleSheet.addRuleCWJ() ----- */

CWJStyleSheet.prototype.addRuleCWJ = function(cssText) {
	if (typeof cssText != 'string' || cssText.indexOf('{') == -1 && cssText.indexOf('{') == -1) {
		throw 'CWJStyle.addRuleCWJ : first argument must be a style rule text.';
	} else {
		var isOldSafari = (CWJ.ua.isSafari && CWJ.ua.revision < 522); /* Safari 2.0.x or ealier */
		if (isOldSafari || (!this.insertRule && !this.addRule)) {
			var style = (CWJ.env.isDOMReady) ? document.createElementCWJ('style') : new CWJTag('style');
			style.setAttributeCWJ('type', 'text/css');
			style.appendChildCWJ(cssText);
			if (CWJ.env.isDOMReady) {
				document.getElementsByTagNameCWJ('head')[0].appendChildCWJ(style);
			} else {
				document.write(style.toString());
			}
		} else if (this.insertRule) {
			// Std DOM. (opera causes crash?)
			this.insertRule(cssText, this.cssRules.length);
		} else if (this.addRule) {
			// IE
			var selector  = cssText.getBeforeCWJ('{');
			var predicate = cssText.getAfterCWJ ('{', true);
			this.addRule(selector, predicate);
		}
	}
}






/* ============================ Common Constructors ============================ */

/* --------------- Constructor : CWJSetTimeout --------------- */

function CWJSetTimeout(func, ms, aThisObject) {

	this.storeIndex  = 0;

	this.timer       = null;

	this.storeName   = 'CWJ_SETTIMEOUT_STOREDFUNC';

	this.removerName = 'CWJ_SETTIMEOUT_STOREDFUNC_REMOVER';

	if (arguments.length) {
		this.storeFunc(func, ms, aThisObject);
	}
}

CWJSetTimeout.prototype = {

	storeFunc : function(func, ms, aThisObject) {
		if (!window[this.storeName]) {
			window[this.removerName] = [];
			window[this.storeName]   = [];
			window[this.storeName].remove = function(_idx) {
				this[_idx] = null;
			};
		}

		this.storeIndex = window[this.storeName].push(CWJCreateDelegate(func, aThisObject));
		this.storeIndex--;
		this.setTimer(ms);
	},

	setTimer : function(ms) {
		var func   = 'window.' + this.storeName + '[' + this.storeIndex + ']()';
		this.timer = (CWJ.ua.isIE) ?
		             	setTimeout(func, ms, 'JScript') : // workaround to the page weaved with vbscript.
		             	setTimeout(func, ms           ) ;
		this.removeFunc(ms);
	},
	
	clearTimer : function() {
		if (this.timer) {
			this.clearTimerMain();
			clearTimeout(window[this.removerName][this.storeIndex]);
			this.timer = null;
			this.removeFunc(0);
		}
	},

	clearTimerMain : function() {
		clearTimeout(this.timer);
	},

	removeFunc : function(delay) {
		var func   = 'window.' + this.storeName + '.remove(' + this.storeIndex + ')';
		    delay += 1000;
		window[this.removerName][this.storeIndex] = (CWJ.ua.isIE) ?
		                                            	setTimeout(func, delay, 'JScript') : // workaround to the page weaved with vbscript.
		                                            	setTimeout(func, delay           ) ;
	}
}



/* --------------- Constructor : CWJSetInterval inherits CWJSetTimeout --------------- */

function CWJSetInterval(func, ms, aThisObject) {

	this.storeName   = 'CWJ_SETINTERVAL_STOREDFUNC';

	this.removerName = 'CWJ_SETINTERVAL_STOREDFUNC_REMOVER';

	if (arguments.length) {
		this.storeFunc(func, ms, aThisObject);
	}
}

CWJSetInterval.prototype = new CWJSetTimeout;

CWJSetInterval.prototype.setTimer = function(ms) {
	var func   = 'window.' + this.storeName + '[' + this.storeIndex + ']()';
	this.timer = (CWJ.ua.isIE) ?
	             	setInterval(func, ms, 'JScript') : // workaround to the page weaved with vbscript.
	             	setInterval(func, ms           ) ;
}


CWJSetInterval.prototype.clearTimerMain = function() {
	clearInterval(this.timer);
}



/* --------------- Constructor : CWJStatusDisplay --------------- */

function CWJStatusDisplay(node, defaultMsg) {

	this.node         = node;

	this.msg          = '';

	this.defaultMsg   = defaultMsg;

	this.delay        = 0;

	this.sustain      = 0;

	this.delayTimer   = null;

	this.sustainTimer = null;
	
	if (CWJSingleton(CWJEnvironment).env.isDOMReady) {
		this.init()
	}
}

CWJStatusDisplay.prototype = {

	init : function() {
		if (!this.node) {
			throw 'CWJStatusDisplay.init: element node as display is not supplied.';
		} else {
			if (typeof this.defaultMsg != 'string') {
				this.setDefaultMsg(this.node.getInnerTextCWJ());
			}
			this.node.removeAllChildrenCWJ();
			this.node.appendChildCWJ('');
			this.unset();
		}
	},

	getDefaultMsg : function() {
		return this.defaultMsg;
	},

	setDefaultMsg : function(msg) {
		if (typeof msg != 'string') {
			throw 'CWJStatusDisplay.setDefaultMsg: first argument must be an string.';
		} else {
			this.defaultMsg = msg;
			return msg;
		}
	},

	set : function(msg, delay, sustain) {
		if (typeof msg != 'string') {
			throw 'CWJStatusDisplay.set: first argument must be an string.';
		} else {
			this.msg     = msg;
			this.delay   = (typeof delay   == 'number' && delay   > 0) ? delay   :  0;
			this.sustain = (typeof sustain == 'number' && sustain > 0) ? sustain :  0;
			if (this.delay > 0) {
				this.delayTimer = new CWJSetTimeout(this.setProcess, this.delay, this);
			} else {
				this.setProcess();
			}
			return msg;
		}
	},

	unset : function() {
		this.clearTimer();
		this.unsetMsg();
	},

	setProcess : function() {
		this.clearTimer();
		if (this.msg) {
			this.setMsg();
			if (this.sustain > 0) {
				this.sustainTimer = new CWJSetTimeout(this.unset, this.sustain, this);
			}
		} else {
			this.unset();
		}
	},

	setMsg : function() {
		if (this.node) {
			this.node.removeAllChildrenCWJ();
			this.node.appendChildCWJ(this.msg);
		}
	},

	unsetMsg : function() {
		if (this.node) {
			this.node.removeAllChildrenCWJ();
			this.node.appendChildCWJ(this.defaultMsg);
		}
	},

	clearTimer : function() {
		if (this.delayTimer  ) this.delayTimer.clearTimer();
		if (this.sustainTimer) this.sustainTimer.clearTimer();
	}
}



/* --------------- Constructor : CWJStatusMsg inherits CWJStatusDisplay --------------- */

function CWJStatusMsg(defaultMsg) {

	this.node         = window.defaultStatus || '';

	this.msg          = '';

	this.defaultMsg   = (typeof defaultMsg == 'string') ? defaultMsg : '';

	this.delay        = 0;

	this.sustain      = 0;

	this.delayTimer   = null;

	this.sustainTimer = null;
}

CWJStatusMsg.prototype = new CWJStatusDisplay;

CWJStatusMsg.prototype.init = function() { }

CWJStatusMsg.prototype.setMsg = function() {
	window.status = this.msg;
}

CWJStatusMsg.prototype.unsetMsg = function() {
	window.status = this.defaultMsg;
}



/* --------------- Constructor : CWJTimer --------------- */

function CWJTimer() { 
	this.reset();
}

CWJTimer.prototype = {

	reset : function() {
		this.startTime = (new Date()).getTime();
	},
	
	getTime : function() {
		return (new Date()).getTime() - this.startTime;
	},

	getSeconds : function() {
		return this.getTime() / 1000;
	}
}



/* --------------- Constructor : CWJTag --------------- */

function CWJTag(tagName, attrs) {

	this.tagName    = tagName;

	this.attributes = attrs || {};

	this.childNodes = [];

	this.instanceOf = 'CWJTag';
}

CWJTag.prototype = {

	setAttributeCWJ : function(attrName, value) {
		this.attributes[attrName] = value;
	},

	appendChildCWJ : function(arg) {
		this.childNodes.push(arg);
	},

	toString : function(debug) {
		var tagOpen    = (debug) ? '&lt;' : '<';
		var tagClose   = (debug) ? '&gt;' : '>';
		var tag        = tagOpen + this.tagName;
		var content    = (this.childNodes.length) ? '' : null;
		for (var i = 0, n = this.childNodes.length; i < n; i++) {
			content += this.childNodes[i].toString(debug);
		}
		for (var attr in this.attributes) {
			tag += ' ' + attr + '="' + this.attributes[attr] + '"';
		}
		tag += (content != null) ?
		       	tagClose + content + tagOpen + '/' + this.tagName + tagClose :
		       	' /' + tagClose;
		return tag;
	}
}



/* -------------------- Constructor : CWJObservable -------------------- */

function CWJObservable() {

	this.callBackChains      = null;

	this.callBackIgnoreLevel = null;
}

CWJObservable.prototype.doCallBack = function(name, /* arg1, arg2, ... */ _arguments) {
	if (!this.callBackChains || !this.callBackChains[name]) {
		return null;
	} else {
		var ret;
		var args = Array.prototype.slice.call(arguments, 1);
		this.callBackChains[name]
			.filter(function(delegate) {
				var level = (this.callBackIgnoreLevel) ? this.callBackIgnoreLevel[name] : 'none';
				switch (level) {
					case 'preserved'  : return  delegate.isDisposableCallBack;
					case 'disposable' : return !delegate.isDisposableCallBack;
					case 'all'        : return  false;
					case 'none'       : return  true;
					default           : return  true;
				}
			}, this)
			.forEach(function(delegate) {
				ret = delegate.apply(null, args);
				delegate.isDisposable = delegate.isDisposableCallBack;
			});
		this.removeDisposableCallBacks(name);
		return ret;
	}
}

CWJObservable.prototype.addCallBack = function(name, func, aThisObject, disposable) {
	if (typeof name != 'string' || name == '') {
		throw 'CWJObservable.addCallBack: argument \'name\' must be a string as callback name.';
	} else if (typeof func != 'function') {
		throw 'CWJObservable.addCallBack: argument \'func\' must be a Function object.';
	} else {
		if (!this.callBackChains) {
			this.callBackChains = {};
		}
		if (!this.callBackChains[name]) {
			this.callBackChains[name] = [];
		}
		var delegate = CWJCreateDelegate(func, aThisObject);
		delegate.isDisposableCallBack = (disposable == 'disposable');
		this.callBackChains[name].push(delegate);
		return delegate;
	}
}

CWJObservable.prototype.removeCallBack = function(name, func, aThisObject) {
	if (typeof name != 'string' || name == '') {
		throw 'CWJObservable.removeCallBack: argument \'name\' must be a string as callback name.';
	} else if (this.callBackChains && this.callBackChains[name]) {
		if (typeof func != 'function') {
			delete this.callBackChains[name];
		} else {
			var obj = (typeof aThisObject == 'object' && aThisObject) ? aThisObject : window;
			this.callBackChains[name] = this.callBackChains[name].filter(function(delegate) {
				return (delegate.func !== func || delegate.aThisObject !== obj);
			});
		}
	}
}

CWJObservable.prototype.removeDisposableCallBacks = function(name) {
	if (!this.callBackChains || !this.callBackChains[name]) {
		return;
	} else {
		this.callBackChains[name] = this.callBackChains[name].filter(function(delegate) {
			return (!delegate.isDisposable);
		});
	}
}

CWJObservable.prototype.ignoreCallBack = function(name, level) {
	if (typeof name != 'string' || name == '') {
		throw 'CWJObservable.ignoreCallBack: argument \'name\' must be a string as callback name.';
	} else {
		if (['all', 'preserved', 'disposable', 'none'].indexOf(level) == -1) {
			level = 'none';
		}
		if (!this.callBackIgnoreLevel) {
			this.callBackIgnoreLevel = {};
		}
		this.callBackIgnoreLevel[name] = level;
	}
}

CWJObservable.prototype.setCallBack = function() { return this.addCallBack.apply(this, arguments) }






/* ======================================== Common Global Functions ======================================== */

/* --------------- Function : CWJRegisterDOMMethodsTo --------------- */

function CWJRegisterDOMMethodsTo(node, deep) {
	var isValidNodeType;
	try { // prevent exception that raises when 'node' is 'div.anonymous-div' contained by the input nodes in Gecko.
		isValidNodeType = (node && (node.nodeType == 1 || node.nodeType == 11));
	} catch(err) {  }
	if (node && node.instanceOf != 'CWJElement' && isValidNodeType) {
		for (var i in CWJElement.prototype) {
			node[i] = CWJElement.prototype[i];
		}
	}
	if (deep === true && deep && node && node.hasChildNodes()) {
		for (var i = 0, n = node.childNodes.length; i < n; i++) {
			arguments.callee(node.childNodes[i], true);
		}
	}
	return node;
}



/* --------------- Function : CWJAddOnload --------------- */

function CWJAddOnload(func, aThisObject) {
	var target = (CWJ.ua.isGecko || CWJ.ua.isOpera) ? document           : window;
	var type   = (CWJ.ua.isGecko)                  ? 'DOMContentLoaded' : 'load';
	target.addEventListenerCWJ(type, func, aThisObject);
}



/* --------------- Function : CWJAddOnunload --------------- */

function CWJAddOnunload(func) {
	var target = (CWJ.ua.isOpera) ? document : window;
	target.addEventListenerCWJ('unload', func);
}



/* --------------- Function : CWJGetCommonDir --------------- */

function CWJGetCommonDir(dirName) {
	var path  = './';
	var nodes = document.getElementsByTagName('head')[0].getElementsByTagName('script');
	for (var i = 0, n = nodes.length; i < n; i++) {
		var arr = nodes[i].src.split('/');
		var idx = arr.indexOf(dirName);
		if (idx != -1) {
			path = arr.slice(0, idx + 1).join('/') + '/';
			break;
		}
	}
	if (!path.match(':')) {   // if path is not absolute url (workaround for IE)
		var base = document.getElementsByTagName('base')[0];
		var burl = (base) ? base.href : location.href;
		if (path.startsWithCWJ('/')) {
			path = burl.match(/^\w+:\/*[^\/]+/)[0] + path;
		} else {
			path = path.relToAbsCWJ(burl);
		}
	}
	return path;
}



/* --------------- Function : CWJGetStyleSheets --------------- */

function CWJGetStyleSheets() {
	var oSheets = document.styleSheets;
	var rSheets = [];

	if (oSheets) {
		for (var i = 0, n = oSheets.length; i < n; i++) {
			rSheets.push(oSheets[i]);
		}
	}

	// workaround for Safari's lack of title property of the styleSheet object.
	if (rSheets.every(function(sheet) { return (sheet.title === null) })) {
		var sheets = [];
		var nodes  = document.getElementsByTagName('link');
		for (var i = 0, n = nodes.length; i < n; i++) {
			var node = nodes[i];
			var rel  = node.rel  || '';
			var href = node.href || '';

			if (/stylesheet$/i.test(rel)) {
				var matched = rSheets.filter(function(sheet) { return (sheet.href == href) })[0];
				if (matched) {
					matched.__CWJStyleTitle__ = node.title;
					sheets.push(matched);
				}
			}
		}
		rSheets = sheets;
	}

	rSheets.forEach(function(sheet) {
		if (sheet.instanceOf != 'CWJStyleSheet') {
			for (var i in CWJStyleSheet.prototype) {
				sheet[i] = CWJStyleSheet.prototype[i];
			}
		}
	});
	return rSheets;
}



/* --------------- Function : CWJGetActiveCSSTitle --------------- */

function CWJGetActiveCSSTitle() {
	var ret = '';
	document.getStyleSheetsCWJ().forEach(function(sheet) {
		try {
			var title = sheet.getTitleCWJ();
		} catch(err) {
			// custom methods of CWJStyleSheets are unavailable in MacIE
			var title = sheet.title;
		}
		if (!ret && title && !sheet.disabled) {
			ret = title;
		}
	});
	return ret;
}



/* --------------- Function : CWJSingleton --------------- */

function CWJSingleton(_constructor) {
	return _constructor.__CWJSingleInstance__ || (_constructor.__CWJSingleInstance__ = new _constructor());
}



/* --------------- Function : CWJCreateDelegate --------------- */

function CWJCreateDelegate(func, aThisObject){
	if (typeof func != 'function') {
		throw 'CWJCreateDelegate: first argument must be a function object.';
	} else {
		var aThisObj = (typeof aThisObject == 'object' && aThisObject) ? aThisObject : window;
		var delegate = function(){
			return func.apply(aThisObj, arguments);
		};
		delegate.func        = func;
		delegate.aThisObject = aThisObj;
		return delegate; 
	}
}



/* --------------- Function : CWJAlreadyApplied --------------- */

function CWJAlreadyApplied(func) {
	if (!CWJ.ua.isDOMReady || func.__CWJAlreadyApplied__) return true;
	func.__CWJAlreadyApplied__ = true;
	return false;
}



/* --------------- Function : CWJConcatNodeList --------------- */

function CWJConcatNodeList() {
	var nodes = [];
	(function(args) {
		for (var i = 0, n = args.length; i < n; i++) {
			var arg = args[i];
			if (!arg) {
				continue;
			} else if (arg.nodeType == 1) {
				nodes.push(arg);
			} else if (arg.length > 0) {
				arguments.callee(arg);
			}
		}
	})(arguments);
	return nodes;
}



/* --------------- Function : CWJPreloadImage --------------- */

function CWJPreloadImage(src) {
	var img = new Image();
	img.src = src;
	return img;
}



/* --------------- Function : CWJOpenWindow --------------- */

function CWJOpenWindow(url, target, width, height, options, moveFlag) {
	if (!target) target = '_blank';
	var optVariations = {
		'exampleTarget1' : 'toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes,scrollbars=yes,resizable=yes',
		'exampleTarget2' : 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no'
	}
	options = options || optVariations[target] || '';
	width += (options.match('scrollbars=yes')) ? 16 : 0;
	if (width && height) options = 'width=' + width + ',height=' + height + (options ? ',' + options : '');
	var newWin = window.open(url, target, options);
	newWin.focus();
	if (moveFlag) newWin.moveTo(0, 0);
	if (window.event) window.event.returnValue = false;
	return newWin;
}



/* --------------- Function : CWJOpenFullscreenWindow --------------- */

function CWJOpenFullscreenWindow(url, target, options) {
	options = options || 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no';
	return CWJOpenWindow(url, target, screen.availWidth, screen.availHeight, options, true);
}



/* --------------- Function : CWJAppendJS --------------- */

function CWJAppendJS(src, defer) {
	if (!src || typeof src != 'string') {
		throw 'CWJAppendJS: first argument must be a string as URL.';
	} else {
		var E = new CWJTag('script');
		E.setAttributeCWJ('type', 'text/javascript');
		E.setAttributeCWJ('src' , src.replace(/~/g, '%7E'));
		if (defer == 'defer') {
			E.setAttribute('defer', 'defer');
		}
		E.appendChildCWJ ('');
		document.write(E.toString());
	}
}



/* --------------- Function : CWJAppendCSS --------------- */

function CWJAppendCSS(href, title, media) {
	if (!href || typeof href != 'string') {
		throw 'CWJAppendCSS: first argument must be a string as URL.';
	} else if (title && typeof title != 'string') {
		throw 'CWJAppendCSS: second argument must be a string as CSS title';
	} else if (media && typeof media != 'string') {
		throw 'CWJAppendCSS: third argument must be a string as CSS media type.';
	} else {
		var act = CWJGetActiveCSSTitle();
		var E   = new CWJTag('link');
		E.setAttributeCWJ('rel'  , (!title || !act || title == act) ? 'stylesheet' : 'alternate stylesheet');
		E.setAttributeCWJ('type' , 'text/css');
		E.setAttributeCWJ('media', media || 'all');
		E.setAttributeCWJ('href' , href.replace(/~/g, '%7E'));
		if (title) E.setAttributeCWJ('title', title);
		document.write(E.toString());
	}
}



/* --------------- Function : CWJAppendStateClassName --------------- */

function CWJAppendStateClassName(className) {
	if (typeof className != 'string' || !className) {
		throw 'CWJSetStateClassName: argument must be a string.';
	} else {
		var body = document.getElementsByTagNameCWJ('body')[0];
		if (!body) {
			throw 'CWJSetStateClassName: <body> element not exists.';
		} else {
			body.appendClassNameCWJ(className);
		}
	}
}



/* --------------- Function : CWJRemoveStateClassName --------------- */

function CWJRemoveStateClassName(className) {
	if (typeof className != 'string' || !className) {
		throw 'CWJRemoveStateClassName: argument must be a string.';
	} else {
		var body = document.getElementsByTagNameCWJ('body')[0];
		if (!body) {
			throw 'CWJRemoveStateClassName: <body> element not exists.';
		} else {
			body.removeClassNameCWJ(className);
		}
	}
}



/* --------------- Function : CWJGetGeometry --------------- */

function CWJGetGeometry(e) {
	var w = window;
	var d = document.documentElement;
	var b = document.getElementsByTagNameCWJ('body')[0];
	var isWinIEqm   = CWJ.ua.isWinIEQM;
	var isMacIE     = CWJ.ua.isMacIE;
	var isOldSafari = (CWJ.ua.isSafari && CWJ.ua.revision < 522); /* Safari 2.0.x or ealier */

	if (!arguments.callee.__geom__) {
		arguments.callee.__geom__ = {};
	}
	var geom       = arguments.callee.__geom__;

	geom.scrollX   = w.scrollX     || d.scrollLeft || b.scrollLeft || 0;
	geom.scrollY   = w.scrollY     || d.scrollTop  || b.scrollTop  || 0;
	geom.windowW   = w.innerWidth  || (isMacIE ? b.scrollWidth  : d.offsetWidth );
	geom.windowH   = w.innerHeight || (isMacIE ? b.scrollHeight : d.offsetHeight);
	geom.pageW     = (isMacIE) ? d.offsetWidth  : (isWinIEqm) ? b.scrollWidth  : d.scrollWidth ;
	geom.pageH     = (isMacIE) ? d.offsetHeight : (isWinIEqm) ? b.scrollHeight : d.scrollHeight;
	geom.windowX   = (!e) ? (geom.windowX  ||  0) : e.clientX - ( isOldSafari ? geom.scrollX : 0);
	geom.windowY   = (!e) ? (geom.windowY  ||  0) : e.clientY - ( isOldSafari ? geom.scrollY : 0);
	geom.mouseX    = (!e) ? (geom.mouseX   ||  0) : e.clientX + (!isOldSafari ? geom.scrollX : 0);
	geom.mouseY    = (!e) ? (geom.mouseY   ||  0) : e.clientY + (!isOldSafari ? geom.scrollY : 0);
	geom.zoom      = _getZoomRatio();
	geom.scrollBar = _getScrollBarWidth();

	if (CWJ.debugMode) {
		var arr = [geom.windowW, geom.windowH, geom.pageW , geom.pageH , geom.windowX, geom.windowY  ,
		           geom.scrollX, geom.scrollY, geom.mouseX, geom.mouseY, geom.zoom   , geom.scrollBar];
		var msg = '[Debug Mode] window: ${0}x${1} | page: ${2}x${3} | scroll: ${6},${7} | pos(view): ${4},${5} | pos(abs): ${8},${9} | zoom: ${10} | sbar: ${11}';
		CWJ_STATUSMSG.set(msg.formatTextCWJ(arr));
	}

	return geom;

	function _getZoomRatio() {
		var per = 1;
//		if (CWJ.ua.isIE70) {
//			if (isWinIEqm) {
//				per = d.offsetWidth / b.offsetWidth;
//			} else {
//				var id   = 'CWJGetGeometry_getZoomRatio_testNode';
//				var node = document.getElementByIdCWJ(id);
//				if (!node) {
//					var node = document.createElementCWJ('ins');
//					node.id = id;
//					node.style.position = 'absolute';
//					node.style.top      = '-10000px';
//					node.style.left     = '0';
//					node.style.width    = (d.scrollWidth * 10) + 'px';
//					b.appendChildCWJ(node);
//				}
//				node.style.display = 'block';
//				per = d.scrollWidth / node.offsetWidth;
//				node.style.display = 'none';
//			}
//		}
		return per;
	}

	function _getScrollBarWidth() {
		if (typeof arguments.callee.__width__ != 'number') {
			var id   = 'CWJGetGeometry_getScrollBarWidth_testNode';
			var node = document.getElementByIdCWJ(id);
			if (!node) {
				node = document.createElementCWJ('ins');
				node.id = id;
				node.style.display    = 'block';
				node.style.visibility = 'hidden';
				node.style.overflow   = 'scroll';
				node.style.position   = 'absolute';
				node.style.border     = 'none';
				node.style.top        = node.style.left    = '-10000px';
				node.style.width      = node.style.height  = '100px';
				node.style.margin     = node.style.padding = '0';
				b.appendChildCWJ(node);
			}
			arguments.callee.__width__ = node.offsetWidth - node.clientWidth;
		}
		return arguments.callee.__width__;
	}
}



/* --------------- Function : CWJSetWording --------------- */

function CWJSetWording(expression, str) {
	if (typeof expression != 'string' || typeof str != 'string') {
		throw 'CWJSetWording: argument type must be string.';
	} else if (!expression) {
		throw 'CWJSetWording: not enough arguments.';
	} else {
		var props  = expression.split('.');
		var target = 'window';
		while (props.length > 1) {
			var type    = null;
			    target += '.' + props.shift();
			try {
				type = (typeof eval(target));
			} catch(err) { }
			switch (type) {
				case 'undefined' :
					eval(target + ' = {}');
					break;
				case 'object' :
					break;
				default  : 
					throw 'CWJSetWording: specified expression is unavailable.';
					return;
			}
		}
		var type = null;
		try {
			type = typeof eval('window.' + expression);
		} catch(err) {
			throw 'CWJSetWording: specified expression is unavailable.';
		}
		if (type == 'undefined' || type == 'string') {
			eval(expression + ' = "' + str + '"');
		}
	}
}






/* =============== Startup Functions (non-DOM / pre onload) =============== */

/* ----- CWJRegisterDOMMethods ----- */

function CWJRegisterDOMMethods() {
	// register to Window object
	for (var name in CWJWindow.prototype) {
		window[name] = CWJWindow.prototype[name];
	}

	// register to Document object
	for (var name in CWJDocument.prototype) {
		document[name] = CWJDocument.prototype[name];
	}

	// register to document.body
	CWJAddOnload(function() {
		CWJRegisterDOMMethodsTo(document.body);
	});
}






/* =============== Startup Functions (DOM / post onload) =============== */

/* ----- CWJStartGeometryMeasure ----- */

function CWJStartGeometryMeasure() {
	if (CWJAlreadyApplied(arguments.callee)) return;

	CWJGetGeometry();
	document.addEventListenerCWJ('mousemove' , CWJGetGeometry);
	document.addEventListenerCWJ('mousewheel', CWJGetGeometry);
}






/* =============== Postprocess Functions (DOM / onunload) =============== */

/* ----- CWJCleanUpEventListeners ----- */

function CWJCleanUpEventListeners() {
	if (CWJ_EVENTLISTENER_STORED_NODES) {
		CWJ_EVENTLISTENER_STORED_NODES.forEach(function(node) {
			var listeners = node.__callListenersCWJ__.listeners;
			for (var type in listeners) {
				if (node.removeEventListener) {
					node.removeEventListener(type, node.__callListenersCWJ__, false);
				} else if (node.detachEvent) {
					node.detachEvent('on' + type, node.__callListenersCWJ__);
				}
				this['on' + type] = null;
			}
			node.__callListenersCWJ__ = null;
		});
		window.CWJ_EVENTLISTENER_STORED_NODES = null
	}
}






/* ============================== Main ============================== */

CWJ           = CWJSingleton(CWJEnvironment);
CWJ_STATUSMSG = CWJSingleton(CWJStatusMsg);

if (CWJ.ua.isDOMReady) {
	CWJRegisterDOMMethods();

	// prevent background image flicker.
	if (CWJ.ua.isIE) try { document.execCommand('BackgroundImageCache', false, true) } catch(err) { }

	CWJAddOnload(function() {
		CWJ.env.isDOMReady = true;
		if (CWJ.debugMode) CWJStartGeometryMeasure();
		CWJAppendStateClassName('dom-enabled');
	});

	CWJAddOnunload(function() {
		CWJCleanUpEventListeners();
	});
}
