// nützliche Funktionen
// $(id, node): gibt das Element mit der Id id im Document der Node node zurück, wenn id mit einem Punkt anfängt werden alle Nodes zurückgegeben, die den Klassennamen id haben; wenn id die form "<tag>" hat werden die nodes mit tag alsTagname zurückgegeben
// nummer(str): erzeugt aus einem String eine Zahl (nimmt die ersten Ziffern, die vorkommen - sobald etwas anders kommt wird die Zahl bis dort hin ausgegeben). Leerzeichen werden ignoriert. (str darf auch ein Array sein - dann wird analog mit den Elementen verfahren)
// EINE_ZAHL.toZeros(anzahl): Gibt einen String zurück, mit der Zahl EINE_ZAHL am Ende und so vielen Nullen, dass vor dem Komma anzahl Stellen sind
// EIN_STRING.firstToUpperCase(restToLowerCase): Gibt den String mit dem ersten Buchstaben groß zurück - wenn restToLowerCase gleich true ist wird der Rest des String in kleine Buchstaben umgewandelt
// EINE_ZAHL.toHex(anzahl): Gibt einen String zurück mit der Zahl EINE_ZAHL in hexadezimaler Schreibweise und min. anzahl Stellen
// EIN_STRING.hexToNumber(str): behandelt den String str wie eine Hexadecimale Zahl (andere Zeichen werden als 0 interpretiert) und gibt ihren Wert als Zahl zurück
// max(obj,index); vergleicht alle Elemente im Ojekt obj un gibt das Maximum zurück. Wenn index wird ein Array zurückgegebn (1. Wert, 2. Index des Wertes in obj)
// min(obj,index): wie max
// EINE_ZAHL.inInRange(lower, upper): gitb true zurück, wenn EINE_ZAHL zwischen lower und upper liegt, sonst false
// EINE_ZAHL.setInRange(lower, upper): "quetscht" die zahl EINE_ZAHL in das Intervall [lower, upper], d.h. sie wird auf lower bzw. upper gesetzt, wenn sie außerhalb liegt
// array(arr): Definition meiner Persönlichen Arrayklasse, die ich unten auch verändere erzeugt wird sie wie ein normaler Array
// EIN_ARRAY.add(arr): addiert zu den Elementen des Arrays EIN_ARRAY entweder die Elemente des Arrays arr oder die Zahl arr
// EIN_ARRAY.sub(arr): subtrahiert von den Elementen des Arrays EIN_ARRAY entweder die Elemente des Arrays arr oder die Zahl arr
// EIN_ARRAY.mul(arr): multipliziert die Elementen des Arrays EIN_ARRAY entweder mit den Elemente des Arrays arr oder der Zahl arr
// EIN_ARRAY.div(arr): dividiert die Elementen des Arrays EIN_ARRAY entweder durch die Elemente des Arrays arr oder die Zahl arr
// rangeUeberlapp(l1, u1, l2, u2): gibt true zurück, wenn sich die beiden Zahlenbereiche [l1, u1] und [l2, u2] überschneiden
// onLoad(node,kinder): führt in der Node node das onload-Ereignis aus, wenn kinder werden auch die der kinder ausgeführt
// mausPosition(Ereignis): gibt die Mausposition eines Ereignisses zurück (als Array)
// scrollPosition: gibt die aktuelle Scrollposition des Hauptfensters zurück
// convertDate(date, von, bis): Convertiert Datumsformate ineinander um (à la YYYY-MM-DD -> DD.MM.YYYY)
// ajax(ort, funktion): führt eine AJAX-GET-Anfrage am Ort ort aus. Die Antwort wird dann an die Funktion funktion gegeben. Gibt den Request zurück
//AJAX(ort, funktion, art, send): wie oben, nur kann hier die Art der Anfrage art und derSendeparameter send gesetzt werden.
// loadXMLDoc(dname): Läd' das XML-Dokument aus dem Pfad dname und gibt dieses als Document zurück. // von http://www.w3schools.com/dom/dom_loadxmldoc.asp
// isEnthalten(such, obj): gibt true zurück, wenn such in obj enthalten ist - andernfalls false
// getIndex(such, obj): gibt den ersten Index von such in obj zurück - wenn es nicht ethalten ist false
// objectLength(obj): gibt die Länge des Objektes obj zurück
// isArray(obj); gitb true zurück, wenn das Objekt obj ein Array ist, sonst false
// isNotDefined(obj /isUndefined(obj): gibt true zurück, wenn das Objekt obj nicht definiert ist
// getWindowSize(); gibt die Anzeigegröße als Array(Breite, Höhe) zurück 
// createNode(type, attributes, style, child1, child2, ..): gibt eine neue Node mit den Attributen attributes und den Style style zurück - die kinder childN werden in die neue Node eingefügt
// koordAdd(node,kinder): fügt der Node node die Funktionen getX und getY hinzu, die die Koordinaten der Node zurückgeben. wenn kinder = true (default ist false) werden den Kindelementen der Node auch diese Funktionene hinzugefügt.
// tabelle(zeilen, spalten): gibt ein Table-Objekt zurück mit zeilen Zeilen und spalten Spalten. Eigentlich gibt es ein Array der Objekte zurück (rueckgabe[0] ist das Table-Objekt, rueckgabe[i][0] ist die i.te Reihe und rueckgabe[i][j] ist die Zelle in Reihe i und Spalte j)
// loadScript(url,ort): läd das JS an de URI url in die Node ort (default ist der erste HEAD); gitb die SCRIPt-Node zurück
// loadPlugin(plugin, ort): wie loadScript, nur dass hier als Basis-Ordner der von dieser nuetzlich.js genommen wird 


