/*
	copyright (2009) crossip communications gmbh
	Everyone is permitted to copy and distribute verbatim or modified
	copies of this license document, and changing it is allowed as long
	as the name is changed.
*/
		var base=36;
		var tmin=1;
		var tmax=26;
		var skew=38;
		var damp=700;
		var initial_bias=72;
		var initial_n = 128;		
		//**string Konstante zur ace-string Kennzeichnung
		var const_xn_code="xn--";
		//**trennt basic code points vom punycode-string
		var delimiter = 45; 
		//**zulässiger Sonderzeichensatz at-Domains Unicode ISO-10646-3
		var domidncs = new Array(224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,248,339,353,254,249,250,251,252,253,255,382);
		//**ascii-Bereich 0 ... 9
		var domnum_min=48;
		var domnum_max = 57;
		//**ascii-Bereich a ... z
		var domch_lmin = 97;
		var domch_lmax = 122;
		var  hexcs = new Array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');		
		var hexbase=16;
		//**größte speicherbare Zahl
		var maxint = Number.MAX_VALUE; 
		//**max punycode Länge entspricht der maximal zulässigen Domainlänge abzügl. xn--
		var maxpunylength=59;
		//**max domain Länge
		var maxdomlength=63;
		//**Fehler-Text Konstante
		var errtxt = new Array("kein Fehler","Der von Ihnen eingegebene Domain Name ist zu lang!","Der von Ihnen eingegebene Domain Name ist zu kurz!","Der von Ihnen eingegebene Domainname ist ungültig!","Der von Ihnen eingegeben ace-string ist ungültig!","Der extrahierte Punycode ist ungültig!","Es wurde kein Domainname eingegeben!","Es wurde kein ace-string eingegeben!","Fehler bei der Punycode-Convertierung Punycode-Überlauf!");
		//**Fehlerkonstante
		var nerr_noerr=0;
		var nerr_2long = 1;
		var nerr_2short = 2;
		var nerr_idninvalid = 3;
		var nerr_aceinvalid = 4;
		var nerr_punyinvalid = 5;
		var nerr_noidn = 6;
		var nerr_noace = 7;
		var nerr_punyoverflow = 8;

function ext_puny2idn(domain) {
	var sout="";
	var txtval_ = "";
	txtval_ = domain;
	txtval_ =txtval_.replace(" ","");
	txtval_ = txtval_.toLowerCase();
	txtval_ = txtval_.split(".");    
	sld = txtval_[0];
	tld = "";
	if (txtval_[1]) {
		tld = txtval_[1]
	}
	if (txtval_[2]) {
		tld = tld + "." + txtval_[2];
	}
	punyval_ =sld.replace("xn--","");
	if (punyval_ != sld) {
		punylen_ = punyval_.length;
		var input = new Array(100);
		var inplen_ = 0;
		for(var nIndex=0;nIndex < punylen_; nIndex++) {
        		input[nIndex] = punyval_.charCodeAt(nIndex);
		}
		inplen_ = nIndex;
		output = punycode_decode(inplen_,input);
		for(var nIndex=0;nIndex < output.length;nIndex++) {
        		var varout_ = output[nIndex];   
		        if(Number(varout_)) {
        		        if(isbasic(Number(varout_))) {
                		        sout += unescape("%" + enc_dec2hex(varout_));
	                	} else {
	        	                sout += document.getElementById("txt_" + varout_).value;
        	        	}
        		}
		}
		if (tld == "") {
			domain_new = sout;
		}
		else {
			domain_new = sout + "." + tld;
		}
 
		return (domain_new);
	}
	return("");
}

function ext_print_idn(domain) {
	idn_domain = ext_puny2idn(domain);
	if (idn_domain) {
		document.write(idn_domain + " / ");
	}
}

function ext_change_idn() {
	idn_domain = ext_puny2idn(document.getElementById("sld").value);
	if (idn_domain) {
		document.fgetElementById("sld").value = idn_domain;
	}
}



