//-- changed: objTest -> object.test [05.08.27]
//-- changed: object.test.addTest -> object.test.add [05.08.27]
//-- added: object.test.isRegExp() [05.08.27]
//-- added: object.test.isRegExpStr() [05.08.27]


/*---< core.js >----------------------[05.09.12]
|
| System information and
| core methods/constructors for js components
|
+----< dependencies >----------------------------
|
| >> none
|
+----< contents >--------------------------------
|
+-[browser info]
| +-browser		<object>
| | :-is(pStr)	<method> -> 'browser:platform:[=|>|<|>=|<=]version' (e.g. 'ie:win:>=3.0,ns:*:>5,sa')
|
+-[document info]
| +-getModDate() <PENDING>
|
+-[object : javascript & document(HTML element)]
| +-object.test <object>
| | :-addTest(id,test)	<constructor> -> add tests to testObject
| | tag		-> test for any tag object
| | ptag	-> test for any physical tag object
| | nontag	-> test for non-tag object
| | any		-> test for any object (always true)
|
+-[object : document(HTML element)]
| +-collectElements(test,firstElm,firstElm,searchBranch)
| +-walkDocTree({list{array},[test{string},][first{object},][last{object},][add{bool}]}[,curObj]) <function>
| +-getById(who)
| | +>findChild(who)
| | +>findById(who[,verified{bool}])
| +-getProps(who[,detailed{bool}])
| +-getPos(who)
| +-setClass(who,nClass)
| +-setAttribute(who,attName,nValue)
| +-setDisplay(pStr) -->> ("item1:y,item2:n,item3:y")
|
+-[event tasking]
| +-tasks										<method object>
| | :-tasks.init(obj,event)						<method>
| | :-tasks.add(obj,event,task,id,at,repCnt)	<method>
| | :-tasks.addAfter(obj,event,task,id,at)		<method>
| | :-tasks.replace(obj,event,task,id,at,repCnt)<method>
| | :-tasks.kill(obj,event,at,killCnt)			<method>
| | :-tasks.rebuild(obj,event)					<method>
| | :-tasks.getIndex(obj,event,at)				<internal method>
|
+-[math]
| vector() <constructor>
| ease_cubic() <PENDING>
|
+-[string]
| stripWhiteSpace(str,at)
| extractParam(pStr, pId[,dlm])
|
+-[object prototypes]
| +-Array.rebuild(new items[,..])
| +-[ie:mac specific]
| | +-Array.push(item)
| | +-Array.pop(item)
| | +-Array.unshift(item)
| | +-Array.shift(item)
| | +-Array.splice(startIndex,count[,replace items[,..]])
|
+----< notes >-----------------------------------
|
| Javascript 1.4 compliant
| replaced --> system info with browser info - 
| - getSysInfo()
|
+------------------------------------------------
| (c)2003,2004,2005 Inter-Planning Inc.
| http://www.inter-garden.com
+----------------------------------------------*/

debug = false;

function initCore() {
	if (!top.opener && top == window) { window.name = "win_main"; }
	document.src = file.splitSrc();
	if (debug) { document.write('<script src="debug.js" type="text/javascript"></script>'); }
	if (!window.jsComponent) { jsComponent = {}; }
	jsComponent.core = {v:2.0};
//	test();
}

//========== browser info ====================[begin]

browser = {};

//-- init platforms --> platforms.id = 'name key'
browser.platforms = {};
browser.platforms.win = 'win';
browser.platforms.mac = 'mac';
//-- init browsers --> browsers.id = ['name key','version key']
browser.browsers = {};
browser.browsers.ie = ['msie','msie '];
browser.browsers.sa = ['safari','safari/'];
browser.browsers.ff = ['firefox','firefox/'];
browser.browsers.mz = ['mozilla','rv:'];
browser.browsers.ns = ['netscape','netscape/'];
browser.browsers.ow = ['omniweb','omniweb/v'];
browser.browsers.op = ['opera','opera ']; // caution: opera's userAgent contains 'msie'!!!
//-- browser versions
// sa: 1.0(85), 1.24(125.12), 1.3(312), 2.0(412.2)
// ow: 4.5(496), 5.0(558), 5.1(563.34)