(function(){
if (!window.kkjs) window.kkjs = new Object();

kkjs.setGlobal = function setGobal(){
	kkjs.is.global = true;
	for (var i in kkjs){
		window[i] = kkjs[i];
	}
}

kkjs.$ = function $(id, node){
	function getAllClass(ret,klasse,node){
		if (/^\/.+\/$/.test(klasse)) var klasse_re = new RegExp(klasse.replace(/^\/|\/$/g, ""));
		else var klasse_re = new RegExp("^" + klasse + "$");
		if (klasse_re.test(node.className)){
			ret.push(node);
		}
		var kinder = node.childNodes;
		for (var i = 0 ; i < kinder.length; i++){
			ret = getAllClass(ret,klasse,kinder[i]);
		}
		return ret;
	}
	
	if (!node) node = document;
	if (!node.nodeType) node = kkjs.getDocument(node);
	if (kkjs.is.node(id)) return id;
	if (/^\./.test(id)) return getAllClass(new Array(),id.replace(/^\./,''),node);
	if (/^<.+>/.test(id)) return node.getElementsByTagName(id.replace(/^<(.+)>/,'$1'),node);
	
	node = kkjs.getDocument(node);
	return node.getElementById(id);
};

kkjs.print_r = function print_r(ob, ebene){
	if (!ebene) ebene = 0;
	var ind = "";
	for (var i = 0; i < ebene; i++) ind += "\t";
	if (typeof(ob) == "function") return ind + "function(){[code]}\n";
	var ret = ob.toString();
	
	if (
		kkjs.is.string(ob) ||
		kkjs.is.number(ob) ||
		kkjs.is.boolean(ob) ||
		kkjs.is.node(ob)
	) return ret + "\n";
	
	
	ret += "{\n";
	for (var i in ob) ret += ind + "\t" + i + ": " + kkjs.print_r(ob[i], ebene + 1);
	ret += ind;
	ret += "}";
	
	return ret + "\n";
}

if (!window.$){
	window.$ = kkjs.$;
}

kkjs.nummer = function nummer(str){
	if (kkjs.is.array(str)){
		var ret = new Array(str.length);
		for (var i = 0; i < ret.length; i++){
			ret[i] = kkjs.nummer(str[i]);
		}
		return ret;
	}
	if (isNaN(parseFloat(str))) return 0;
	return parseFloat(str);
};

Number.prototype.toZeros = function toZeros(vorKomma, nachKomma, fill){
	if(!fill) fill = "0";
	fill = fill.toString();
	if (fill.length > 1) fill = fill.substring(0,1);
	var zahl = Math.abs(this);
	var minus = (this < 0);
	if (isNaN(nachKomma)) nachKomma = 0;
	zahl = zahl.toFixed(nachKomma);
	
	while (zahl.replace(/[\.,].+/, "").length < vorKomma){
		zahl = fill + zahl.toString();
	}
	if (minus) zahl = "-" + zahl;
	return zahl;
};

Number.prototype.toRoman = function toRoman(){
	var h = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"];
	var z = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"];
	var e = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
	
	var ret = "";
	var tausend = Math.floor(this/1000);
	for (var i = 0; i < tausend; i++){
		ret += "M";
	}
	var hundert = Math.floor(this/100) - 10*tausend;
	ret += h[hundert];
	var zehn = Math.floor(this/10) - 10*hundert - 100*tausend;
	ret += z[zehn];
	var eins = this%10;
	ret += e[eins];
	return ret;
};

String.prototype.firstToUpperCase = function firstToUpperCase(restToLowerCase){
	var str = this;
	if (restToLowerCase) str = this.toLowerCase();
	return str.substring(0,1).toUpperCase()+str.substring(1,this.length);
};

String.prototype.reverse = function reverse(block){
	if (!block) block = 1;
	var ret = "";
	for (var i = this.length - block; i >= 0; i -= block){
		ret += this.substr(i, block);
	}
	if (i != block*-1){
		ret += this.substr(0, -i);
	}
	return ret;
};

Number.prototype.toHex = function toHex(anzahl){
	var ret = this.toString(16);
	while (ret.length < anzahl){
		ret = "0" + ret;
	}
	return ret;
	/*
	var stellen = new Array();
	stellen[0] = this;
	if (!isNaN(anzahl)) for (var i = 1; i<anzahl; i++) stellen[i] = 0;

	var ziffer = new Array(0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F");

	for (var i=0; i < stellen.length; i++){
		var rest = stellen[i]%16;
		var erg = parseInt(stellen[i]/16);
		stellen[i] = rest;
		if (erg>0) stellen[i+1] = erg;
	}
	var text = "";
	for (var i = 0; i< stellen.length; i++) text = ziffer[stellen[i]] + text;
	return text;*/
};

String.prototype.hexToNumber = function hexToNumber(){
	return parseInt(this, 16);
	/*var zahl = 0;
	var ziffer = new Array(0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F");

	for (var i = 0; i < this.length; i++){
		for (var j = 0; j < ziffer.length; j++){
			if (this.substring(i,i+1).match(new RegExp("^"+ziffer[j]+"$","i"))){
				zahl += j*Math.pow(16,this.length-1-i);
			}
		}
	}
	return zahl;*/
};

kkjs.max = function max(obj,index){
	var max = -1*Number.MAX_VALUE;
	if (typeof(obj) != "object"){
		for (var i = 0; i < arguments.length; i++){
			if (arguments[i] > max) max = arguments[i];
		}
		return max;
	}
	var i = null;
	for (var att in obj){
		if (obj[att] > max){
			max = obj[att];
			i = att;
		}
	}
	if (index) return new Array(max,i);
	return max;
};

kkjs.min = function min(obj,index){
	var min = Number.MAX_VALUE;
	if (typeof(obj) != "object"){
		for (var i = 0; i < arguments.length; i++){
			if (arguments[i] < min) min = arguments[i];
		}
		return min;
	}
	var i = null;
	for (var att in obj){
		if (obj[att] < min){
			min = obj[att];
			i = att;
		}
	}
	if (index) return new Array(min,i);
	return min;
};

Number.prototype.isInRange = function isInRange(lower,upper){
	if (this >= lower && this <= upper) return true;
	if (this <= lower && this >= upper) return true;
	return false;
};

Number.prototype.setInRange = function setInRange(lower, upper){
	if (kkjs.is.undefined(lower)) lower = this;
	if (kkjs.is.undefined(upper)) upper = this;
	lower = kkjs.nummer(lower);
	upper = kkjs.nummer(upper);
	
	if (this < lower) return lower;
	if (this > upper) return upper;
	return this
}

Number.prototype.setInCircle = function setInCircle(lower, upper){
	var zahl = this;
	if (lower == upper) return lower;
	if (lower > upper){
		var l = lower;
		lower = upper;
		upper = l;
	}
	while (zahl < lower) zahl += Math.abs(upper - lower);
	while (zahl > upper) zahl -= Math.abs(upper - lower);
	return zahl;
};

kkjs.array = function(){
	if (kkjs.is.array(arguments[0])){
		for (var i = 0; i < arguments[0].length; i++){
			this[i] = arguments[0][i];
		}
		this.length = arguments[0].length;
	}
	else{
		for (var i = 0; i < arguments.length; i++){
			this[i] = arguments[i];
		}
		this.length = arguments.length;
	}
	
	this.toString = function(){
		var text = "";
		for (var i in this){
			if (!isNaN(i)) text += this[i] + ", ";
		}
		return text.substring(0, text.length - 2);
	};
		
	this.add = function(arr){
		if (kkjs.is.array(arr)){
			if (arr.length < this.length) return kkjs.Debug.error("Der übergebene Array muss mindestens so lang sein wie der Objektarray.");
			for (var i = 0; i < this.length; i++){
				this[i] += arr[i];
			}
		}
		else {
			if (typeof(arr) != "number") return kkjs.Debug.error("Das Argument muss entweder ein Array oder eine Zahl sein.");
			for (var i = 0; i < this.length; i++){
				this[i] += arr;
			}
		}
		return this;
	};
	
	this.sub = function(arr){
		if (kkjs.is.array(arr)){
			if (arr.length < this.length) return kkjs.Debug.error("Der übergebene Array muss mindestens so lang sein wie der Objektarray.");
			for (var i = 0; i < this.length; i++){
				this[i] -= arr[i];
			}
		}
		else {
			if (typeof(arr) != "number") return kkjs.Debug.error("Das Argument muss entweder ein Array oder eine Zahl sein.");
			for (var i = 0; i < this.length; i++){
				this[i] -= arr;
			}
		}
		return this;
	};
	
	this.mul = function(arr){
		if (kkjs.is.array(arr)){
			if (arr.length < this.length) return kkjs.Debug.error("Der übergebene Array muss mindestens so lang sein wie der Objektarray.");
			for (var i = 0; i < this.length; i++){
				this[i] *= arr[i];
			}
		}
		else {
			if (typeof(arr) != "number") return kkjs.Debug.error("Das Argument muss entweder ein Array oder eine Zahl sein.");
			for (var i = 0; i < this.length; i++){
				this[i] *= arr;
			}
		}
		return this;
	};
	
	this.div = function(arr){
		if (kkjs.is.array(arr)){
			if (arr.length < this.length) return kkjs.Debug.error("Der übergebene Array muss mindestens so lang sein wie der Objektarray.");
			for (var i = 0; i < this.length; i++){
				this[i] /= arr[i];
			}
		}
		else {
			if (typeof(arr) != "number") return kkjs.Debug.error("Das Argument muss entweder ein Array oder eine Zahl sein.");
			for (var i = 0; i < this.length; i++){
				this[i] /= arr;
			}
		}
		return this;
	};
	
	this.max = function(){
		var max = false;
		for( var i in this){
			if (typeof(this[i]) == "number"){
				if (!max || max < this[i]) max = this[i];
			}
		}
		return max;
	};
	
	return this;
};

kkjs.rangeUeberlapp = function rangeUeberlapp(l1,u1,l2,u2){
	return (l1.isInRange(l2,u2) || u1.isInRange(l2,u2) || l2.isInRange(l1,u1) || u2.isInRange(l1,u1));
};


kkjs.setGetter = function setGetter(name, obj, func){
	obj[name] = func;
	obj[name].toString = obj[name];
};

kkjs.bindObj = function bindObj(obj, func){
	return function(){func.apply(obj, arguments)};
};


kkjs.onLoad = function onLoad(node,kinder){
	if (!node.nodeName.match(/body|document|html/i) && node.onload){
		var code = node.onload.toString().replace(/this/g,"node");
		//alert(code);
		code = code.replace(/function\s*[-_a-zA-Z]*\s*\([-_a-zA-Z]*\)\s*\{\s*(.*)\s*\}/,"$1");
		eval(code);
	}
	if (kinder){
		var kinder = node.childNodes;
		for (var i = 0; i< kinder.length; i++){
			kkjs.onLoad(kinder[i],true);
		}
	}
};

kkjs.mausPosition = function mausPosition(Ereignis){
	if (!Ereignis){
		if (window.event){
			Ereignis = window.event;
		}
		else return false;
	}
	
	var HTMLOffset = new Array(
		document.body.clientLeft + document.body.parentNode.clientLeft,
		document.body.clientLeft + document.body.parentNode.clientTop
	);
	
	if (kkjs.is.key(Ereignis, "pageX"))
		return new Array(
			Ereignis.pageX,
			Ereignis.pageY
		);
	return new Array(
		Ereignis.clientX + kkjs.getScrollPosition()[0] - HTMLOffset[0],
		Ereignis.clientY + kkjs.getScrollPosition()[1] - HTMLOffset[1]
	);
};

kkjs.getScrollPosition = function getScrollPosition(){
	var x = kkjs.nummer(document.body.scrollLeft) + kkjs.nummer(document.documentElement.scrollLeft);
	var y = kkjs.nummer(document.body.scrollTop)  + kkjs.nummer(document.documentElement.scrollTop);
	return new Array(x,y);
};

kkjs.scrollPosition = kkjs.getScrollPosition;

kkjs.getScrollSize = function getScrollSize(node){
	if (!node) node = document.documentElement;
	return new Array(node.scrollWidth, node.scrollHeight);
};

kkjs.convertDate = function convertDate(date, von, zu){
	var jahr = "";
	var monat = "";
	var tag = "";
	
	if (von != Date){
		for (var i = 0; i<date.length; i++){
			if (von.substr(i,1).match(/y|j/i)){jahr += date.substr(i,1);}
			if (von.substr(i,1).match(/m/i)){monat += date.substr(i,1);}
			if (von.substr(i,1).match(/d|t/i)){tag += date.substr(i,1);}
		}
		
		jahr = kkjs.nummer(jahr);
		monat = kkjs.nummer(monat);
		tag = kkjs.nummer(tag);
	}
	else{
		jahr = date.getFullYear();
		monat = date.getMonth() + 1;
		tag = date.getDate();
	}
	
	if (zu == Date){
		return new Date(jahr, monat - 1, tag);
	}
	
	
	var j = 0;
	var zj = 0;
	while (zu.substring(zj,zu.length).search(/y|j/ig) >= 0){
		zj = zj+zu.substring(zj,zu.length).search(/y|j/ig)+1;
		j++;
	}
	
	var m = 0;
	var zm = 0;
	while (zu.substring(zm,zu.length).search(/m/ig) >= 0){
		zm = zm+zu.substring(zm,zu.length).search(/m/ig)+1;
		m++;
	}
	
	var t = 0;
	var zt = 0;
	while (zu.substring(zt,zu.length).search(/d|t/ig) >= 0){
		zt = zt+zu.substring(zt,zu.length).search(/d|t/ig)+1;
		t++;
	}
	
	jahr = jahr.toZeros(j);
	monat = monat.toZeros(m);
	tag = tag.toZeros(t);
	
	var erg = "";
	
	for (var i = zu.length-1; i>=0; i--){
		if (zu.substr(i,1).match(/y|j/i)){
			erg = jahr.substr(jahr.length-1,1)+erg;
			jahr = jahr.substring(0,jahr.length-1);
		}
		else if( zu.substr(i,1).match(/m/i)){
			erg = monat.substr(monat.length-1,1)+erg;
			monat = monat.substring(0,monat.length-1);
		}
		else if( zu.substr(i,1).match(/d|t/i)){
			erg = tag.substr(tag.length-1,1)+erg;
			tag = tag.substring(0,tag.length-1);
		}
		else{
			erg = zu.substr(i,1)+erg;
		}
	}
	
	return erg;
};

kkjs.datumErgaenzen = function datumErgaenzen(str){
	if (str.match(/^(\d+)\.(\d+)\.(\d*)$/)){
		var jahr = kkjs.nummer(RegExp.$3);
		
		if (jahr == 0){
			jahr = (new Date()).getFullYear();
		}
		if (jahr < 100) {jahr += 2000;}
		
		var datum = new Date(jahr, kkjs.nummer(RegExp.$2) - 1, kkjs.nummer(RegExp.$1));
		
		if (datum.getDate() != kkjs.nummer(RegExp.$1)){
			return false;
		}
		
		var tag = datum.getDate().toZeros(2);
		var monat = (datum.getMonth() + 1).toZeros(2);
		
		var jahr = datum.getFullYear();
		
		jahr = jahr.toZeros(4);
		
		return tag+"."+monat+"."+jahr;
	}
	else{
		return false;
	}
};


kkjs.ajax = function ajax(ort, funktion){
	kkjs.AJAX(ort, funktion, "GET", null);
};

kkjs.AJAX = function AJAX(ort, funktion, art, send, asynch){
	if (!art) art = "GET";
	if (!kkjs.is.boolean(asynch)) asynch = true;
	if (typeof(funktion) != "function") funktion = function(){};
	//Request initialisieren
	var req;
	if (window.XMLHttpRequest){
		req = new XMLHttpRequest();
	}
	else if(window.ActiveXObject){
		try{
			req = new ActiveXObject('Msxml2.XMLHTTP');
		}
		catch (nonms){
			try{
				req = new ActiveXObject('Microsoft.XMLHTTP');
			}
			catch (failed){	}
		}
	}
	if (!req){
		alert('Error creating request object!');
		return false;
	}
	
	// Umbau wg. IE6 notwendig
	//req.finishFunction = funktion;
	var finishFunction = funktion;
	
	//request öffnen
	req.open(art, ort, asynch);
	//Beim abschliessen des request wird diese Funktion ausgeführt
	req.onreadystatechange = function(){
		(function(){
			switch (this.readyState) {
				case 4:
					try{
						switch (this.status) {
							case 0:
								break;
							case 200:
								finishFunction.call(this, this.responseText, this.responseXML);
								break;
							default:
								alert('Status error: ' + this.status);
								break;
						}
					}
					catch(e){
						var message = "";
						if (e.description) message = e.description;
						else if (e.message) message = e.message;
						else message = e.toString();
						alert("Evaluation error:\n" + message);
					}
					break;
				default:
					return false;
					break;
			}
		}).call(req);
	};
	req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	req.setRequestHeader('X-AJAX-Engine','KKJS: Version 1.0');
	req.send(send);
	return req;
};

kkjs.AJAXUpdater = function AJAXUpdater(element, url, art, send, asynch){
	element = kkjs.$(element);
	var updateFkt = function(txt){
		element.innerHTML = txt;
	};
	return kkjs.AJAX(url, updateFkt, art, send, asynch);
}

kkjs.AJAXObject = function AJAXObject(att){
	if (!att) att = new Object();
	if (!kkjs.is.boolean(att.asynchronous)){
		if (kkjs.is.boolean(att.synchronous)) att.asynchronous = !att.synchronous;
		else if (kkjs.is.boolean(att.async)) att.asynchronous = att.async;
		else if (kkjs.is.boolean(att.sync)) att.asynchronous = !att.sync
		else att.asynchronous = true;
	}
	if (!typeof(att.finishFunction) != "function"){
		if (!typeof(att.func) != "function") att.finishFunction = att.func;
		else att.finishFunction = function(){};
	}
	if (!kkjs.is.key(att, "url")){
		if (kkjs.is.key(att, "src")) att.url = att.src;
		else att.url = "";
	}
	if (!kkjs.is.key(att, "type")){
		if (kkjs.is.key(att, "art")) att.type = att.art;
		else if (kkjs.is.key(att, "method")) att.type = att.method;
		else att.type = "GET";
	}
	if (!att.content) att.content = null;
	
	//Request initialisieren
	var req;
	if (window.XMLHttpRequest){
		req = new XMLHttpRequest();
	}
	else if(window.ActiveXObject){
		var tries = new Array('Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP');
		for (var i = 0; i < tries.length; i++){
			try{
				req = new ActiveXObject(tries[i]);
				break;
			}
			catch (e){}
		}
	}
	if (!req){
		alert('Error creating request object!');
		return false;
	}
	
	for (var i in att){
		req[i] = att[i];
	}
	
	req.doOpen = function doOpen(){
		//request öffnen
		this.open(this.type, this.url, this.asynchronous, this.user, this.password);
		//Beim abschliessen des request wird diese Funktion ausgeführt
		this.onreadystatechange = function(){
			switch (this.readyState) {
				case 4:
					try{
						switch (this.status) {
							case 200:
								this.finishFunction(this.responseText, this.responseXML);
								break;
							default:
								alert('Status error: ' + this.status);
								break;
						}
					}
					catch(e){
						var message = "";
						if (e.description) message = e.description;
						else if (e.message) message = e.message;
						else message = e.toString();
						alert("Evaluation error:\n" + message);
					}
					break;
				default:
					return false;
					break;
			}
		};
		if (this.requestContentType) this.setRequestHeader('Content-Type', this.requestContentType);
		else this.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		
		if (this.headers){
			for (var i in this.headers){
				this.setRequestHeader(i, this.headers[i]);
			}
		}
		if (this.user && this.password){
			//this.setRequestHeader('Authorization', 'Basic ' + kkjs.encodeBase64(this.user + ":" + this.password));
		}
		
		if (!this.notSend){
			this.doSend();
		}
		
		return this;
	}
	req.doSend = function doSend(){
		this.send(this.content);
		
		return this;
	}
	
	if (!req.notOpen){
		req.doOpen();
	}
	return req;
};


kkjs.loadXMLDoc = function loadXMLDoc(dname){
	// Kopiert aus http://www.w3schools.com/dom/dom_loadxmldoc.asp am 27.11.2008 um 12:00
	try{ //Internet Explorer
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
	}
	catch(e){
		try{ //Firefox, Mozilla, Opera, etc.
		xmlDoc=document.implementation.createDocument("","",null);
		}
		catch(e){
			alert(e.message);
		}
	}
	try{
		xmlDoc.async = false;
		xmlDoc.load(dname);
		return xmlDoc;
	}
	catch(e){
		alert(e.message);
	}
	return null;
};


kkjs.isEnthalten = function isEnthalten(such, obj){
	//return (such in obj);
	for (var k in obj){
		if (obj[k] == such){
			return true;
		}
	}
	return false;
};

kkjs.getIndex = function getIndex(such, obj){	
	for (var i in obj){
		if (obj[i] == such){
			return i;
		}
	}
	return false;
};

kkjs.objectLength = function objectLength(obj){
	var len = 0;
	for (var k in obj){
		len++;
	}
	return len;
};


kkjs.is = {
	array: function(obj){
		return (obj != null && (obj.constructor == Array || (!kkjs.is.undefined(kkjs.array) && obj.constructor == kkjs.array)));
	},
	object: function(obj){
		return (obj != null && (/^object$/i.test(typeof obj) || obj.constructor == Object));
	},
	number: function(num){
		return (!isNaN(num) && (/^number$/i.test(typeof num) || num.constructor == Number));
	},
	string: function(str){
		return (str != null && (/^string$/i.test(str) || str.constructor == String));
	},
	boolean: function(bool){
		return (bool != null && (/^boolean$/i.test(bool) || bool.constructor == Boolean));
	},
	'true': function(tr){
		return (kkjs.is.boolean(tr) && tr);
	},
	'false': function(fl){
		return (kkjs.is.boolean(fl) && !fl);
	},
	undefined: function(un){
		return (un == null || /^undefined$/i.test(typeof un));
	},
	'null': function(nu){
		return (nu == null);
	},
	key: function(array, key){
		if (key in array) return true;
		
		return !kkjs.is.undefined(array[key]);
	},
	node: function(node){
		return (kkjs.is.object(node) && ("nodeName" in node) && ("nodeType" in node) && ("nodeValue" in node));
	},
	opera: /opera/i.test(navigator.userAgent),
	ie: (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)),
	version: (/(msie|firefox|opera)[\/\s]((\d+\.?)+)/i.exec(navigator.userAgent))?/(msie|firefox|opera)[\/\s]((\d+\.?)+)/i.exec(navigator.userAgent)[2]: Number.NaN,
	gecko: /gecko/i.test(navigator.userAgent),
	ff: /firefox/i.test(navigator.userAgent)
};

kkjs.enableSimpleIs = function enablerSimpleIs(){
	kkjs.isArray = kkjs.is.array;
	kkjs.isNotDefined = kkjs.is.undefined;
	kkjs.isUndefined  = kkjs.is.undefined;

	kkjs.is_Opera = kkjs.is.opera;
	kkjs.is_IE = kkjs.is.ie;
	kkjs.is_Gecko = kkjs.is.gecko;
	kkjs.is_Firefox = kkjs.is.ff;
};


kkjs.exists = function exists(obj){
	return !kkjs.is.undefined(obj);
};

kkjs.getWindowSize = function getWindowSize(){
	if (document.documentElement.clientWidth && document.compatMode != "BackCompat")
		var ret = new Array(document.documentElement.clientWidth, document.documentElement.clientHeight);
	else if (document.body.clientWidth)
		var ret = new Array(document.body.clientWidth, document.body.clientHeight);
	else if (document.body.offsetWidth)
		var ret = new Array(document.body.offsetWidth, document.body.offsetHeight);
	else if (window.innerWidth)
		var ret = new Array(window.innerWidth, window.innerHeight);
	else {
		var px = document.createElement("div");
		px.style.height = "0px";
		px.style.width = "0px";
		px.style.backgroundColor = "#FFFFFF";
		px.style.position = "fixed";
		px.style.bottom = "0px";
		px.style.right = "0px";
		document.body.appendChild(px);
		kkjs.koordAdd(px);
		var ret = new Array(px.getX(), px.getY());
		kkjs.removeNode(px);
	}
	return ret;
};

kkjs.createNode = function createNode(type, attributes, style){
	var node = document.createElement(type);
	for (var i in attributes){
		//node.setAttribute(i, attributes[i]);
		node[i] = attributes[i];
	}
	
	kkjs.setStyle(node, style);
	
	for (var i = 3; i < arguments.length; i++){
		node.appendChild(arguments[i]);
	}
	
	return node;
}

kkjs.koordAdd = function koordAdd(node,kinder){
	if (typeof(node.offsetLeft) == "undefined" || typeof(node.offsetTop) == "undefined") return false;
	node.getX = function(){
		if (kkjs.is.undefined(this.parentNode)) return 0;
		var x = kkjs.nummer(this.offsetLeft);
		var elter = this.offsetParent
		while (elter){
			x += kkjs.nummer(elter.offsetLeft);
			if (!kkjs.is.opera && !elter.nodeName.match(/html/i)){
				x -= kkjs.nummer(elter.scrollLeft);
			}
			if (kkjs.is.opera){
				x -= kkjs.nummer(elter.style.borderLeftWidth);
			}
			elter = elter.offsetParent;
		}
		return x;
	}
	node.getY = function(){
		if (kkjs.is.undefined(this.parentNode)) return 0;
		var y = kkjs.nummer(this.offsetTop);
		var elter = this.offsetParent
		while (elter){
			y += kkjs.nummer(elter.offsetTop);
			if (!kkjs.is.opera && !elter.nodeName.match(/html/i)){
				y -= kkjs.nummer(elter.scrollTop);
			}
			if (kkjs.is.opera){
				y -= kkjs.nummer(elter.style.borderTopWidth);
			}
			elter = elter.offsetParent;
		}
		return y;
	}
	if (kinder){
		for (var i=0;i<node.childNodes.length;i++){
			kkjs.koordAdd(node.childNodes[i],true);
		}
	}
	return node;
};

kkjs.tabelle = function tabelle(zeilen,spalten){
         zeilen = (!zeilen || isNaN(zeilen))? 0 : zeilen;
         spalten = (!spalten || isNaN(spalten))? 0 : spalten;
         var tab = new Array();
         tab[0] = document.createElement("table");
         var head = document.createElement("thead");
         var body = document.createElement("tbody");
         var foot = document.createElement("tfoot");
         tab[0].appendChild(head);
         tab[0].appendChild(body);
         tab[0].appendChild(foot);
         tab[0].border = 0;
         tab[0].style.borderSpacing = "0px";
         tab[0].cellSpacing = "0";
         tab[0].cellPadding = "0";

         for (var i = 1; i <= zeilen; i++){
             tab[i] = new Array();
             tab[i][0] = document.createElement("tr");
             body.appendChild(tab[i][0]);
             for (var j = 1; j <= spalten; j++){
                 tab[i][j] = document.createElement("td");
                 tab[i][0].appendChild(tab[i][j]);
             }
         }
         return tab;
};


kkjs.getDocument = function getDocument(node){
	if (!node) return document;
	if (!node.nodeType){
		if (node.document){
			return node.document;
		}
		else{
			return document;
		}
	}
	if (node.nodeType == 9) return node;
	if (node.ownerDocument) return node.ownerDocument;
	if (node.document) return node.document;
	while(node.nodeType != 9){
		if (!node.parentNode) break;
		node = node.parentNode;
	}
	if (node.nodeType != 9) return document;
	return node;
};

kkjs.getWindow = function getWindow(node){
	if (!node) return window;
	var doc = kkjs.getDocument(node);
	if (doc.parentWindow) return doc.parentWindow;
	if (doc.defaultView) return doc.defaultView;
	
	kkjs.Debug.error(1);
	return false;
};

kkjs.loadScript = function loadScript(url,ort){
	if (!ort) ort = document.getElementsByTagName("head")[0];
	var script = kkjs.getDocument(ort).createElement("script");
	script.type = "text/javascript";
	script.src = url;
	ort.appendChild(script);
	return script;
};

kkjs.loadPlugin = function loadPlugin(plugin,ort){
	if (kkjs.is.array(plugin)){
		var script = new Array();
		for (var i in plugin){
			if (!/\.js/.test(plugin[i])) plugin[i] = plugin[i] + ".js";
			script[i] = kkjs.loadPlugin(plugin[i], ort);
		}
		return script;
	}
	if (!/\.js/.test(plugin)) plugin = plugin + ".js";
	return kkjs.loadScript(kkjs.plugin_url + plugin, ort);
};


//Mein Event-Handling
kkjs.addEvent = function addEvent(node,event,func,bool){
	if (!bool){bool = false;}
	
	if (/_CASE!$/.test(event)){
		event = event.replace(/^on|_CASE!$/g, "");
	}
	else{
		event = event.replace(/^on/i,"").toLowerCase();
	}
	
	if (event == "selectionchange" ){
		node = new Array(node);
		event = new Array("mouseup", "mousedown", "keyup", "keypress");
		if (kkjs.is.ie){
			event.push("selectionchange");
		}
		func = new Array(func);
		bool = new Array(bool);
		for (var i = 0; i< event.length; i++){
			node[i] = node[0];
			func[i] = func[0];
			bool[i] = bool[0];
		}
	}
	
	function ADD(Node,Event,Func,Bool){
		if (Node.addEventListener){
			return Node.addEventListener(Event,Func,Bool);
		}
		if (Node.attachEvent){
			return Node.attachEvent('on'+Event,Func);
		}
		kkjs.Debug.error("Ihr Browser unterstützt diese Funktion nicht.");
		return false;
	}
	
	if (kkjs.is.array(node)){
		var ret = false;
		for(var i in node){
			ret = ADD(node[i],event[i],func[i],bool[i]);
		}
		return ret;
	}
	
	return ADD(node,event,func,bool);
};

kkjs.EventKontainer = function EventKontainer(){
	this.allFunctions = new Array();
	this.eventFunctions = new Object();
	this.getAllEvents = function(art){
		var ret = new Array();
		var functs = this.allFunctions;
		for (var i = 0; i < functs.length; i++){
			if (functs[i].type == art){
				ret.push(functs[i]);
			}
		}
		return ret;
	}
	this.getEvent = function(art, func){
		var functs = this.allFunctions;
		for (var i = functs.length-1; i >= 0 ; i--){
			if (functs[i].type == art && functs[i].func == func){
				return functs[i];
			}
		}
	}
	this.loescheEventVonAllFunctions = function(art, func){
		var event = this.getEvent(art, func);
		if (index = window.kkjs.getIndex(event, this.allFunctions)){
			this.allFunctions.splice(index, 1);
		}
		return this;
	}
};

kkjs.setzeEvent = function setzeEvent(node, eventType, func, amAnfang, useCapture){
	if (/_CASE!$/.test(eventType)){
		eventType = eventType.replace(/^on|_CASE!$/g, "");
	}
	else{
		eventType = eventType.replace(/^on/i,"").toLowerCase();
	}
	
	if (!amAnfang) amAnfang == false;
	if (!useCapture) useCapture == false;
	if (kkjs.is.undefined(node.events)){
		node.events = new kkjs.EventKontainer();
	}
	var ev = node.events;
	var newEvent ={
		type : eventType,
		func : func
	};
	
	if (!amAnfang){
		ev.allFunctions.push(newEvent);
	}
	else{
		var h = new Array(newEvent);
		ev.allFunctions = h.concat(ev.allFunctions);
		delete(h);
	}
	
	var typeEvents = ev.getAllEvents(eventType);
	var old_func = ev.eventFunctions[eventType];
	var new_func = function(event){
		if (!event) event = window.event;
		if (!event.target) event.target = event.srcElement;
		if (window.kkjs.is.undefined(event.which)) event.which = event.keyCode;
		var ret = new Array();
		for (var i = 0; i < typeEvents.length; i++){
			ret.push(typeEvents[i].func.call(node, event, node));
		}
		var Ret = true;
		for (var i = 0; i < ret.length ; i++){
			Ret = Ret && ret[i];
		}
		return Ret;
	}
	ev.eventFunctions[eventType] = new_func;
	kkjs.removeEvent(node, eventType + "_CASE!", old_func, useCapture);
	return kkjs.addEvent(node, eventType + "_CASE!", new_func, useCapture);
};

kkjs.addRightClickEvent = function addRightClickEvent(node, func){
	
	if (kkjs.is.undefined(node.rightClickFunctions)){
		node.rightClickFunctions = new Array();
	}
	
	node.rightClickFunctions.push(func);

	var f = function(ev, node){
		//kkjs.Debug.elementAlert(ev);
		if (ev.button == 2 || /contextmenu/i.test(ev.type)){
			
			if (!/contextmenu/i.test(ev.type)){
				var but = kkjs.createNode("input", {type: "button"}, {width: "100%", height: "100%", position: "fixed", left: "0px", top: "0px", backgroundColor: "transparent", border: "0px solid transparent", margin: "0px"});
				document.body.appendChild(but);
				
				kkjs.setzeEvent(document, "mouseup", function(){kkjs.removeNode(but); kkjs.loescheEvent(document, "mouseup", arguments.callee);});
			}
			
			for (var i = 0; i < node.rightClickFunctions.length; i++){
				node.rightClickFunctions[i](ev, node);
			}
			
			if (ev.stopPropagation) ev.stopPropagation();
			else ev.cancelBubble = true;
			
			if (ev.preventDefault) ev.preventDefault();
			return false;
		}
	};

	if (kkjs.is.opera){
		kkjs.setzeEvent(node, "mousedown", f);
	}
	else{
		kkjs.setzeEvent(node, "contextmenu", f);
	}
};

kkjs.removeRightClickEvent = function removeRightClickEvent(node, func){
	var is;
	if (is = getIndex(func, node.rightClickFunctions)){
		node.rightClickFunctions.splice(is, 1);
	}
};

kkjs.onWindowLoad = function onWindowLoad(func, win){
	if (!win) win = window;
	win = kkjs.getWindow(win);
	if (/loaded|complete/.test(win.document.readyState)) func();
	else kkjs.setzeEvent(win, "load", func, false);
};

kkjs.onDOMReady = function onDOMReady(func, win){
	if (!win) win = window;
	win = kkjs.getWindow(win);
	var doc = kkjs.getDocument(win);
	if (kkjs.is.key(doc, "onreadystatechange")){
		kkjs.setzeEvent(doc, "readystatechange", function(ev, node){
			var sc = kkjs.$("<script>", node);
			var sc_unready = false;
			for (var i = 0; i < sc.length; i++){
				if (sc[i].readyState && !/complete|loaded/i.test(sc[i].readyState)) sc_unready = i;
			}
			if (/interactive|complete|loaded/i.test(kkjs.getDocument(node).readyState)){
				if(kkjs.is['false'](sc_unready)){
					func(ev, node);
				}
				else{
					kkjs.setzeEvent(sc[sc_unready], "readystatechange", arguments.callee);
				}
				kkjs.loescheEvent(node,  "readystatechange", arguments.callee);
			}
		});
	}
	else if (kkjs.is.gecko) kkjs.setzeEvent(doc, "DOMContentLoaded_CASE!", func);
	else if (kkjs.exists(doc.readyState)) {
		win.setTimeout(function(){
			var sc = kkjs.$("<script>", document);
			var sc_ready = true;
			for (var i = 0; i < sc.length; i++){
				if (sc[i].readyState && !/complete|loaded/i.test(sc[i].readyState)) sc_ready = false;
			}
			if (sc_ready && /interactive|complete|loaded/i.test(this.document.readyState)){
				try{
					func(null, this.document);
				}
				catch(e){
					kkjs.onWindowLoad(func, this);
				}
			}
			else{
				this.setTimeout(arguments.callee, 10);
			}
		}, 10);
	}
	else {
		kkjs.Debug.error("Die onDOMReady-Funktion steht in ihrem Browser nicht zur Verfügung - es wird deswegen die onWindowLoad-Funktion verwendet.");
		kkjs.onWindowLoad(func, win);
	}
}

kkjs.removeEvent = function removeEvent(node,event,func,bool){
	if (!func) return;
	if (!bool){bool = false;}
	
	if (/_CASE!$/.test(event)){
		event = event.replace(/^on|_CASE!$/g, "");
	}
	else{
		event = event.replace(/^on/i,"").toLowerCase();
	}
	
	if (event == "selectionchange" ){
		node = new Array(node);
		event = new Array("mouseup", "mousedown", "keyup", "keypress");
		if (kkjs.is.ie){
			event.push("selectionchange");
		}
		func = new Array(func);
		bool = new Array(bool);
		for (var i = 0; i< event.length; i++){
			node[i] = node[0];
			func[i] = func[0];
			bool[i] = bool[0];
		}
	}
	
	function REMOVE(Node,Event,Func,Bool){
		if (Node.addEventListener){
			return Node.removeEventListener(Event,Func,Bool);
		}
		if (Node.attachEvent){
			return Node.detachEvent('on'+Event,Func);
		}
		kkjs.Debug.error(1);
		return false;
	}
	
	if (kkjs.is.array(node)){
		var ret = false;
		for(var i in node){
			ret = REMOVE(node[i],event[i],func[i],bool[i]);
		}
		return ret;
	}
	
	return REMOVE(node,event,func,bool);
};

kkjs.loescheEvent = function loescheEvent(node, eventType, func, useCapture){
	if (/_CASE!$/.test(eventType)){
		eventType = eventType.replace(/^on|_CASE!$/g, "");
	}
	else{
		eventType = eventType.replace(/^on/i,"").toLowerCase();
	}
	
	if (!useCapture) useCapture == false;
	if (kkjs.is.undefined(node.events)){
		node.events = new kkjs.EventKontainer();
	}
	var ev = node.events;
	ev.loescheEventVonAllFunctions(eventType, func);
	var typeEvents = ev.getAllEvents(eventType);
	var old_func = ev.eventFunctions[eventType];
	var new_func = function(event){
		if (!event) event = window.event;
		if (!event.target) event.target = event.srcElement;
		if (!event.which) event.which = event.keyCode;
		var ret = new Array();
		for (var i = 0; i < typeEvents.length; i++){
			ret.push(typeEvents[i].func.call(node, event, node));
		}
		var Ret = true;
		for (var i = 0; i < ret.length ; i++){
			Ret = Ret && ret[i];
		}
		return Ret;
	}
	ev.eventFunctions[eventType] = new_func;
	kkjs.removeEvent(node, eventType + "_CASE!", old_func, useCapture);
	return kkjs.addEvent(node, eventType + "_CASE!", new_func, useCapture);
};

kkjs.loescheAlleEvents = function loescheAlleEvents(node, art){
	if (!art){
		for (var i = 0; i < node.events.allFunctions.length; i){
			kkjs.loescheEvent(node, node.events.allFunctions[i].type, node.events.allFunctions[i].func);
		}
	}
	else{
		art = art.replace(/^on/,"").toLowerCase();
		for (var i = 0; i < node.events.allFunctions.length; i++){
			if (art == node.events.allFunctions[i].type){
				kkjs.loescheEvent(node, node.events.allFunctions[i].type, node.events.allFunctions[i].func);
				i--;
			}
		}
	
	}
};

kkjs.getWorkingEvent = function getWorkingEvent(event){
		if (document.createEventObject) return document.createEventObject(event);
		if (document.createEvent){
			var ev = document.createEvent("UIEvents");
			ev.initEvent(event.type,true,true);
			for (var i in event){
				try{
					ev[i] = event[i];
				}
				catch(e){}
			}
			return ev;
		}
};

kkjs.fireEvent = function fireEvent(node, event, cancelBubble){
	if (!node) node = document;
	if (!event) event = "click";
	if (!cancelBubble) cancelBubble = false;
	if (typeof(event) == "string")event = event.replace(/^on/i,"").toLowerCase();
	
	if (node.fireEvent){
		if (typeof (event) == "string") node.fireEvent("on" + event);
		else {
			node.fireEvent("on" + event.type, event);
			event.cancelBubble = cancelBubble;
		}
		return true;
	}
	if (document.createEvent){
		var ev = event;
		if (typeof(event) == "string"){
			ev = document.createEvent("UIEvents");
			ev.initEvent(event,true,true);
		}
		
		ev.cancelBubble = cancelBubble;
		return node.dispatchEvent(ev);
	}
};

kkjs.fireOwnEvent = function fireOwnEvent(node, event, ev, cancelBubble){
	if (/_CASE!$/.test(event)){
		event = event.replace(/_CASE!$/, "");
	}
	else{
		event = event.replace(/^on/i,"").toLowerCase();
	}
	var ret = true;
	
	if (node.events){
		if (node.events.eventFunctions[event]){
			if (!ev){
				if (document.createEvent){
					ev = document.createEvent("UIEvents");
					ev.initEvent(event, true, true);
					node.dispatchEvent(ev);
				}
			}
			ret = node.events.eventFunctions[event](ev, node);
		}
	}
	if (!cancelBubble && node.parentNode){
		ret = ret && kkjs.fireOwnEvent(node.parentNode, event + "_CASE!", ev);
	}
	return ret;
};

kkjs.handleKeyEvents = function handleKeyEvents(node){
	if (!node.handleKeyEvents){
		kkjs.setzeEvent(node, "keyup", function(ev, node){
			var type = "up";
			var mod = "";
			if (ev.ctrlKey) mod += "ctrl+";
			if (ev.altKey) mod += "alt+";
			
			var code = ev.which;
			//if (ev.keyCode && ev.keyCode != code) alert("Differenz zwischen keyCode(" + ev.keyCode + ") und which(" + code + ").");
			//window.status = "up:" + code + " -> " + kkjs.constTabelle.keyCodes2[code];if(!kkjs.constTabelle.keyCodes2[code])alert("Diese Taste ist noch nicht zugeordnet! (" + code + ")");
			var buch = "";
			if (kkjs.constTabelle.keyCodes2[code]) buch = kkjs.constTabelle.keyCodes2[code];
			else if (String.fromCharCode(code)) buch = String.fromCharCode(code);
			else return;
			
			ev.taste = buch;
			var res = new Array(/^\w$/, /^\W$/, /^\D$/, /^\d$/, /^\s$/);
			
			for (var i = 0; i < res.length; i++){
				if (res[i].test(buch)) kkjs.fireOwnEvent(node, "key" + mod + res[i].toString().replace(/\/\^|\$\/|\//g, "") + type + "_CASE!", ev, true);
			}
			
			return kkjs.fireOwnEvent(node, "key" + mod + buch + type + "_CASE!", ev, true);
		});
		kkjs.setzeEvent(node, "keydown", function(ev, node){
			var type = "down";
			var mod = "";
			if (ev.ctrlKey) mod += "ctrl+";
			if (ev.altKey) mod += "alt+";
			
			var code = ev.which;
			//if (ev.keyCode && ev.keyCode != code) alert("Differenz zwischen keyCode(" + ev.keyCode + ") und which(" + code + ").");
			//window.status = "down:" + code + " -> " + kkjs.constTabelle.keyCodes2[code];if(!kkjs.constTabelle.keyCodes2[code])alert("Diese Taste ist noch nicht zugeordnet!^^");
			var buch = "";
			if (kkjs.constTabelle.keyCodes2[code]) buch = kkjs.constTabelle.keyCodes2[code];
			else if (String.fromCharCode(code)) buch = String.fromCharCode(code);
			else return;
			
			ev.taste = buch;
			var res = new Array(/^\w$/, /^\W$/, /^\D$/, /^\d$/, /^\s$/);
			
			for (var i = 0; i < res.length; i++){
				if (res[i].test(buch)) kkjs.fireOwnEvent(node, "key" + mod + res[i].toString().replace(/\/\^|\$\/|\//g, "") + type + "_CASE!", ev, true);
			}
			
			return kkjs.fireOwnEvent(node, "key" + mod + buch + type + "_CASE!", ev, true);
		});
		kkjs.setzeEvent(node, "keypress", function(ev, node){
			var type = "press";
			var mod = "";
			if (ev.ctrlKey) mod += "ctrl+";
			if (ev.altKey) mod += "alt+";
			
			var code = ev.which;
			//if (ev.keyCode && ev.keyCode != code) alert("Differenz zwischen keyCode(" + ev.keyCode + ") und which(" + code + ").");
			//window.status = "press:" + code + " -> " + String.fromCharCode(code);
			var buch = "";
			if (String.fromCharCode(code)) buch = String.fromCharCode(code);
			else return;
			
			ev.taste = buch;
			var res = new Array(/^\w$/, /^\W$/, /^\D$/, /^\d$/, /^\s$/);
			
			for (var i = 0; i < res.length; i++){
				if (res[i].test(buch)) kkjs.fireOwnEvent(node, "key" + mod + res[i].toString().replace(/\/\^|\$\/|\//g, "") + type + "_CASE!", ev, true);
			}
			
			return kkjs.fireOwnEvent(node, "key" + mod + buch + type + "_CASE!", ev, true);
		});
	}
	
	node.handleKeyEvents = true;
};

kkjs.cancelAllBubble = function cancelAllBubble(node, art){
	function cancel(ev){
		if (ev.stopPropagation) ev.stopPropagation;
		if (!kkjs.is.undefined(ev.cancelBubble)) ev.cancelBubble = true;
	}
	if (/key/.test(art)){
		kkjs.setzeEvent(node, "keydown", cancel);
		kkjs.setzeEvent(node, "keyup", cancel);
		kkjs.setzeEvent(node, "keypress", cancel);
	}
	if (/mouse/.test(art)){
		kkjs.setzeEvent(node, "mousedown", cancel);
		kkjs.setzeEvent(node, "mouseup", cancel);
		kkjs.setzeEvent(node, "click", cancel);
		kkjs.setzeEvent(node, "dblclick", cancel);
		kkjs.setzeEvent(node, "mousemove", cancel);
	}
	if (/context/.test(art)) kkjs.setzeEvent(node, "contextmenu", cancel);
};


kkjs.ueberwacheVariable = function ueberwacheVariable(obj, id, func, forceWaechter){
	if (!forceWaechter && obj.watch) obj.watch(id, func);
	else{
		function Waechter(obj, id, func){
			this.obj = obj;
			this.id = id;
			this.func = func;
			this.wertAlt = obj[id];
			this.test = function(){
				if (this.obj[this.id] != this.wertAlt){
					this.func(id, this.wertAlt, this.obj[this.id]);
					this.wertAlt = this.obj[this.id];
				}
			}
			
			window.setInterval(kkjs.bindObj(this, this.test), 100);
		}
		
		var f = new Waechter(obj, id, func);
	}
};


kkjs.getScriptNodeArguments = function getScriptNodeArguments(node){
	if (!node.src) return new Object();
	if (!node.src.match(/\?(.+$)/)) return new Object();
	var args = RegExp.$1;
	var args = args.split("&");
	//alert(args);
	var ret = new Object();
	
	for (var i = 0; i < args.length; i++){
		var name = args[i].split("=")[0];
		var wert = args[i].split("=")[1];
		ret[name] = wert;
	}
	
	return ret;
};


// kkjs.Debug - Elemente (wird für fast alle anderen nuetzlich -Module gebraucht)
kkjs.Debug = {
	status : true,
	
	getElements : function(obj,re, wre){
		if (!re){ re = /./;}
		if (!wre){ wre = /.*/;}
		
		var name = "[object]";
		if (kkjs.is.undefined(obj)) name = "undefined";
		else if (obj.toString) name = obj.toString();
		
		if (name.length > 50) {name = name.substring(0,50) + " ...";}
		
		var text = "Elemente von " + name + " :\n";
		for(var i in obj){
			var wert = "nicht anzeigbar";
			try{
				//if (!kkjs.is.null(obj[i]) && obj[i].toString) 
				wert = obj[i].toString();
				if (re.test(i) && wre.test(wert)){
					text += i + ": " + wert + "\n";
				}
			}catch(e){
				text += i + ": nicht anzeigbar\n";
			}
		}
		return text;
	},
	
	alert : function(str){
		if (this.status){
			if (/\n/.test(str)){
				alert(str);
			}
			else{
				window.status = "Bereit";
				if (window.status == "Bereit"){
					window.status = str;
				}
				else{
					alert(str);
				}
			}
			return true;
		}
		else {
			window.status = "kkjs.Debug.alert(" + str + ")";
		}
		return false;
	},
	
	elementAlert : function(obj,re, wre){
		return this.alert(this.getElements(obj,re, wre));
	},
	
	errorList : new Array("Unbekannter Fehler", "Ihr Browser unterstützt diese Funktion nicht."),
	
	error : function(errorNumber){
		var name = kkjs.Debug.error.caller.toString().match(/function\s+([^\(\)]+)\(/)[1];
		
		if (typeof(errorNumber) == "string") errorString = name + "() -> Fehler: " + errorNumber;
		else {
			if (!errorNumber || typeof(errorNumber) != "number" || errorNumber >= this.errorList.length) errorNumber = 0;
			errorString = name + "() -> Fehler: " + this.errorList[errorNumber];
		}
		this.alert(errorString);
		return;
	},
	
	insertDebugConsole : function(){
		if (kkjs.$("kkjs_DebugConsole")) return;
		kkjs.Debug.status = true;
		
		var console = document.createElement("div");
		kkjs.cancelAllBubble(console, "key+mouse");
		
		console.id = "kkjs_DebugConsole";
		console.style.position = "fixed";
		console.style.bottom = "0px";
		console.style.left = "0px";
		console.style.width = "100%";
		console.style.backgroundColor = "buttonface";
		console.style.padding = "0px 5px 5px 5px";
		document.body.appendChild(console);
		
		var link = kkjs.createNode("div", {innerHTML: "Debug Console", onclick: function(){
			document.body.style.paddingBottom = kkjs.nummer(document.body.style.paddingBottom) - this.parentNode.offsetHeight + "px";
			kkjs.toggle(this.nextSibling);
			kkjs.toggle(this);
			document.body.style.paddingBottom = kkjs.nummer(document.body.style.paddingBottom) + this.parentNode.offsetHeight + "px";
			}}, {textAlign: "center", cursor: "pointer", fontSize: "8pt", color: "#777777"});
		console.appendChild(link);
		
		var tab = kkjs.tabelle(3, 4);
		console.appendChild(tab[0]);
		
		tab[0].style.width = "100%";
		tab[0].style.display = "none";
		tab[2][0].style.width = "100%";
		tab[2][1].style.whiteSpace = "noWrap";
		tab[3][1].style.whiteSpace = "noWrap";
		tab[2][2].style.width = "100%";
		tab[0].style.paddingRight = "6px";
		
		tab[1][2].innerHTML = "Debug Console (kkjs ver. 1.0)";
		tab[1][2].style.cssText = "text-align: center; color: #777777; font-size: 10pt; font-family: Times New Roman; font-style: italic;";
		
		var schliessen = kkjs.createCloseButton(function(ev, node){
			document.body.style.paddingBottom = kkjs.nummer(document.body.style.paddingBottom) - node.link.parentNode.offsetHeight + "px";
			kkjs.toggle(node.link);
			kkjs.toggle(kkjs.getParentNodeByTagName(node, "table"));
			document.body.style.paddingBottom = kkjs.nummer(document.body.style.paddingBottom) + node.link.parentNode.offsetHeight + "px";
		});
		kkjs.cancelAllBubble(schliessen, "mouse");
		schliessen.link = link;
		schliessen.style.position = "static";
		tab[0].x = schliessen;
		tab[1][4].style.direction = "rtl";
		tab[1][4].style.paddingTop = tab[1][4].style.paddingBottom = "2px";
		tab[1][4].appendChild(schliessen);
		tab[1][0].style.cursor = "pointer";
		kkjs.setzeEvent(tab[1][0], "click", function(ev, node){kkjs.fireEvent(kkjs.getParentNodeByTagName(node, "table").x, "mouseup");});
		
		tab[2][1].appendChild(document.createTextNode("Befehl: "));
		var cmdFeld = document.createElement("input");
		if (document.cookie.match(/kkjs_DebugConsoleBefehl\s*=\s*([^;]+)/)){
			cmdFeld.value = decodeURIComponent(RegExp.$1);
		}
		cmdFeld.style.width = "98%";
		cmdFeld.onkeypress = function(event){
			if (!event) event = window.event;
			if (event.keyCode == 13){
				this.button.click();
			}
		};
		tab[2][2].appendChild(cmdFeld);
		var cmdButton = document.createElement("input");
		cmdButton.type = "button";
		cmdButton.value = "ausf" + String.fromCharCode(252) + "hren";
		cmdButton.feld = cmdFeld;
		cmdFeld.button = cmdButton;
		cmdButton.onclick = function (){
			try{
				document.cookie = "kkjs_DebugConsoleBefehl=" + encodeURIComponent(this.feld.value);
				eval(this.feld.value);
			}
			catch(e){
				kkjs.Debug.elementAlert(e);
			}
		}
		tab[2][3].appendChild(cmdButton);
		
		var DOMButton = document.createElement("input");
		DOMButton.type = "button";
		DOMButton.value = "DOM";
		DOMButton.title = "DOM Inspektor initialisieren";
		DOMButton.onclick = kkjs.Debug.makeDOMInspector;
		tab[2][4].appendChild(DOMButton);
		
		tab[3][1].appendChild(document.createTextNode("zu lesende Instanz: "));
		
		var readFeld = document.createElement("input");
		if (document.cookie.match(/kkjs_DebugConsoleRead\s*=\s*([^;]+)/)){
			readFeld.value = decodeURIComponent(RegExp.$1);
		}
		readFeld.style.width = "98%";
		readFeld.onkeypress = function(event){
			if (!event) event = window.event;
			if (event.keyCode == 13){
				this.button.click();
			}
		};
		tab[3][2].appendChild(readFeld);
		var readButton = document.createElement("input");
		readButton.type = "button";
		readButton.value = "lesen";
		readButton.feld = readFeld;
		readFeld.button = readButton;
		readButton.onclick = function (){
			try{
				document.cookie = "kkjs_DebugConsoleRead=" + encodeURIComponent(this.feld.value);
				var node = eval(this.feld.value);
				if (typeof(node) == "string") alert(node);
				else kkjs.Debug.elementAlert(node);
			}
			catch(e){
				kkjs.Debug.elementAlert(e);
			}
		}
		tab[3][3].appendChild(readButton);
		
		document.body.style.paddingBottom = kkjs.nummer(document.body.style.paddingBottom) + console.offsetHeight + "px";
		return;
	},
	
	makeDOMInspector : function(){
		var DOM = window.open("about:blank","_blank");
		
		kkjs.Debug.DOM = DOM;
		
		DOM.document.open();
		DOM.document.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8" /><link rel=stylesheet type="text/css" href="' + kkjs.plugin_url +'nuetzlich/DOM_Inspector.css" /><script type="text/javascript" src="' + kkjs.plugin_url + 'nuetzlich.js?plugin=nuetzlich/DOM_Inspector"></script></head><body><table style="table-layout: fixed;width:100%; height : 100%; border: black 1px solid;"><tr style="vertical-align: top;"><td><input type="button" value="baum aktualisieren" onclick="baumAktualisieren();"</td><td><a id="ort">&nbsp;</a><br />Schlüssel Filter: <input id="key_filter" title="Schlüssel Filter" onchange="search();" onkeyup="search();"/><br />Element enthalten?:<input id="hasAttrib"  onchange="testElement(this.value, true);" onkeyup="testElement(this.value, true);" /><input type="button" value="ansehen" onclick="gefundenesElementAnsehen()" /><br />Wert Filter: <input id="wert_filter" title="Wert Filter" onchange="search();" onkeyup="search();"/></td></tr><tr><td id="baum"></td><td id="details">&nbsp;</td></tr></table></body></html>')
		DOM.document.close();
	}
};

kkjs.createApplet = function createApplet(url, style, applet){
	url.match(/^(.+)[\\\/]([^\\\/]+)$/);
	var codeBase = RegExp.$1, code;
	if (url.match(/^(.+)[\\\/]([^\\\/]+)$/)){
		code = RegExp.$2;
	}
	else {
		code = url;
		codeBase = ".";
	}
	
	if (!applet){
		var node = kkjs.createNode("object", null, style);
		//wäre schön, wenn man hier anstatt der null {classid: "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93", type: "application/x-java-applet"} als Übergabeparameter für die Attribute eingeben könnte
		
		if (kkjs.is.ie){
			if (node.readyState < 4){
				setTimeout(function(){
					node.classid = 'clsid:8AD9C840-044E-11D1-B3E9-00805F499D93';
				}, 0);
			}
			else{
				kkjs.setzeEvent(node, "readystatechange", function(ev, node){
					node.classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
				});
			}
		}
		else{
			node.type = "application/x-java-applet";
		}
		
		var Code = kkjs.createNode("param", {name: "code", value: code});
		node.appendChild(Code);
		
		if (codeBase && codeBase != ""){
			var CodeBase = kkjs.createNode("param", {name: "codeBase", value: codeBase});
			node.appendChild(CodeBase);
		}
		
		return node;
	}
	
	return kkjs.createNode("applet", {code: code, codeBase: codeBase}, style);
};

kkjs.createCSSRule = function createCSSRule(rule, index){
	/^([^{}]+)/.test(rule);
	var bezeichner = RegExp.$1;
	/{([^{}]+)}/.test(rule);
	var regel = RegExp.$1;
	
	if (bezeichner.match(/,/)){
		bezeichner = bezeichner.split(",");
		for (var i = 0; i < bezeichner.length; i++){
			kkjs.createCSSRule(bezeichner[i] + "{" + regel + "}", index)
		}
		return;
	}
	
	var style = document.styleSheets;
	
	function cannotread(st){
		if (!kkjs.is.undefined(st.readOnly) && st.readOnly) return true;
		if (!kkjs.is.undefined(st.rules) && !st.rules) return true;
		try{
			if (!kkjs.is.undefined(st.cssRules) && !st.cssRules) return true;
		}
		catch(e){
			return true;
		}
		return false;
	}
	
	for (var i = 0; i < style.length && cannotread(style[i]); i++){}
	if (i == style.length){
		if (document.createStyleSheet){
			style = document.createStyleSheet();
		}
		else {
			style = kkjs.createNode("style");
			kkjs.$("<head>")[0].appendChild(style);
			//return kkjs.Debug.error(1);
			style = document.styleSheets[document.styleSheets.length - 1];
		}
	}
	else {
		style = style[i];
	}
	
	if (isNaN(index)){
		if (style.rules){
			index = style.rules.length;
		}
		else if(style.cssRules){
			index = style.cssRules.length;
		}
		else{
			return kkjs.Debug.error(1);
		}
	}
	if (kkjs.is.ie && kkjs.is.version < 7){
		bezeichner = bezeichner.replace(/>|\+/g, "");
	}
	if (style.addRule){
		style.addRule(bezeichner, regel, index);
		return;
	}
	else if (style.insertRule){
		style.insertRule(rule, index);
		return;
	}
	
	kkjs.Debug.error(1);
};

kkjs.createInlineJS = function createInlineJS(JS, parentNode){
	if (!parentNode) parentNode = kkjs.$("<head>")[0];
	
	var script = kkjs.createNode("script", {type: "text/javascript", text: JS});
	parentNode.appendChild(script);
	
	return script;
};


kkjs.dialog = function dialog(titel, inhaltNode){
	if (kkjs.$("kkjs_dialog"))kkjs.$("kkjs_dialog").close();
	kont = kkjs.createNode(
		"div",
		{className: "kkjs_dialog", id: "kkjs_dialog"},
		{position: "fixed", top: "20px", left: "200px",  overflow: "hidden"}
	);
	document.body.appendChild(kont);
	kont.close = function(ev, node){
		if (!ev || (kkjs.getFirstCommonNode(ev.target, kkjs.$("kkjs_dialog")) != kkjs.$("kkjs_dialog") && !ev.createDialog) || node.className == "kkjs_closeButton"){
			var Dialog = kkjs.$("kkjs_dialog")
			kkjs.removeNode(Dialog);
			delete(Dialog);
			kkjs.loescheEvent(document, "mousedown", arguments.callee);
			kkjs.loescheEvent(document, "keyescup", arguments.callee);
		}
	}
	if (!kkjs.is.undefined(inhaltNode) && inhaltNode.nodeName) kont.appendChild(inhaltNode);
	
	if (titel){

		var kopf = kkjs.createHorizontalVerlaufNode( 200, 20, "#666666", "#FFFFFF");
		kopf.style.width = kont.offsetWidth + "px";
		kopf.style.marginBottom = "10px";
		kopf.style.position = "relative";
		var titel = kkjs.createNode("div", {innerHTML: titel}, {position: "absolute", top: "0px", left: "2px", fontSize: "16px", fontWeight: "bold", color: "#FFFFFF", backgroundColor: "transparent"});
		var x = kkjs.createCloseButton( kont.close);
		kont.kopf = kopf;
		kont.titel = titel;
		kopf.appendChild(titel);
		kopf.appendChild(x);
		kont.insertBefore(kopf, kont.firstChild);
		
		if (kkjs.bewegen) kkjs.bewegen.bewegbar(kont, kopf);
		
	}
	
	//if (kkjs.resize) kkjs.resize.resizebar(kont, kopf);
	
	kkjs.setzeEvent(document, "mousedown", kont.close);
	kkjs.handleKeyEvents(document);
	kkjs.setzeEvent(document, "keyescup", kont.close);
	
	return kont;
};

kkjs.createCloseButton = function createCloseButton(func){
	var x = kkjs.createNode(
		"div",
		{innerHTML: "&times;", className: "kkjs_closeButton"},
		{position: "absolute", top: "1px", right: "1px", width: "10px", height: "10px", backgroundColor: "buttonface", fontFamily: "Arial", fontWeight: "900", textAlign: "center", cursor: "default", fontSize: "18px", lineHeight: "10px"}
	);
	if (!kkjs.is.ie) x.style.lineHeight = "8px";
	kkjs.setzeEvent(x, "mouseup", func);
	
	return x;
};


kkjs.kontextMenu = function kontextMenu(){
	this.menu = kkjs.createNode("div");
	this.kontextMenu = this;
	
	this.add = function(text, func){
		var div = kkjs.createNode("div", {innerHTML: text, className: "kkjs_kontextMenuEintrag"}, {cursor: "default"});
		div.func = func;
		div.kontextMenu = this.kontextMenu;
		kkjs.setzeEvent(div, "click", function(ev, node){
			kkjs.$("kkjs_dialog").close();
			node.func(node.kontextMenu.self);
		});
		
		if (kkjs.is.opera){
			document.body.appendChild(div);
			div.style.position = "absolute";
			this.maxWidth = kkjs.max(new Array(this.maxWidth, div.offsetWidth));
			this.menu.style.width = this.maxWidth + "px";
			div.style.position = "";
		}
		this.menu.appendChild(div);
		return div;
	};
	this.addSubMenu = function(text){
		var div = kkjs.createNode("div",  {innerHTML: text , className: "kkjs_kontextMenuSubMenu"}, {cursor: "default"});
		
		var pf = kkjs.createNode("div", {innerHTML: "►"}, {position: "absolute", bottom: "2px", right: "2px", color: "#666666"});
		div.appendChild(pf);
		
		var menu = kkjs.createNode("div",  {className: "kkjs_dialog"}, {cursor: "default"});
		div.appendChild(menu);
		div.menu = menu;
		div.kontextMenu = this.kontextMenu;
		this[text] = div;
		
		div.add = this.add
		div.addSubMenu = this.addSubMenu;
		div.addSeparator = this.addSeparator;
		
		if (kkjs.is.opera){
			document.body.appendChild(div);
			div.style.position = "absolute";
			this.maxWidth = kkjs.max(new Array(this.maxWidth, div.offsetWidth));
			this.menu.style.width = this.maxWidth + "px";
			div.style.position = "";
		}
		this.menu.appendChild(div);
		return div;
	};
	this.addSeparator = function(){
		var div = kkjs.createNode("div", null, {margin: "2px", borderBottom: "1px buttonShadow solid"});
		this.menu.appendChild(div);
	};
	
	this.open = function(ev, node){
		var kontextMenu = node.kontextMenu;
		kontextMenu.self = node;
		
		var Dialog = kkjs.dialog(false, kontextMenu.menu);
		Dialog.style.overflow = "visible";
		var pos = new kkjs.array(ev.clientX, ev.clientY).add(5);
		var win = kkjs.getWindowSize();
		if (pos[0] + Dialog.offsetWidth > win[0]){
			pos[0] -= 10 + Dialog.offsetWidth;
		}
		if (pos[1] + Dialog.offsetHeight > win[1]){
			pos[1] -= 10 + Dialog.offsetHeight;
		}
		Dialog.style.left = pos[0] + "px";
		Dialog.style.top = pos[1] + "px";
		
		ev.createDialog = "true";
		return false;
	};
	
	this.registerNode = function(node){
		node.kontextMenu = this;
		
		kkjs.addRightClickEvent(node, this.open);
	};
};


kkjs.encodeBase64 = function encodeBase64(str){
	var base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	var addedNull = 0;
	while (str.length % 3 != 0){
		addedNull++;
		str += String.fromCharCode(0);
	}
	var ret = "";
	for (var i = 0; i < str.length; i += 3){
		var tripple = (str.charCodeAt(i) << 16) + (str.charCodeAt(i+1) << 8) + str.charCodeAt(i+2); 
		
		ret += base.charAt(tripple >> 18);
		tripple = tripple & 262143;
		ret += base.charAt(tripple >> 12);
		tripple = tripple & 4095;
		ret += base.charAt(tripple >> 6);
		tripple = tripple & 63;
		ret += base.charAt(tripple);
	}
	
	ret = ret.substring(0, ret.length - addedNull);
	for (var i = 0; i < addedNull; i++){
		ret += "=";
	}
	return ret;
}
kkjs.decodeBase64 = function decodeBase64(str){
	str = str.replace(/[\s\n\r]/g, "");
	var base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	var addedNull = 0;
	str = str.replace(/=*$/, function(match){
		addedNull = match.length;
		var ret = "";
		while(ret.length < addedNull) ret += "A";
		return ret;
	});
	
	var ret = "";
	for (var i = 0; i < str.length; i += 4){
		var quadro=(base.indexOf(str.charAt(i))<<18) + (base.indexOf(str.charAt(i+1))<<12) + (base.indexOf(str.charAt(i+2))<<6) + base.indexOf(str.charAt(i+3));
		
		ret += String.fromCharCode(quadro >> 16);
		quadro = quadro & 65535;
		ret += String.fromCharCode(quadro >> 8);
		quadro = quadro & 255;
		ret += String.fromCharCode(quadro);
	}
	return ret.substring(0, ret.length - addedNull);
}

kkjs.encodeUTF8 = function encodeUTF8(str){
	var ret = "";
	for (var i = 0; i < str.length; i++){
		var chr = str.charCodeAt(i);
		if (chr < 128){
			ret += str.charAt(i);
		}
		else{
			var blocks = new Array();
			var beginn = 128;
			var plus = 128;
			while (beginn + chr > 255 - (plus>>1)){
				var last = (63 & chr) + 128;
				chr = chr >> 6;
				plus = plus>>1;
				beginn += plus;
				blocks.push(last);
			}
			blocks.push(beginn + chr);
			
			for (var j = blocks.length - 1; j >= 0; j--){
				ret += String.fromCharCode(blocks[j]);
			}
		}
	}
	return ret;
}
kkjs.decodeUTF8 = function decodeUTF8(str){
	var errorChar = String.fromCharCode(65533);
	var btes = new Array(str.length);
	for (var i = 0; i < str.length; i++){
		btes[i] = str.charCodeAt(i);
	}
	var ret = "";
	for (var i = 0; i < btes.length; i++){
		if (btes[i] < 128){
			ret += str.charAt(i);
			continue;
		}
		if (btes[i] < 192){
			ret += errorChar;
			continue;
		}
		var block = btes[i];
		var error = false;
		var length = 0;
		while ((((128>>length)|block) == block) && (block > 0)){
			block -= 128>>length;
			length++;
		}
		for (var j = 1; j < length; j++){
			var help = btes[i + j];
			if (help < 128 || help >= 192){
				error = true;
				break;
			}
			help -= 128;
			block = (block<<6) + help;
		}
		i += length - 1;
		
		if (error){
			ret += errorChar;
		}
		else {
			ret += String.fromCharCode(block);
		}
	}
	
	return ret;
}


kkjs.sha256 = function sha256(str){
	// Algorithmus aus http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode

	function int32(n){
		// Nur die ersten 32 Bit stehen lassen und das Problem mit den negativen Zahlen umgehen (0xFFFFFFFF >> 1 == -1; 0xFFFFFFFF >>> 1 == 0x7FFFFFFF und -1 >>> 0 == 0xFFFFFFFF)
		return ((n & 0xFFFFFFFF) >>> 0);
	};
	function leftRotate(a, n){
		a = int32(a);
		return int32(int32(a<<n) | int32(a>>>(32-n)));
	}
	function rightRotate(a, n){
		return leftRotate(a, 32 - n);
	}
	
	// Byteweises einlesen des Eingabestrings
	var btes = new Array();
	for (var i = 0; i < str.length; i++){
		var chr = str.charCodeAt(i);
		while (chr > 255){
			var helpChr = chr;
			var rot = 0;
			while (helpChr > 255){
				helpChr >>= 8;
				rot++;
			}
			btes.push(helpChr);
			chr = chr & ((1<<(rot*8)) - 1);
		}
		btes.push(chr);
	}
	
	var h0 = 0x6a09e667;
	var h1 = 0xbb67ae85;
	var h2 = 0x3c6ef372;
	var h3 = 0xa54ff53a;
	var h4 = 0x510e527f;
	var h5 = 0x9b05688c;
	var h6 = 0x1f83d9ab;
	var h7 = 0x5be0cd19;
	
	var k = new Array(
	   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
	   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
	   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
	   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
	   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
	   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
	   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
	   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2);
	
	var messageBitLength = btes.length * 8;
	btes.push(0x80);
	while(btes.length % 64 !=56){
		btes.push(0);
	}
	
	var lengthBytes = new Array();
	for (var i = 0; i < 8; i++){
		var bte = messageBitLength & 255;
		lengthBytes.push(bte);
		messageBitLength >>>= 8;
	}
	//Aus little Endian big Endian machen und anhängen
	for (var i = 7; i >= 0; i--){
		btes.push(lengthBytes[i]);
	}
	
	for (var i = 0; i < btes.length; i += 64){
		var w = new Array(16);
		for (var j = 0; j < 16; j++){
			w[j] = int32(
					int32(btes[i + 0 + (j*4)] << 24) |
					int32(btes[i + 1 + (j*4)] << 16) |
					int32(btes[i + 2 + (j*4)] << 8 ) |
					int32(btes[i + 3 + (j*4)] << 0 )
				);
		}
		for (var j = 16; j < 64; j++){
			var s0 = rightRotate(w[j-15], 7) ^ rightRotate(w[j-15], 18) ^ (w[j-15] >>> 3)
			var s1 = rightRotate(w[j-2], 17) ^ rightRotate(w[j-2], 19) ^ (w[j-2] >>> 10)
			w[j] = int32(w[j-16] + s0 + w[j-7] + s1);
		}
		
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		var f = h5;
		var g = h6;
		var h = h7;
		
		for (var j = 0; j < 64; j++){
			var s0 = rightRotate(a, 2) ^ rightRotate(a, 13) ^ rightRotate(a, 22);
			var maj = int32(a & b) ^ int32(a & c) ^ int32(b & c);
			var t2 = int32(s0 + maj);
			var s1 = rightRotate(e, 6) ^ rightRotate(e, 11) ^ rightRotate(e, 25);
			var ch = int32(e & f) ^ int32(int32(~ e) & g);
			var t1 = int32(h + s1 + ch + k[j] + w[j]);
			
			h = g;
			g = f;
			f = e;
			e = int32(d + t1);
			d = c;
			c = b;
			b = a;
			a = int32(t1 + t2);
		}
		
		h0 = int32(h0 + a);
		h1 = int32(h1 + b);
		h2 = int32(h2 + c);
		h3 = int32(h3 + d);
		h4 = int32(h4 + e);
		h5 = int32(h5 + f);
		h6 = int32(h6 + g);
		h7 = int32(h7 + h);
	}
	
	return h0.toHex(8) + h1.toHex(8) + h2.toHex(8) + h3.toHex(8) + h4.toHex(8) + h5.toHex(8) + h6.toHex(8) + h7.toHex(8);
}
kkjs.sha1 = function sha1(str){
	// Algorithmus aus http://de.wikipedia.org/wiki/Secure_Hash_Algorithm

	function int32(n){
		// Nur die ersten 32 Bit stehen lassen und das Problem mit den negativen Zahlen umgehen (0xFFFFFFFF >> 1 == -1; 0xFFFFFFFF >>> 1 == 0x7FFFFFFF und -1 >>> 0 == 0xFFFFFFFF)
		return ((n & 0xFFFFFFFF) >>> 0);
	};
	function leftRotate(a, n){
		a = int32(a);
		return int32(int32(a<<n) | int32(a>>>(32-n)));
	}
	
	// Byteweises einlesen des Eingabestrings
	var btes = new Array();
	for (var i = 0; i < str.length; i++){
		var chr = str.charCodeAt(i);
		while (chr > 255){
			var helpChr = chr;
			var rot = 0;
			while (helpChr > 255){
				helpChr >>= 8;
				rot++;
			}
			btes.push(helpChr);
			chr = chr & ((1<<(rot*8)) - 1);
		}
		btes.push(chr);
	}
	
	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;
	
	var messageBitLength = btes.length * 8;
	btes.push(0x80);
	while(btes.length % 64 !=56){
		btes.push(0);
	}
	
	var lengthBytes = new Array();
	for (var i = 0; i < 8; i++){
		var bte = messageBitLength & 255;
		lengthBytes.push(bte);
		messageBitLength >>>= 8;
	}
	//Aus little Endian big Endian machen und anhängen
	for (var i = 7; i >= 0; i--){
		btes.push(lengthBytes[i]);
	}
	
	for (var i = 0; i < btes.length; i += 64){
		var w = new Array(16);
		for (var j = 0; j < 16; j++){
			w[j] = int32(
					int32(btes[i + 0 + (j*4)] << 24) |
					int32(btes[i + 1 + (j*4)] << 16) |
					int32(btes[i + 2 + (j*4)] << 8 ) |
					int32(btes[i + 3 + (j*4)] << 0 )
				);
		}
		for (var j = 16; j < 80; j++){
			w[j] = leftRotate(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
		}
		
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		
		for (var j = 0; j < 80; j++){
			if (j < 20){
				//var f = int32(int32(b & c) | int32(int32(~b) & d)); // Originalverarbeitung
				var f = int32(d ^ int32(b & int32(c ^ d)));
				var k = 0x5A827999;
			}
			else if (j < 40){
				var f = int32(int32(b ^ c) ^ d);
				var k = 0x6ED9EBA1;
			}
			else if (j < 60){
				var f = int32(int32(b & c) | int32(b & d) | int32(c & d));
				var k = 0x8F1BBCDC;
			}
			else{
				var f = int32(int32(b ^ c) ^ d);;
				var k = 0xCA62C1D6;
			}
			
			var temp = int32(leftRotate(a, 5) + f + e + k + w[j]);
			e = d;
			d = c;
			c = leftRotate(b, 30);
			b = a;
			a = temp;
		}
		
		h0 = int32(h0 + a);
		h1 = int32(h1 + b);
		h2 = int32(h2 + c);
		h3 = int32(h3 + d);
		h4 = int32(h4 + e);
	}
	
	return h0.toHex(8) + h1.toHex(8) + h2.toHex(8) + h3.toHex(8) + h4.toHex(8);
}
kkjs.md5 = function md5(str){
	// Algorithmus aus http://de.wikipedia.org/wiki/Message-Digest_Algorithm_5

	function int32(n){
		// Nur die ersten 32 Bit stehen lassen und das Problem mit den negativen Zahlen umgehen (0xFFFFFFFF >> 1 == -1; 0xFFFFFFFF >>> 1 == 0x7FFFFFFF und -1 >>> 0 == 0xFFFFFFFF)
		return ((n & 0xFFFFFFFF) >>> 0);
	};
	function leftRotate(a, n){
		a = int32(a);
		return int32(int32(a<<n) | int32(a>>>(32-n)));
	}
	
	// Byteweises einlesen des Eingabestrings
	var btes = new Array();
	for (var i = 0; i < str.length; i++){
		var chr = str.charCodeAt(i);
		while (chr > 255){
			var helpChr = chr;
			var rot = 0;
			while (helpChr > 255){
				helpChr >>= 8;
				rot++;
			}
			btes.push(helpChr);
			chr = chr & ((1<<(rot*8)) - 1);
		}
		btes.push(chr);
	}
	
	var bitLength = 0xFFFFFFFF + 1;
	
	var r = new Array(7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);
	/*
	var k = new Array(64);
	for (var i = 0; i < 64; i++){
		k[i] = int32(Math.floor(Math.abs(Math.sin(i + 1) * bitLength)));
	}
	/* Nachfolgende Zeile könnte vielleicht etwas performanter sein, da nichts berechnet werden muss - das Ergebnis ist das selbe.*/
	var k = new Array(0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391);/**/
	
	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	
	var messageBitLength = btes.length * 8;
	btes.push(0x80);
	while(btes.length % 64 !=56){
		btes.push(0);
	}
	
	for (var i = 0; i < 8; i++){
		var bte = messageBitLength & 255;
		btes.push(bte);
		messageBitLength >>>= 8;
	}
	
	for (var i = 0; i < btes.length; i += 64){
		var w = new Array(16);
		for (var j = 0; j < 16; j++){
			w[j] = int32(
					int32(btes[i + 3 + (j*4)] << 24) |
					int32(btes[i + 2 + (j*4)] << 16) |
					int32(btes[i + 1 + (j*4)] << 8 ) |
					int32(btes[i + 0 + (j*4)] << 0 )
				);
		}
		
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		
		for (var j = 0; j < 64; j++){
			if (j < 16){
				//var f = int32(int32(b & c) | int32(int32(~b) & d)); // Originalverarbeitung
				var f = int32(d ^ int32(b & int32(c ^ d)));
				var g = j;
			}
			else if (j < 32){
				//var f = int32(int32(b & d) | int32(c & int32(~d))); // Originalverarbeitung
				var f = int32(c ^ int32(d & int32(b ^ c)));
				var g = (5*j + 1) % 16;
			}
			else if (j < 48){
				var f = int32(int32(b ^ c) ^ d);
				var g = (3*j + 5) % 16;
			}
			else{
				var f = int32(c ^ int32(b | int32(~ d)));
				var g = (7*j) % 16;
			}
			var temp = d;
			d = c;
			c = b;
			b = int32(leftRotate(a + f + k[j] + w[g], r[j]) + b);
			a = temp;
		}
		
		h0 = int32(h0 + a);
		h1 = int32(h1 + b);
		h2 = int32(h2 + c);
		h3 = int32(h3 + d);
	}
	
	return h0.toHex(8).reverse(2) + h1.toHex(8).reverse(2) + h2.toHex(8).reverse(2) + h3.toHex(8).reverse(2);
}

//Experimentell
kkjs.packHex = function pack(format, str){
	if (/^H(\d+)/.test(format)){
		var len = parseInt(RegExp.$1);
		var read = str.substring(0, len);
		if (len % 2 == 1 ) read += "0";
		
		var ret = "";
		for (var i = 0; i < len/2; i++){
			ret += String.fromCharCode(parseInt(read.substr(i*2, 2), 16));
		}
		return ret;
	}
};

kkjs.pack = function pack(format, str){
	var ret = "";
	var art = format.charAt(0);
	var zahl = /^\d+/.exec(format.substring(1))[0];
	var nFormat = format.substring(1 + zahl.length);
	var len = parseInt(zahl || 0);
	for (var i = 0; i < len; i++){
		
	}
	if (nFormat != ""){
		ret += kkjs.pack(nFormat, str);
	}
}

kkjs.unpackHex = function unpack(format, str){
	if (/^H(\d+)/.test(format)){
		var len = parseInt(RegExp.$1) / 2;
		var read = str.substring(0, len);
		
		var ret = "";
		for (var i = 0; i < len; i++){
			ret += read.charCodeAt(i).toHex(2);
		}
		return ret;
	}
};
kkjs.strtr = function strtr(str, from, to){
	var ret = "";
	for (var i = 0; i < str.length; i++){
		var chr = str.substr(i, 1);
		if (from.indexOf(chr) != -1){
			chr = to.charAt(from.indexOf(chr));
		}
		ret += chr;
	}
	return ret;
};
/**/
kkjs.apr1 = function apr1($plainpasswd, $salt) {
	var $teile = $salt.split("$");
	var $salt = $teile[2];
	var $len = $plainpasswd.length;
	var $text = $plainpasswd + '$apr1$' + $salt;
	var $bin = kkjs.packHex("H32", kkjs.md5($plainpasswd + $salt + $plainpasswd));
	for(var $i = $len; $i > 0; $i -= 16) { $text += $bin.substr(0, kkjs.min(16, $i)); }
	for(var $i = $len; $i > 0; $i >>= 1) { $text += ($i & 1) ? String.fromCharCode(0) : $plainpasswd.charAt(0); }
	$bin = kkjs.packHex("H32", kkjs.md5($text));
	for(var $i = 0; $i < 1000; $i++) {
		var $new = ($i & 1) ? $plainpasswd : $bin;
		if ($i % 3) $new += $salt;
		if ($i % 7) $new += $plainpasswd;
		$new += ($i & 1) ? $bin : $plainpasswd;
		$bin = kkjs.packHex("H32", kkjs.md5($new));
	}
	var $tmp = "";
	for (var $i = 0; $i < 5; $i++) {
		var $k = $i + 6;
		var $j = $i + 12;
		if ($j == 16) $j = 5;
		$tmp = $bin.charAt($i) + $bin.charAt($k) + $bin.charAt($j) + $tmp;
	}
	$tmp = String.fromCharCode(0) + String.fromCharCode(0) + $bin[11] + $tmp;
	$tmp = kkjs.strtr(kkjs.encodeBase64($tmp).substring(2).reverse(),
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
	"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
	return "$" + "apr1" + "$" + $salt + "$" + $tmp;
};
kkjs.crypt = function crypt(str, salt){
	if (!salt) salt = "$1$" + kkjs.md5((new Date()).toGMTString() + Math.random).substring(0, 8) + "$";
	var teile = salt.split("$");
	switch (teile[1]){
		case "1":
			return kkjs.md5(teile[2] + str);
		case "2":
			return kkjs.sha1(teile[2] + str);
		case "apr1":
			return kkjs.apr1(str, salt);
	}
}

//Registrierung der kkjs-klassen
kkjs.onWindowLoad(function(){
	kkjs.createCSSRule(".kkjs_dialog { background-color: buttonface; border: buttonface 2px outset; padding: 2px; display: block;}");
	kkjs.createCSSRule(".kkjs_closeButton {border-width: 2px; border-style: solid; border-color: #DDDDDD buttonShadow buttonShadow #DDDDDD; padding: 2px;}");
	kkjs.createCSSRule(".kkjs_closeButton:hover {border-color: buttonShadow #DDDDDD #DDDDDD buttonShadow; padding: 3px 1px 1px 3px;}");
	
	kkjs.createCSSRule(".kkjs_kontextMenuEintrag, .kkjs_kontextMenuSubMenu {line-height: 11pt; font-size: 11pt; padding: 2px 20px; white-space: pre; border: 1px dotted transparent;}");
	kkjs.createCSSRule(".kkjs_kontextMenuSubMenu {position:relative;}");
	kkjs.createCSSRule(".kkjs_kontextMenuEintrag:hover, .kkjs_kontextMenuSubMenu:hover {background-color: #DDDDDD; border-color: white;}");
	
	kkjs.createCSSRule(".kkjs_kontextMenuSubMenu > .kkjs_dialog {display: none; position: absolute; top: -4px; left: 100%; width: auto;}");
	kkjs.createCSSRule(".kkjs_kontextMenuSubMenu:hover > .kkjs_dialog {display: block; }");
	
});

// Variablen
var para = location.search;
para = para.replace(/^\?/, "").split("&");
kkjs.$_GET = new Object();
for (var i = 0; i < para.length; i++){
	var split = para[i].split("=");
	var name = split[0];
	split.splice(0, 1);
	var wert = split.join("=");
	try{
	kkjs.$_GET[name] = decodeURIComponent(wert);
	}
	catch(e){
		alert(wert);
	}
}

kkjs.cookie = {
	update: function(){
		var cString = document.cookie.toString();
		var werte = cString.split(";");
		for (var i = 0; i < werte.length; i++){
			var wert = werte[i].split("=");
			var name = wert[0].replace(/^\s+/, "");
			wert.splice(0, 1);
			var value = decodeURIComponent(wert.join("="));
			this[name] = value;
		}
		return this;
	},
	
	getValue: function(wert){
		this.update();
		if (typeof(this[wert]) == "string") return this[wert];
		return null;
	},
	
	setValue: function(wert, value, att){
		//att kann folgende Werte enthalten; expire, domain, path, secure
		if (typeof att != "object") att = new Object();
		var insert = wert + "=" + encodeURIComponent(value);
		if (att.expire && att.expire.constructor == Date){
			insert += ";expires=" + att.expire.toGMTString();
		}
		if (typeof(att.expire) == "string" && att.expire){
			insert += ";expires=" + att.expire;
		}
		if (typeof(att.domain) == "string" && att.domain){
			insert += ";domain=" + att.domain;
		}
		if (typeof(att.path) == "string" && att.path){
			insert += ";path=" + att.path;
		}
		if (att.secure){
			insert += ";secure";
		}
		document.cookie = insert + ";";
		return this;
	},
	
	deleteValue: function(wert, att){
		if (typeof att != "object") att = new Object();
		att.expire = new Date(0);
		this.setValue(wert, "", att);
		if (typeof this[wert] == "string") this[wert] = false;
	}
};

kkjs.plugin_url = "";
kkjs.nuetzlichScriptNode;

for (var i in kkjs.$("<script>")){
	if (/^(.+)nuetzlich.js/.test(kkjs.$("<script>")[i].src)){
		kkjs.plugin_url = RegExp.$1;
		kkjs.nuetzlichScriptNode = kkjs.$("<script>")[i];
		break;
	}
}

kkjs.loadPlugin("nuetzlich/node");
kkjs.loadPlugin("nuetzlich/array");
kkjs.loadPlugin("nuetzlich/farben");
kkjs.loadPlugin("nuetzlich/selection");
kkjs.loadPlugin("nuetzlich/verlaufnodes");
kkjs.loadPlugin("nuetzlich/bilder");
kkjs.loadPlugin("nuetzlich/tabellen");

kkjs.$SCRIPT_GET = kkjs.getScriptNodeArguments(kkjs.nuetzlichScriptNode);
if (kkjs.$SCRIPT_GET.plugin){
	var p = kkjs.$SCRIPT_GET.plugin.split("+");
	kkjs.loadPlugin(p);
}
if (kkjs.$SCRIPT_GET.script){
	var p = kkjs.$SCRIPT_GET.script.split("+");
	for (var i = 0; i < p.length; i++){
		kkjs.loadScript(p[i]);
	}
}

kkjs.supported = new Object();

kkjs.fixedSupported = function fixedSupported(){
	var f = document.createElement("div");
	f.style.position = "fixed";
	f.style.bottom = "0px";
	f.style.right = "0px";
	var bodyMarginOld = document.body.style.margin;
	document.body.style.margin = "0px";
	document.body.insertBefore(f, document.body.firstChild);
	
	kkjs.supported.fixed = ((f.offsetTop != 0 && f.offsetLeft != 0) || !f.offsetParent);
	f.parentNode.removeChild(f);
	document.body.style.margin = bodyMarginOld;
	
	return kkjs.supported.fixed;
};
kkjs.onDOMReady(kkjs.fixedSupported);

}).apply();