function ext_idn2puny(domain) {
	var txtval_ = "";
	var input = new Array(100);
	var output;
	var inplen_ = 0;
	var sout=const_xn_code;
	txtval_ = domain;
	txtval_ =txtval_.replace(" ","");
	txtval_ = txtval_.toLowerCase();
	idn_ = txtval_;
	idnlen_ = idn_.length;
	if(idnlen_ != 0) {
		for(var nIndex=0;nIndex < idnlen_; nIndex++) {
			input[nIndex] = idn_.charCodeAt(nIndex);
		}
		inplen_ = nIndex;
		if(extended_cps(inplen_,input)) {
			output = punycode_encode(inplen_,input);
		} else {
			output = input;
			sout="";
		}
		for(var nIndex=0;nIndex < output.length;nIndex++) {
			var varout_ = output[nIndex];
			if(Number(varout_)) {
				sout += unescape("%" + enc_dec2hex(varout_));
			}
		}
		return (sout);
	}
	return ("");

}

function ext_checkidn(domain) {
	var txtval_ = "";
	var input = new Array(100);
	var output;
	var inplen_ = 0;
	var sout=const_xn_code;
	txtval_ = domain;
	txtval_ =txtval_.replace(" ","");
	txtval_ = txtval_.toLowerCase();
	idn_ = txtval_;
	idnlen_ = idn_.length;
	if(idnlen_ != 0) {
		for(var nIndex=0;nIndex < idnlen_; nIndex++) {
			input[nIndex] = idn_.charCodeAt(nIndex);
		}
		inplen_ = nIndex;
		if(extended_cps(inplen_,input)) {
			return true;
		} else {
			return false;
		}
	}
	return false;
}

function ext_change_puny() {

	puny_allowed = new Array(".ðô");

	var domain = document.getElementById("sld").value;
	var tld = document.getElementById("tld").value;
	var tlds = document.getElementById("tld");
	var is_idn = ext_checkidn(domain);
   t = (domain.indexOf('.'));
if(t > -1)
{
alert("Êîìïàíèÿ ðåãèñòðèðóåò òîëüêî äîìåíû âòîðîãî óðîâíÿ.\nÄëÿ ðåãèñòðàöèè äîìåíà òðåòüåãî óðîâíÿ - \nîáðàòèòåñü ê âëàäåëüöó îñíîâíîãî äîìåíà.");
		return (false);
}
if (domain.length < 2 && (tld == ".ru" || tld == ".ðô" ||  tld == ".su")){alert("Èìÿ äîìåíà â âûáðàííîé çîíå äîëæíî ñîäåðæàòü ìèíèìóì 2 ñèìâîëà!"); return (false);}
else {if (domain.length < 3 && (tld != ".ru" && tld != ".ðô" &&  tld != ".su")){alert("Èìÿ äîìåíà â âûáðàííîé çîíå äîëæíî ñîäåðæàòü ìèíèìóì 3 ñèìâîëà!"); return (false);}}


	if (is_idn == true) {
		for (var i = 0; i < puny_allowed.length; ++i) {
			if (puny_allowed[i] == tld) {
				$("div#errorboxidn").hide();
				document.getElementById("sld").value = ext_idn2puny(domain);
				//alert(tlds.options[tlds.selectedIndex].value);
				tlds.options[tlds.selectedIndex].value = ".xn--p1ai";
			//	alert("Ñåðâèñ íàõîäèòñÿ íà ñòàäèè òåñòèðîâàíèÿ\n\npunycode IDN: "+document.getElementById("sld").value+tlds.options[tlds.selectedIndex].value);
				//$('#tld').val(ext_idn2puny(puny_allowed[i]));
				return;
			}
		}
		$("div#errorboxidn").show();
		return(false);
	}
	$("div#errorboxidn").hide();
	return;
}