browser.agt = window.navigator.userAgent.toLowerCase();
with (browser) {
	//-- get platform info --
	for (var item in platforms) {
		browser[item] = false;
		if (!browser.platform && agt.indexOf(platforms[item]) >= 0) {
			browser.platform = item;
			browser[item] = true;
		}
	}
	//-- get browser info --
	for (var item in browsers) {
		var b = browsers[item];
		browser[item] = false;
		if (!browser.id && agt.indexOf(b[0]) >= 0) {
			browser.id = item;
			browser[item] = true;
			browser.ver = parseFloat(agt.substring(agt.indexOf(b[1]) + b[1].length));
		}
	}
	//-- get mozilla info and check for older netscape versions --
	if (agt.indexOf("mozilla") >= 0) {
		browser.moz = true;
		browser.engine = "moz";
		browser.moz_ver = parseFloat(navigator.appVersion);
		if (!browser.id && document.layers) {
			browser.id = "n4";
			browser.n4 = true;
			browser.ver = browser.moz_ver;
		}
	}
}

//-- browser "is" method --
// returns	-> boolean
// syntax	-> browser:platform:[=|>|<|>=|<=]version {string}
// e.g.	-> browser.is('ie:win:>=3.0,ns:*:>5,sa');
browser.is = function(q) { //-- v1.0[05.02.14]
	var dlm=',';
	var sep=':';
	var wild='*';
	q = stripWhiteSpace(q).toLowerCase().split(dlm);
	for (var i=0; i<q.length; i++) {
		q[i] = q[i].split(sep);
		var b = (q[i][0] == null || q[i][0] == '') ? wild : q[i][0];
		var p = (q[i][1] == null || q[i][1] == '') ? wild : q[i][1];
		var v = (q[i][2] == null || q[i][2] == '') ? wild : q[i][2];
		var chk = wild;
		if (v != wild) {
			chk = v.replace(/[\d\.]+/g,'');
			v = parseFloat(v.replace(/[^\d\.]+/g,''));
			if (chk == '' || chk == '=') { chk = (isNaN(v)) ? wild : '=='; }
		}
		if (b == wild || b == this.id) {
			if (p == wild || p == this.platform) {
				if (v == wild || eval(this.ver+chk+v)) {
					return true;
				}
			}
		}
	}
	return false;
};

//========== browser info ====================[end]

//========== file info ====================[begin]

file = {};