function ext_change_puny1() {

	puny_allowed = new Array(".ðô");

	var domain = document.getElementById("sld1").value;
	var tld = document.getElementById("tld1").value;
	var tlds = document.getElementById("tld1");
	var is_idn = ext_checkidn(domain);
   t = (domain.indexOf('.'));
if(t > -1)
{
alert("Êîìïàíèÿ ðåãèñòðèðóåò òîëüêî äîìåíû âòîðîãî óðîâíÿ.\nÄëÿ ðåãèñòðàöèè äîìåíà òðåòüåãî óðîâíÿ - \nîáðàòèòåñü ê âëàäåëüöó îñíîâíîãî äîìåíà.");
		return (false);
}
if (domain.length < 2 && (tld == ".ru" || tld == ".ðô" ||  tld == ".su")){alert("Èìÿ äîìåíà â âûáðàííîé çîíå äîëæíî ñîäåðæàòü ìèíèìóì 2 ñèìâîëà!"); return (false);}
else {if (domain.length < 3 && (tld != ".ru" && tld != ".ðô" &&  tld != ".su")){alert("Èìÿ äîìåíà â âûáðàííîé çîíå äîëæíî ñîäåðæàòü ìèíèìóì 3 ñèìâîëà!"); return (false);}}


	if (is_idn == true) {
		for (var i = 0; i < puny_allowed.length; ++i) {
			if (puny_allowed[i] == tld) {
				$("div#errorboxidn").hide();
				document.getElementById("sld1").value = ext_idn2puny(domain);
				//alert(tlds.options[tlds.selectedIndex].value);
				tlds.options[tlds.selectedIndex].value = ".xn--p1ai";
			//	alert("Ñåðâèñ íàõîäèòñÿ íà ñòàäèè òåñòèðîâàíèÿ\n\npunycode IDN: "+document.getElementById("sld").value+tlds.options[tlds.selectedIndex].value);
				//$('#tld').val(ext_idn2puny(puny_allowed[i]));
				return;
			}
		}
		$("div#errorboxidn").show();
		return(false);
	}
	$("div#errorboxidn").hide();
	return;
}


function extended_cps(ninplen,input)
		{
			var extcps = false;
			//
			for(var j = 0; j < ninplen;j++)
			{
				if(!isbasic(input[j]))
				{
					extcps=true;
				}//end if isbasic
			}//end for each basic codepoint	
			return extcps;
		}	
		//
		function punycode_encode(ninplen,input)
		{
			var output = new Array(59);
			var noutplen=output.length;
			var n = initial_n;    //Obergrenze für den Punycode-Output
			var delta = 0;    //generalized variable-lengt integer 
			var out = 0;    //Anzahl der Outputs
			var bias = initial_bias;    //bias
			var h = 0;    //gehandelte code points
			var b = 0;    //anzahl von basic code points
			var m = 0;    //variable zur Zwischenspeicherung der input-Werte wird initial auf einen möglichst hohen Wert gesetzt
			var q=0;    //integer container zum Handling von delta-Zwischenstufen
			var out=0;
			var t=0;
			var k=0;
			var traceon = false;
			var nOk=nerr_noerr;  //Kontrollflag, ob während der Abarbeitung Fehler aufgetreten sind
			var max_out=noutplen;  //das output Array darf nicht über max_out hinausgehend befüllt werden
			var ncomparer=0; //variable in der zu Vergleichszwecken bei Plausibilitätsprüfungen verschieden Werte abgelegt werden
			var traceerron = false; //Flag um unmittelbare Fehler-Notifizierung zu aktivieren			
			//
			//separiere alle basic code points
			//das grundlegende Prinzip der codierung codiere das Ergebnis der Modulo-div
			//weitergerechnet wird mit dem quotienten q
			//zunächst muss der input nach basic codepoints durchsucht werden
			for(var j = 0; j < ninplen;j++)
			{
				if(isbasic(input[j]))
				{
					//Sicherstellung dass es zu keinem Array-Überlauf kommt
					if((max_out - out) < 2)
					{
						nOk=nerr_2long;
						traceerr(nOk,traceerron);
					}//end if((max_out - out) < 2)
					else
					{
						output[out++] = input[j];
					}// end else if out befindet sich noch im zulässigen Bereich
				}//end if isbasic
			}//end for each basic codepoint
			h=out;
			b=out;
			if(b>0)
			{
				output[out++] = delimiter;
				trace("delimiter: " + output,traceon);
			}//end if prüfe, ob erster codepoint verarbeitet wird				
			//Hauptschleife zur Codierung
			//wird solange durchlaufen, solange input-Werte gefunden werden
			while((h < ninplen) &&  (nOk == nerr_noerr))
			{
				//suche den kleinsten zu kodierenden input-Wert im Array
				//zunächst muss m auf einen möglichst hohen Wert gelegt werden
				 m = maxint;
				for(var j=0;(j < input.length) &&  (nOk == nerr_noerr);j++)
				{	
					//prüfe zunächst, ob der cp in dem 
					//für die punycode-Codierung
					//relevanten Wertebereich liegt. 
					var inpval_ = input[j];
					if(inpval_ >= n && inpval_ < m)
					{
						m=inpval_;
					}//end if aktueller Wert = kleiner als vorhergehender
				}//end for each input-Value
				trace("kleinster Input Value: " + m,traceon);
				//Am Beginn ist delta gleich 0
				//Prüfe auf Punycode-Overflow
				ncomparer = (((maxint - delta) - ((maxint - delta) % (h+1))) / (h+1));
				trace((m-1) + " > prüfe auf Überlauf " + ncomparer,traceon);				
				if((m-1) > ncomparer)
				{
					nOk=nerr_punyoverflow;	
					traceerr(nOk,traceerron);					
				}//end if ((m-1) > ncomparer)
				if(nOk == nerr_noerr)
				{
					//lege delta auf m(m>128) - 128 * 1
					delta = delta + (m-n) * (h+1);
					trace("errechnetes Delta: " + delta,traceon);
					//die neue Grenze wird auf das alte m festgelegt
					//damit beim nächsten Schleifendurchlauf die
					//Bemessungsgrundlage zum Suchen des nächsten kleinsten
					//input-Wertes der vorhergehend gefundene Wert darstellt.
					n=m;
					//für jeden input Wert
					for(var j=0;(j<input.length) && (nOk == nerr_noerr);++j)
					{	
						//input[j] muss nicht auf basic geprüft werden
						if(input[j] < n) //für alle davor liegenden Werte die bereits gehandhabt wurden
						{
							delta++;
							trace("inkrement delta: " + delta,traceon);	
							trace(delta + " == prüfe auf Überlauf 0",traceon);
							if(delta == 0)
							{
								nOk=nerr_punyoverflow;	
								traceerr(nOk,traceerron);						
							}//end if (delta == 0)												
						}// end if (input[j] < n)
						//
						if(nOk == nerr_noerr)
						{
							//Repräsentiere delta als generalisierten variable length int
							if(input[j] == n)
							{
								trace("aktuelles n: " + n,traceon);	
								//repräsentiere delta als generalized variable-length integer
								//diese Schleife arbeitet in base-Schrittweite
								var t_ = 0;
								for(q=delta,k=base;(q >= t_) && (nOk == nerr_noerr) ;k+=base)
								{
									trace("prüfe auf möglichen Arrayüberlauf " + out + " >= "  + max_out,traceon);
									if(out >= max_out)
									{
										nOk = nerr_idninvalid;
										traceerr(nOk,traceerron);
									}//end if (out >= max_out)
									if(nOk == nerr_noerr)
									{
										//ermittle den threshold
										//t bleibt zwischen tmin und tmax
										//wenn k also base * nIndex <= bias ist
										//belasse t auf tmin andererseits wenn nIndex*base >= bias ist dann
										//setze t auf tmax fest
										t= k <= bias ? tmin : k >= bias+tmax ? tmax : k - bias;
										t_ = t;
										if(q >= t_)
										{
											//Encoding
											//encoded wird t um den Modulo-Wert von q-threshold und base-threshold erweitert
											trace("Threshold: " + t + " q: " + q + " k: " + k + " bias: " + bias,traceon);	
											var digit2enc_ = t + (q - t) % (base - t);
											trace("digit 2 encode: " + digit2enc_,traceon);
											var digit_ = encode_digit(digit2enc_);
											output[out++] = digit_;
											trace("encoded digit: " + digit_,traceon);								
											//q, der quotient wird schließlich auf seinen neuen Wert festgelegt
											//ziehe zunächst den Restwert ab um ein Ganzzahliges Ergebnis zu bekommen
											q = ((q - t) - ((q - t) % (base - t))) / (base-t);
											trace("neuer Quotient: " + q,traceon);	
										}//end if quotient größer gleich threshold
									}//end if (nOk == nerr_noerr) nach Prüfung der Einhaltung der Arraygrenzen
								}//end for solange q >= threashold
								//
								//encoding des letzten Quotienten der bei der Berechnung übrig geblieben ist
								var lastdigit_ = encode_digit(q);
								output[out++] = lastdigit_;
								trace("encoded last digit: " + lastdigit_,traceon);	
								//bias Anpassung
								//auf Basis des aktuellen delta
								//nächster Index
								//ob es sich um den ersten Wert handelt
								bias = adapt(delta,h+1,h==b);
								delta=0;
								++h;
							}//end if aktueller input wert entspricht n	
						}//end if	nOk == nerr_noerr nach zweiter Überlaufprüfung delta == 0
					}//end for each input value
				}//end if nOk == nerr_noerr nach erster Überlaufprüfung
				//inkrementiere n um eine korrekte Bemessungsgrundlage
				//zum Suchen des nächst höheren zu codieren Wertes zu haben
				++n;
				++delta;
			}//end while input-codepoints zu verarbeiten
			return output;
		}//end function punycode_encode
		
		function punycode_check_encode(ninplen,input)
		{
			var noutplen = 59;
			var n = initial_n;    //Obergrenze für den Punycode-Output
			var delta = 0;    //generalized variable-lengt integer 
			var out = 0;    //Anzahl der Outputs
			var bias = initial_bias;    //bias
			var h = 0;    //gehandelte code points
			var b = 0;    //anzahl von basic code points
			var m = 0;    //variable zur Zwischenspeicherung der input-Werte wird initial auf einen möglichst hohen Wert gesetzt
			var q=0;    //integer container zum Handling von delta-Zwischenstufen
			var out=0;
			var t=0;
			var k=0;
			var traceon = false;
			var nOk=nerr_noerr;
			var nOk=nerr_noerr;  //Kontrollflag, ob während der Abarbeitung Fehler aufgetreten sind
			var max_out=noutplen;  //das output Array darf nicht über max_out hinausgehend befüllt werden
			var ncomparer=0; //variable in der zu Vergleichszwecken bei Plausibilitätsprüfungen verschieden Werte abgelegt werden
			//
			//separiere alle basic code points
			//das grundlegende Prinzip der codierung codiere das Ergebnis der Modulo-div
			//weitergerechnet wird mit dem quotienten q
			//**zunächst muss der input nach basic codepoints durchsucht werden
			for(var j = 0; j < ninplen;j++)
			{
				if(isbasic(input[j]))
				{
					//Sicherstellung dass es zu keinem Array-Überlauf kommt
					if((max_out - out) < 2)
					{
						nOk=nerr_2long;
					}//end if((max_out - out) < 2)
					else
					{
						out++;
					}// end else if out befindet sich noch im zulässigen Bereich										
				}//end if isbasic
			}//end for each basic codepoint
			h=out;
			b=out;
			if( b > 0 )
			{
				out++;
			}//end if prüfe, ob erster codepoint verarbeitet wird				
			//Hauptschleife zur Codierung
			//wird solange durchlaufen, solange input-Werte gefunden werden
			while((h < ninplen) &&  (nOk == nerr_noerr))
			{
				//suche den kleinsten zu kodierenden input-Wert im Array
				//zunächst muss m auf einen möglichst hohen Wert gelegt werden
				 m = maxint;
				for(var j=0;(j < input.length) &&  (nOk == nerr_noerr);j++)
				{	
					//prüfe zunächst, ob der cp in dem 
					//für die punycode-Codierung
					//notwendigen Wertebereich liegt. 
					var inpval_ = input[j];
					if(inpval_ >= n && inpval_ < m)
					{
						m=inpval_;
					}//end if aktueller Wert = kleiner als vorhergehender
				}//end for each input-Value
				trace("kleinster Input Value: " + m,traceon);
				//Am Beginn ist delta gleich 0
				//Prüfe auf Punycode-Overflow
				ncomparer = (((maxint - delta) - ((maxint - delta) % (h+1))) / (h+1));
				trace((m-1) + " > prüfe auf Überlauf " + ncomparer,traceon);				
				if((m-1) > ncomparer)
				{
					nOk=nerr_punyoverflow;	
				}//end if ((m-1) > ncomparer)
				if(nOk == nerr_noerr)
				{				
					//lege delta auf m(m>128) - 128 * 1
					delta = delta + (m-n) * (h+1);
					trace("errechnetes Delta: " + delta,traceon);
					//die neue Grenze wird auf das alte m festgelegt
					//damit beim nächsten Schleifendurchlauf die
					//Bemessungsgrundlage zum Suchen des nächsten kleinsten
					//input-Wertes der vorhergehend gefundene Wert darstellt.
					n=m;
					//für jeden input Wert
					for(var j=0;(j<input.length) && (nOk == nerr_noerr);++j)
					{	
						//input[j] muss nicht auf basic geprüft werden
						if(input[j] < n) //für alle davor liegenden Werte die bereits gehandhabt wurden
						{
							delta++;
							trace("inkrement delta: " + delta,traceon);	
							trace(delta + " == prüfe auf Überlauf 0",traceon);
							if(delta == 0)
							{
								nOk=nerr_punyoverflow;	
							}//end if (delta == 0)												
						}// end if (input[j] < n)
						//Repräsentiere delta als generalisierten variable length int
						//
						if(nOk == nerr_noerr)
						{						
							if(input[j] == n)
							{
								trace("aktuelles n: " + n,traceon);	
								//repräsentiere delta als generalized variable-length integer
								//diese Schleife arbeitet in base-Schrittweite
								var t_ = 0;
								for(q=delta,k=base;(q >= t_) && (nOk == nerr_noerr);k+=base)
								{
									trace("prüfe auf möglichen Arrayüberlauf " + out + " >= "  + max_out,traceon);
									if(out >= max_out)
									{
										nOk = nerr_idninvalid;
									}//end if (out >= max_out)	
									if(nOk == nerr_noerr)
									{																
										//ermittle den threshold
										//t bleibt zwischen tmin und tmax
										//wenn k also base * nIndex <= bias ist
										//belasse t auf tmin andererseits wenn nIndex*base >= bias ist dann
										//setze t auf tmax fest
										t= k <= bias ? tmin : k >= bias+tmax ? tmax : k - bias;
										t_ = t;
										if(q >= t_)
										{
											//Encoding
											//encoded wird t um den Modulo-Wert von q-threshold und base-threshold erweitert
											trace("Threshold: " + t + " q: " + q + " k: " + k + " bias: " + bias,traceon);	
											var digit2enc_ = t + (q - t) % (base - t);
											trace("digit 2 encode: " + digit2enc_,traceon);
											var digit_ = encode_digit(digit2enc_);
											out++;
											trace("encoded digit: " + digit_,traceon);								
											//q, der quotient wird schließlich auf seinen neuen Wert festgelegt
											//ziehe zunächst den Restwert ab um ein Ganzzahliges Ergebnis zu bekommen
											q = ((q - t) - ((q - t) % (base - t))) / (base-t);
											trace("neuer Quotient: " + q,traceon);	
										}//end if quotient größer gleich threshold
									}//end if (nOk == nerr_noerr) nach Prüfung der Einhaltung der Arraygrenzen									
								}//end for solange q >= threashold
								//
								//encoding des letzten Quotienten der bei der Berechnung übrig geblieben ist
								var lastdigit_ = encode_digit(q);
								out++;
								trace("encoded last digit: " + lastdigit_,traceon);	
								//bias Anpassung
								//auf Basis des aktuellen delta
								//nächster Index
								//ob es sich um den ersten Wert handelt
								bias = adapt(delta,h+1,h==b);
								delta=0;
								++h;
							}//end if aktueller input wert entspricht n	
						}//end if	nOk == nerr_noerr nach zweiter Überlaufprüfung delta == 0							
					}//end for each input value
				}//end if nOk == nerr_noerr nach erster Überlaufprüfung
				//inkrementiere n um eine korrekte Bemessungsgrundlage
				//zum Suchen des nächst höheren zu codieren Wertes zu haben
				++n;
				++delta;
			}//end while input-codepoints zu verarbeiten
			if(out > maxpunylength)
			{
				nOk=nerr_2long;
			}
			return nOk;
		}//end function	punycode_check_encode	
		
		function encode_digit(digit_ /*flag*/)
		{
		
			digit_ = digit_ + 22 + 75 * (digit_ < 26);    //-((flag != 0) << 5) //bei ucase-Unterstützung wird dec 64 abgezogen
			return digit_;
			//0 ... 25 wird auf ASCII a...z gemappt
			//26...35 wird auf ASCII 0 ... 9 gemappt
		}//end function encode_digit
		
		function decode_digit(cp_)
		{
			var cpret_ = 0;
			//prüfe cp_ stetig steigernd primär gegen 10 cp_ - 48
			//dann gegen 26 cp_ - 65 
			//dann gegen 26 cp_ - 97
			//der Rückgabewert bewegt sich zwischen 0 und base
			cpret_ = cp_-48 < 10 ? cp_-22 : cp_-65 < 26 ? cp_ - 65 : cp_ - 97 < 26 ? cp_ - 97 : base;
			return cpret_
		}//end function decode_digit	
		
		function isdelimiter(cp_)
		{
			return (cp_ == delimiter);
		}//end function isdelimiter	
	
	function isbasic(dec)
		{
			var bbasic = false;
			if(dec < initial_n)
			{
				bbasic=true;
			}//end if (dec < initial_n)
			return bbasic;
		}//end function isbasic
		
		function trace(msg,traceon)
		{
			if(traceon)
			{
				var oDate = new Date();
				alert("Datum: " + oDate.getDay() + "." + oDate.getMonth() + "." + oDate.getFullYear() + "\nTime:" + oDate.getHours() + ":" + oDate.getMinutes() + ":" + oDate.getSeconds() + ".."  + oDate.getMilliseconds() + "\n\nWert:\n\n" + msg);
			}
		}//end function trace
		
		function adapt(delta_,index_,isfirst_)
		{
			var k=0;
			var border_ = ((base - tmin) * tmax) >> 1;
			var retval=0;
			var traceon = false;
			trace("bias adapt eingang_ : " + delta_ + " isfirst_: " + isfirst_,traceon);	
			delta_ = isfirst_ ? (delta_ - (delta_%damp)) / damp : delta_ >> 1 // entspricht delta_=delta_/2
			trace("second step delta_ : " + delta_ + " isfirst_: " + isfirst_,traceon);	
			//stelle durch Abzug des Restwertes wieder sicher, dass das
			//Ergebnis eine Ganze Zahl ist. 
			delta_ = delta_ + (delta_ - (delta_ % index_)) / index_;
			trace("third step delta_ : " + delta_,traceon);	
			for(k=0;delta_ > border_;k+=base)
			{
				delta_ = (delta_ - (delta_ % base)) / base - tmin;
			}//end for each base-Steps
			ergtmp =  (base - tmin + 1) * delta_;
			retval = (ergtmp - (ergtmp % (delta_ + skew))) / (delta_ + skew);
			retval+=k;
			trace("neues bias: " + retval,traceon);	
			return retval;
		}//end function adapt
		
		function enc_dec2hex(dec)
		{
			var shex = "";
			var mod=0;
			var q = dec;
			while(q >= hexbase)
			{
				mod = q % hexbase;
				shex = hexcs[mod] + shex;
				q = (q-mod) / hexbase;
				//alert(q);
			}
			//Verarbeitung des verbleibenden Hexrestwertes
			shex = hexcs[q] + shex;
			return shex;
		}//end function enc_dec2hex