//-- file regular expressions (file method specific)
file.re = {};
file.re.email		= /(^|mailto:)([\w\.\-]+@[\w\.\-]+)/;
file.re.root		= /^\w{2,}:[\/]{0,3}[^\/]*\/?/;
file.re.protocol	= /^\w{2,}:[\/]{0,3}/;
file.re.param		= /[#?].+$/;

//-- file(src) methods --[begin]

file.splitSrc = function(src,mode) { // mode (not functional yet)
// fix!! - file:/ protocol has no domain so improve root re!!
// later - add: mode
// mode = r : convert paths to relative
// mode = a : convert paths to absolute

	//-- verify src object --
	if (!src) { src = document.location.href; }
	if (typeof src == 'string') {
		var obj = getById(src);
		if (obj) { src = obj; }
	}
	if (typeof src == 'object') {
		if (src.src) { src = src.src; }
		else if (src.href) { src = src.href; }
		else { src = ''; }
	}
	src = (typeof src == 'string') ? unescape(src) : '';

	//-- init vars (defaults) --
	var s;
	var d = {};
	d.all		= src;	// -> [http://www.domain.com/_prt/mmenu/btn_top_n.gif]
	d.protocol	= '';	// -> [http://] www.domain.com/_prt/mmenu/btn_top_n.gif
	d.domain	= '';	// -> http:// [www.domain.com] /_prt/mmenu/btn_top_n.gif
	d.root		= '/';	// -> [http://www.domain.com/] _prt/mmenu/btn_top_n.gif
	d.paths		= [];	// -> http://www.domain.com/ [_prt/] [mmenu/] btn_top_n.gif
	d.path		= './';	// -> http://www.domain.com/ [_prt/mmenu/] btn_top_n.gif
	d.fullPath	= '';	// -> http://www.domain.com [/_prt/mmenu/] btn_top_n.gif
	d.absPath	= '';	// -> [http://www.domain.com/_prt/mmenu/] btn_top_n.gif
	d.file		= '';	// -> http://www.domain.com/_prt/mmenu/ [btn_top_n.gif]
	d.fileName	= '';	// -> http://www.domain.com/_prt/mmenu/ [btn_top_n] .gif
	d.fileType	= '';	// -> http://www.domain.com/_prt/mmenu/btn_top_n. [gif]
	d.anchor	= '';	// -> http://www.domain.com/_prt/mmenu/index.html# [a001]
	d.params	= '';	// -> http://www.domain.com/_prt/mmenu/index.php? [a=1+b=2]
	d.email		= '';	// -> emailto: [who@where.com]
	d.type		= '';	// -> http://www.domain.com/_prt/mmenu/ [btn] _top_n.gif
	d.id		= '';	// -> http://www.domain.com/_prt/mmenu/btn_ [top] _n.gif
	d.state		= '';	// -> http://www.domain.com/_prt/mmenu/btn_top_ [n] .gif
	d.btn		= null;	// -> [http://www.domain.com/_prt/mmenu/btn_top_] n [.gif]

	var relRoot = (src.match(/^[\/]/)) ? true : false;

	//-- get email --
	s = src.match(this.re.email);
	if (s) {
		d.protocol = 'mailto:';
		d.email = s[2];
		d.root = '';
		d.path = '';
		return d;
	}

	//-- get root/protocol/domain --
	s = src.match(this.re.root);
	if (s) {
		s = s[0];
		if (s.charAt(s.length - 1) != '/') { s = s + '/'; }
		d.root = s;
		d.protocol = d.root.match(this.re.protocol).join('');
		d.domain = d.root.substring(d.protocol.length, s.length - 1);
		src = src.substring(s.length);
	}

	//-- get anchor/params --
	s = src.match(this.re.param);
	if (s) {
		s = s[0];
		if (s.charAt(0) == '#') { d.anchor = s.substring(1); }
		if (s.charAt(0) == '?') { d.params = s.substring(1); }
		src = src.substring(0,src.length - s.length);
	}
	src = src.splitAfter('/');
	if (relRoot) { src.shift(); }

	//-- get file data --
	if (src.length > 0) {
		if (src[src.length - 1].indexOf('/') < 0) {
			d.file = src.pop();
			s = d.file.split('.');
			d.fileName = s.shift();
			d.fileType = s.shift();
		}
		if (d.fileName) {
			s = d.fileName.split('_');
			if (s.length > 1) { d.type = s[0]; }
			d.id = (s.length > 1) ? s[1] : s[0];
			if (s.length > 2) { d.state = s[2]; }
		}

	}

	//-- get path data --
	if (src.length > 0) {
		d.paths = src;
		d.path = src.join('');
		if (relRoot || d.protocol) { d.fullPath = '/' + d.path; }
		d.absPath = (d.protocol) ? d.root + d.path : this.toAbsPath(d.path,true);
//		if (d.protocol) { d.absPath = d.root + d.path; }
	}

	//-- get btn info --
	if (d.type && d.id && d.fileType) {
		d.btn = [d.absPath + d.type + '_' + d.id + '_','.' + d.fileType];
	}

	return (d);
};

file.toAbsPath = function(path, verified) {
	if (!verified) {
		var root = path.match(this.re.root);
		if (root) { return path; }
	}
	if (typeof path == 'string') { path = path.splitAfter('/'); }
	var newPath = document.src.root;
	if (path[0] == '/') { //-- if relative root (/)
		path.shift();
	} else {
		if (path[0] == './') { //-- if current path (./)
			path.shift();
		}
		var docPath = [].concat(document.src.paths);
		while (path[0] == '../') { //-- if parent path (../)
			path.shift();
			docPath.pop();
		}
		newPath += docPath.join('');
	}
// build this later (removal of parent '../' paths)	
/*	for (var i = 0; i < path.length; i++) {
		if (path[i] == '../') {
			path = path.slice(0,i-2).concat(path.slice(i+2));
		}
	}*/
	newPath += path.join('');
	return newPath;
};
function test() {
	alert('http://www.aaa.aaa/' +'\n'+ file.toAbsPath('http://www.aaa.aaa/'));
	alert('rekishi/aaa/' +'\n'+ file.toAbsPath('rekishi/aaa/'));
	alert('../aaa/aaa/' +'\n'+ file.toAbsPath('../aaa/aaa/'));
	alert('/aaa/aaa/' +'\n'+ file.toAbsPath('/aaa/aaa/'));
	alert('../../../aaa/aaa/' +'\n'+ file.toAbsPath('../../../aaa/aaa/'));
	alert('../../../aaa/../../aaa/' +'\n'+ file.toAbsPath('../../../aaa/../../aaa/'));
}
file.toRelPath = function(src, verified) {
	if (!verified) {
		if (src.match(this.re.root)) { return src; }
	}
};

//-- file preloader --

file.preload = {};
file.preload.add = function(src) {
	if (!this[src]) { this[src] = new Image(); }
};
file.preload.load = function() {
	for (var src in this) {
		if (typeof this[src] == 'object') {
			this[src].src = src;
			delete this[src];
		}
	}
};

//========== file info ====================[end]



//========== object : custom(javascript) & document(HTML element) ====================[begin]

object = {};

//-- object.test object --[begin] v1.0[05.02.16]

object.test = {};

object.test.add = function(id,test) {
	if (arguments.length < 2) { return false; }
	this[id] = new Function('obj','return (' + test + ') ? true : false;');
};
object.test.test = function(obj,test) {
	if (arguments.length < 2) { return false; }
	return (eval(test)) ? true : false;
};
// note: right now this only works for && cases
// rewrite for && || cases as well as grouping ()
object.test.run = function(tests,obj) {
	if (arguments.length < 2) { return false; }
	tests = tests.split(',');
	for (var i = 0; i < tests.length; i++) {
		if (tests[i].indexOf('!') >= 0) {
			tests[i] = tests[i].substring(1);
			if (this[tests[i]](obj)) { return false; }
		} else {
			if (!this[tests[i]](obj)) { return false; }
		}
	}
	return true;
};
//-- default test definitions --
object.test.add('any','true');
object.test.isNode = function(obj,type) {
	if (arguments.length < 1) { return false; }
	if (!type) { return (obj.nodeType) ? true : false; }
	if (typeof type == 'string') {
		switch (type.toLowerCase()) {
			case 'tag' :		type = 1; break;
			case 'attr' :
			case 'attribute' :	type = 2; break; // [1]
			case 'text' :		type = 3; break;
			case 'comment' :	type = 8; break; // [1]
			case 'doc' :
			case 'document' :	type = 9; break;
			case 'doctype' :	type = 10; break; // [1]
			case 'frag' :
			case 'fragment' :	type = 11; break; // [1]
		}
		// [1] not implemented in all bowsers!
	}
	return (obj.nodeType == type) ?  true : false;
}
object.test.isTag = function(obj,name) {
	if (obj.nodeType == 1) {
		if (!name || obj.tagName.toLowerCase() == name.toLowerCase()) { return true; }
	}
	return false;
};
object.test.add('isPTag','this.isTag(obj) && !this.isTag(obj,"tbody")');
object.test.add('notTag','!this.isTag(obj)');
object.test.add('isText','obj.nodeType == 3');
object.test.add('isNode','obj.nodeType');
object.test.hasAttribute = function(obj,attr) {
//-- e.g. hasAttribute(obj,"id=/^btn_/,width");
	if (this.isTag(obj) && attr) {
		attr = attr.split(',');
		for (var i = 0; i < attr.length; i++) {
			attr[i] = attr[i].split('=');
			var a = getAttribute(obj,attr[i][0]);
			if (a != null) {
				if (attr[i].length == 2) {
					if (this.isString(attr[i][1])) { attr[i][1] = attr[i][1].toRegExp(); }
					if (!a.match(attr[i][1])) { return false; }
				}
			} else { return false; }
		}
	} else { return false; }
	return true;
};
object.test.hasChildren = function(obj) { //build this later -> ,type,attr,val) {
	if (this.isNode(obj) && obj.childNodes.length > 1) {
		return true;
	}
	return false;
};
//object.test.isRegExp = function(obj) {
//	return (obj.toString().test(/^\/.+\/[g|i]*$/)) ? true : false;
//};
object.test.add('isNumber','typeof obj == "number"');
object.test.add('isBoolean','typeof obj == "boolean"');
object.test.add('isString','typeof obj == "string"');
object.test.add('isFunction','typeof obj == "function"');
object.test.add('isArray','obj.join');
object.test.add('isDate','obj.getYear');
object.test.add('isRegExp','obj.test');
object.test.add('isRegExpStr','typeof obj == "string" && obj.match(/\\/.+[\\/][gi]{0,2}/)');
object.test.add('isObject','typeof obj == "object"');
object.test.add('isCustomObject','obj != window && this.run("isObject,!isNode,!isArray,!isDate",obj)');
//-- object.test object --[end]

//========== object : custom(javascript) & document(HTML element) ====================[end]

//========== object : document(HTML element) ====================[begin]

element = {}
// build get-search-offset features into element

function getById(id,offset) { //-- v3.0 [05.04.19]
	if (id == null || object.test.isNode(id)) { return (offset) ? window.offset.get(id,offset) : id; }
	if (!object.test.isString(id)) { return null; }
	if (id.indexOf('.') < 0) {
		var obj = searchById(id,true);
	} else {
		id = id.split('.');
		var obj = searchById(id[0],true); //-- get parent
		if (!obj) { return null; }
		for (var i = 1; i < id.length; i++) { //-- search for children
			var tStr = 'this.isTag(obj) && this.hasAttribute(obj,"id='+id[i]+'")';
			obj = collectElements(tStr,null,null,obj);
			if (obj.length == 0) { return null; }
			obj = obj[0];
		}
	}
	return (offset) ? window.offset.get(id,offset) : obj;
}

function searchById(who,verified) { //-- v1.13 [04.02.18]
	if (!verified) {
		if (typeof who == "object") { return who }
		who = (typeof who != "string") ? who.toString() : who;
	}
	if (document.getElementById) { return document.getElementById(who) }
	else if (document.all) { return document.all[who] }
	return ((document.layers) ? document.layers[who] : null);
}

function collectElements(test,elm1,elm2,branch) { //-- v1.0[05.02.16]
	branch = (branch) ? getById(branch) : document.documentElement;
	var eDat = {};
	eDat.test = false;
	eDat.tStr = null;
	if (test) {
		if (object.test[test]) { eDat.test = test; }
		else { eDat.test = 'test'; eDat.tStr = test; }
	}
	eDat.first = getById(elm1);
	eDat.last = getById(elm2);
	eDat.add = false;
	eDat.list = [];
	if (branch == eDat.first && (!eDat.test || object.test[eDat.test](branch,eDat.tStr))) {
		eDat.list.push(branch);
	}
	walkDocTree(eDat,branch.firstChild);
	return eDat.list;
}

function walkDocTree(eDat,curElm) { //-- v1.0[05.02.16]
	if (!eDat.add && (!eDat.first || eDat.first == curElm)) { eDat.first = true; eDat.add = true; }
	if (eDat.add) {
		if (!eDat.test || object.test[eDat.test](curElm,eDat.tStr)) { eDat.list.push(curElm); }
		if (eDat.last == curElm) { eDat.last = true; eDat.add = false; }
	}
	if (eDat.last != true) {
		if (curElm.firstChild) { walkDocTree(eDat,curElm.firstChild); }
		if (curElm.nextSibling) { walkDocTree(eDat,curElm.nextSibling); }
	}
}

// it runs for now but later add object.test ability
offset = {};
offset.find = function(obj,type,nType) {
// p=parent,c=firstChild,C=lastChild,s=nextSibling,S=previousSibling
//	alert(obj+ '>' +type+ ':' +obj.firstChild);
	if (!nType) { nType = '1' } // default: tags
	var o = obj;
	do {
		switch (type) {
			case 'p': o = o.parentNode; break;
			case 'c':
				o = o.firstChild;
				while (o && nType.indexOf(o.nodeType.toString()) < 0) { o = this.find(o,'s',nType); }
				break;
			case 'C':
				o = o.lastChild;
				while (o && nType.indexOf(o.nodeType.toString()) < 0) { o = this.find(o,'S',nType); }
				break;
			case 's': o = o.nextSibling; break;
			case 'S': o = o.previousSibling; break;
			default : return null;
		}
	} while (o && nType.indexOf(o.nodeType.toString()) < 0)
	return o;
}
offset.get = function(obj,offset,nType) {
	obj = (obj) ? getById(obj) : document.body;
	offset = offset.split('');
	for (var i = 0; i < offset.length; i++) {
		obj = this.find(obj,offset[i],nType);
		if (!obj) { break; }
	}
	return obj;
};
offset.p = function(obj,nType) { return obj.parentNode; };
offset.c = function(obj,nType) { return obj.firstChild; };
offset.C = function(obj,nType) { return obj.lastChild; };
offset.s = function(obj,nType) { return obj.nextSibling; };
offset.S = function(obj,nType) { return obj.previousSibling; };

function getPos(who) { //-- v1.0 [03.09.13]
	who = getById(who);
	var offX = who.offsetLeft;
	var offY = who.offsetTop;
	var tempMe = who;
	while (tempMe.offsetParent != null) {
		tempMe = tempMe.offsetParent;
		offX += tempMe.offsetLeft;
		offY += tempMe.offsetTop;
	}
	if (browser.is('ie:mac')) {
		var adjX = (document.body.marginwidth) ? parseInt(document.body.marginwidth) : 10;
		var adjY = (document.body.marginheight) ? parseInt(document.body.marginheight) : 15;
		offX += (window.bodyPad) ? adjX + bodyPad.l : adjX;
		offY += (window.bodyPad) ? adjY + bodyPad.t : adjY;
	}
	return new vector(offX,offY);
}

function setAttribute(who,attName,newVal) { //-- v1.0 [03.12.07]
// this is workaround for ie browsers (mac & win)
// for (god only knows why) some attributes cannot be set via the setAttirbute method
	who = getById(who);
	if (browser.ie) {
		var a = who.attributes.getNamedItem(attName);
		if (a) {
			a.value = newVal;
			var set = true;
		}
	}
	if (!set) { who.setAttribute(attName,newVal); }
}

function setClassAttr(who,newCls) { //-- v1.0 [03.12.07]
	setAttribute(who,'class',newCls);
}

function getAttribute(who,attName) { //-- v1.0 [05.05.06]
// this is workaround for ie browsers (mac & win)
// for (god only knows why) some attributes cannot be retrived via the getAttirbute method
	who = getById(who);
	if (browser.ie) {
		var a = who.attributes.getNamedItem(attName);
		a = (a) ? a.value : who.attributes[attName];
		if (a) { return a; }
		else { return null; }
// later build a way to determine a null as an existing custom attribute
//		if (!a) { a = who.getAttribute(attName); }
//		return (a == null && typeof who[attName] == 'object') ? '' : a;
	}
	return who.getAttribute(attName);
}

function getClassAttr(who) { //-- v1.0 [05.05.06]
	return getAttribute(who,'class');
}

function setDisplay(pStr) { //-- v1.11 [04.02.20]
//-- example -->>  setDisplay("item1:y,item2:n,item3:y");
	var pArr, i, j, p, who, s;
	pArr = stripWhiteSpace(pStr).split(',');
	for (i=0; i<pArr.length; i++) {
		p = pArr[i];
		j = p.indexOf(':');
		who = getById(p.substring(0,j));
		s = p.substring(j+1);
		who.style.display = (s == 'y') ? '' : 'none';
	}
}

//-- event tasking --

tasks = {};

tasks.init = function(obj,evt) { //-- v1.0[05.04.03]
	obj.tasks = {};
	var task = (obj[evt]) ? obj[evt].toString() : '';
	if (task != '') {
		task = task.replace(/[\n|\r]/g,'').match(/{\s*(.+)\s*}$/)[1];
		if (!task.match(/;$/)) { task += ';' }
		if (!obj.tasks[evt]) { obj.tasks[evt] = []; }
		obj.tasks[evt].push({ id:'coded',task:task });
	}
};
tasks.add = function(obj,evt,task,id,at,repCnt) { //-- v1.0[05.04.03]
	obj = getById(obj);
	if (!obj.tasks) { this.init(obj,evt); }	
	if (!obj.tasks[evt]) { obj.tasks[evt] = []; }
	if (task && !task.match(/;$/)) { task += ';' }
	at = this.getIndex(obj,evt,at);
	if (!repCnt || at == obj.tasks[evt].length) { repCnt = 0; }
	if (task) { obj.tasks[evt].splice(at,repCnt,{ id:id,task:task }); }
	else { obj.tasks[evt].splice(at,repCnt); }
	this.rebuild(obj,evt);
};
tasks.addAfter = function(obj,evt,task,id,at) { //-- v1.0[05.04.03]
	obj = getById(obj);
	if (obj.tasks && obj.tasks[evt]) { at = this.getIndex(obj,evt,at) + 1; }
	this.add(obj,evt,task,id,at);
}
tasks.replace = function(obj,evt,task,id,at,repCnt) { //-- v1.0[05.04.03]
	if (!repCnt) { repCnt = 1; }
	this.add(obj,evt,task,id,at,repCnt);
};
tasks.kill = function(obj,evt,at,killCnt) { //-- v1.0[05.04.03]
	if (!killCnt) { killCnt = 1; }
	this.add(obj,evt,null,null,at,killCnt);
};
tasks.rebuild = function(obj,evt) { //-- v1.0[05.04.03]
	var tasks = '';
	for (var i = 0; i < obj.tasks[evt].length; i++) {
		tasks += obj.tasks[evt][i].task;
	}
	if (browser.ie) { obj[evt] = new Function(tasks); }
	else { obj[evt] = new Function('evt',tasks); }
};
tasks.getIndex = function(obj,evt,at) { //-- v1.0[05.04.03]
	if (!at) { at = obj.tasks[evt].length; }
	else if (isNaN(at)) {
		for (var i = 0; i < obj.tasks[evt].length; i++) {
			if (obj.tasks[evt][i].id == at) { break; }
		}
		at = i;
	} else if (at > obj.tasks[evt].length) {
		at = obj.tasks[evt].length;
	}
	return at;
};

//========== object : document(HTML element) ====================[end]

//========== math ====================[begin]

vector = function () { //-- v1.0[03.09.14]
	var v = ['x','y','z','t'];
	for (var i = 0; i < arguments.length; i++) {
		this[v[i]] = arguments[i];
	}
}

function ease_cubic() {
	return false;
}

//========== math ====================[end]

//========== string ====================[begin]

function stripWhiteSpace(str,at) { //-- v2.0[04.12.25]
//-- e.g. -->> stripWhiteSpace('a = b'); => 'a=b';
//-- e.g. -->> stripWhiteSpace('a = b','=[>]'); => 'a= b';
//-- e.g. -->> stripWhiteSpace('a = b : c','='); => 'a=b : c';
////	if (!str && typeof this == 'string') { str = this; }
	if (at) {
		var dlm = ' ';
		var optPat = /^.+(\[.+\])$/;
		var stripL = />/;
		var stripR = /</;
		at = at.split(dlm);
		for (var i=0; i<at.length; i++) {
			var cutL = '\\s*';
			var cutR = '\\s*';
			var opt = at[i].match(optPat);
			if (opt) {
				if (!opt[1].match(stripL)) { cutL = ''; }
				if (!opt[1].match(stripR)) { cutR = ''; }
				at[i] = at[i].substring(0,at[i].lastIndexOf(opt[1]));
			}
			str = str.replace(new RegExp(cutL+at[i]+cutR,'g'),at[i]);
		}
	} else { str = str.replace(/\s*/g,''); }
	return str;
}
////String.prototype.stripWhiteSpace = stripWhiteSpace;

// javascript is stupid so it can't evaluate a custom object from a string!!!
// e.g. alert(eval('{a:12,b:true,c:["a","b","c"]}')); doesn't work!!!
// right now nested objects don't parse (fix later) problem is in the delimeter ':' not '='
// make non-quoted string detection
function parseParams(pStr,dlm,sep) {
	if (!dlm) { dlm = ',' }
	if (!sep) { sep = (pStr.indexOf('=') >= 0) ? '=' : ':'; }
	var sepRE = new RegExp(sep);
	var grpHead = /[\(\[\{]/;
	var grpTail = /[\)\]\}]/;
	var grpD = 0;
	pStr = pStr.split(dlm);
	var p = [];
	for (var i = 0; i < pStr.length; i++) { // regrouping
		if (pStr[i].match(grpHead)) { grpD++; }
		if (pStr[i].match(sepRE)) { p.push(pStr[i]); }
		else { // if in group then join, else find set non-valued parameters to true
			if (grpD > 0) { p[p.length - 1] += dlm + pStr[i]; }
			else { p.push(pStr[i] + sep + 'true'); }
		}
		if (pStr[i].match(grpTail)) { grpD--; }
	}
	var pList = {};
	for (var i = 0; i < p.length; i++) { // parse
		p[i] = p[i].split(sep);
		var si = p[i][1].indexOf('{');
		var ei = p[i][1].lastIndexOf('}');
		pList[p[i][0]] = (si != ei) ? parseParams(p[i][1].substring(si + 1,ei)) : eval(p[i][1]);
	}
	return pList;
}
//alert(parseParams('a=[1,2,3],b,c="ddd"').b);
//alert(parseParams('a=12,b=true,c=["a","b","c"],d=window,e="24px",f={aaa:{x:30,y:60},bbb:[1,2,3]}').f.aaa.x);
//alert(parseParams('a->12+b->"24px"','+','->').a);

function extractParam(pStr,pId,dlm) { //-- v1.1[03.08.23]
	var si, ei;
	if (pId.indexOf("=") < 0) { pId += "=" }
	if (dlm == null) { dlm = "," }
	si = pStr.indexOf(pId);
	if(si >= 0) {
		si += pId.length;
		ei = pStr.indexOf(dlm, si);
		if (ei < 0) { ei = pStr.length }
		return pStr.slice(si, ei);
	} else { return null; }
}

//-- String prototypes --

String.prototype.splitAt = function(dlm,rep) {
	if (!dlm) { dlm = ''; }
	if (rep == null) { rep = dlm; }
	var arr = this.split(dlm);
	if (arr[0] == '') { arr.shift(); }
	var i = (this.indexOf(dlm) != 0) ? 1 : 0;
	for (var j = i; j < arr.length; j++) { arr[j] = rep + arr[j]; }
	return arr;
};

String.prototype.splitAfter = function(dlm,rep) {
	if (!dlm) { dlm = ''; }
	if (rep == null) { rep = dlm; }
	var arr = this.split(dlm);
	var i = arr.length;
	if (arr[i-1] == '') { arr.length = --i; }
	if (this.lastIndexOf(dlm) + dlm.length < this.length) { i--; }
	for (var j = 0; j < i; j++) { arr[j] += rep; }
	return arr;
};

function toRegExp(str,absolute) {
	if (!str) { str = this.toString(); }
	if (object.test.isRegExpStr(str)) {
//	if (str.match(/^\/.+\/[gi]*$/)) {
		var si = str.indexOf('/') + 1;
		var ei = str.lastIndexOf('/');
		var head = str.substring(0,si);
		var tail = str.substring(ei);
		str = str.substring(si,ei).replace(/[\/]/g,'\\/');
		return eval(head + str + tail);
	} else {
		return new RegExp('^'+str.escapeRE()+'$');
	}
}

function escapeRE(str) { //-- v1.0[05.04.03]
	if (str == '') { return str; };
	if (!str) { str = this.toString(); }
	var escChars = '\\/^$.*+?-[|]{,}()&';
	str = str.split('');
	for (var i = 0; i < str.length; i++) {
		if (escChars.indexOf(str[i]) >= 0) { str[i] = '\\' + str[i]; }
	}
	return str.join('');
}
String.prototype.toRegExp = toRegExp;
String.prototype.escapeRE = escapeRE;

//========== string ====================[end]

//========== array ====================[begin]

//-- Array prototypes --

Array.prototype.rebuild = function() { //-- v1.0[05.03.05]
	var tmp = [];
	for (var i=0; i<arguments.length; i++) { tmp = tmp.concat(arguments[i]); }
	var old = [].concat(this);
	this.length = 0;
	for (var i=0; i<tmp.length; i++) { this[i] = tmp[i]; }
	return old;
};

//-- Array prototypes (ie:mac specific) --

if (browser.is('ie:mac')) {
	Array.prototype.push = function() { //-- v1.0[05.03.05]
		for (var i=0; i<arguments.length; i++) { this[this.length] = arguments[i]; }
		return this.length;
	};
	Array.prototype.pop = function() { //-- v1.0[05.03.05]
		var i = this.length - 1;
		var cut = this[i];
		this.length = i;
		return cut;
	};
	Array.prototype.unshift = function() { //-- v1.0[05.03.05]
		var tmp = [];
		for (var i=0; i<arguments.length; i++) { tmp.push(arguments[i]); }
		this.rebuild(tmp,this);
		return this.length;
	};
	Array.prototype.shift = function() { //-- v1.0[05.03.05]
		var cut = this[0];
		this.rebuild(this.slice(1));
		return cut;
	};
	Array.prototype.splice = function(si,cnt) { //-- v1.0[05.03.05]
		var tmp = this.slice(0,si);
		var cut = this.slice(si,si+cnt);
		if (arguments.length > 2) {
			for (var i=2; i<arguments.length; i++) { tmp.push(arguments[i]); }
		}
		this.rebuild(tmp,this.slice(si+cnt));
		return cut;
	};
}

//========== array ====================[end]

//========== png alpha loader (ie:win 5.5up) ====================[end]
//-- thanks to --------------------
// Aaron Boodman's "Sleight" script
// http://www.youngpup.net
//---------------------------------

if (browser.is('ie:win:>=5.5') && window.attachEvent) {

	//-- foreground pngs

	function fnLoadPngs() {
		var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
		var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
	
		for (var i = document.images.length - 1, img = null; (img = document.images[i]); i--)
		{
			if (itsAllGood && img.src.match(/\.png$/i) != null)
			{
				var src = img.src;
				var div = document.createElement("DIV");
				div.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizing='scale')"
				div.style.width = img.width + "px";
				div.style.height = img.height + "px";
				img.replaceNode(div);
			}
			img.style.visibility = "visible";
		}
	}
	document.writeln('<style type="text/css">img { visibility:hidden; } </style>');
	window.attachEvent("onload", fnLoadPngs);

	//-- background pngs (including css styles!!!)

	function alphaBackgrounds(){
		var rslt = navigator.appVersion.match(/MSIE (\d+\.\d+)/, '');
		var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
		for (i=0; i<document.all.length; i++){
			var bg = document.all[i].currentStyle.backgroundImage;
			if (itsAllGood && bg){
				if (bg.match(/\.png/i) != null){
					var mypng = bg.substring(5,bg.length-2);
					document.all[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+mypng+"', sizingMethod='crop')";
					document.all[i].style.backgroundImage = "url('/assets/images/x.gif')";
				}
			}
		}
	}
	window.attachEvent("onload", alphaBackgrounds);
}

//========== finish up ====================[begin]

initCore();

//========== finish up ====================[end]
