/*	pstrainer.js
	Author: pstrainer@gmx.net
	Version 3.02 / 2008-11-01

########## Liste der Funktionen ##########
***** Header ***************
 pst_preload();
***** Header ***************
 header(thestatus);
 frame_break();
 visitor_nr_get();
 pst_nesting_get();
 do_onload();
 get_nesting(); -- deprecated
***** Navigation ***************
 menu_check(h,n);
 my_filename();
***** Datum & Zeit ***************
 datim_to_iso(datim);
 datim_to_iso_date(datim);
 datim_to_iso_time(datim);
***** Array ********************
 array_mul_sort(ary,idx,updwn);
***** DOM *** Arg node = nodeid oder node *****
 node_test(node);
 node_get(node);
 MgetAttribute(mynode,attname);
 MsetAttribute(mynode,attname,attvalue);
 child_text_get(node);
 childnodes_delete(node);
 child_text_replace(node,txt);
 child_text_copy(src_id,dst_id);
 child_text_create(node,txt);
 child_text_newline(node,text);
 append_break(node);
 append_div(node,text);
 node_info(node);
***** Cookie ***************
 getCookie(name);
 setCookie(name,value,expires,path,domain,secure);
***** Formular ***************
 validate_int(arg);
 validate_float(arg);
 validate_range(arg,min,max);
 option_nr(obj);
 option_value(obj);
 option_null(obj);
 option_set_nr(obj,optnr);
 option_set_value(obj,optval);
 selection_nr(obj);
 selection_set_value(obj,optval);
***** Webseite ***************
 mail_link_create(nid,subject);
 hilite(node,01);
 node_display(node,01);
 node_visibility(node,01);
 tab_col_css(table_id);
 pst_get_arguments();
 write_my_url(); -- deprecated
 add_url_to_bookmarks(); -- deprecated
 write_my_modif_time(); -- deprecated
 trailer();
***** PopUp Tools ***************
 calendar_open();
 time_open();
***** Numerisch ***************
 sign(x,typ)
 pst_round(arg_f,arg_d)
 zufall_0_255();
 rnd_from_to(rmin,rmax);
 ceilfloor(x);
 my_frac(x);
 floorceil(x);
 dmodulo(a,b);
 my_minimum(a,b,c,...);
 faktorielle(n);
 n_ueber_r(n,r);
***** String ***************
 round_txt(arg_f,arg_d);
 sprintf_sci(x,dm,em);
 leading_zero_txt(i,d);
 num2str_2(mynumber);
 count_txt(the_text,search_string);
 strip_controlchars(mytxt);
 text_repeat(tt,n);
 trim(t);
 fixed_lenght_string(str,fill,fixlen,align);
 dec2hex1(dec);
 dec_to_bin(dec,stellen);
 iso=usdatim_to_iso(us);		// mm/dd/yyyy hh:mi:ss
 iso=rfc_to_iso(rfc);		// Day, dd Mon yyyy hh:mi:ss +0100
***** Array ***************
 array_sort_multidim(amul,idx);
***** Unicode ***************
 string_to_utf8(str);
 char_to_utf8(c);
 utf8_to_string(utf);
***** CSS ***************
 position_get(id);
 pst_size_get(id);
 pst_style_set(id,css,val)
***** Hex ***************
 dec2hex(dec,ndigs);
 hex2dec(hex);
*/

//alert("pstrainer.js a");

// Globale Variable
var pst_frame="pstrainer.php";
var my_brs1 = navigator.appName.substr(0,1);	// browser = [N,M,O...]
var link_to_me="";
var mymail_adr = "pstrainer\u0040gmx\u002Enet";
var mymail_status = "\u004Dail an PS-Trainer";
//-----deprecated:-----
var targetframe="pstrainer.php";
//
my_visitor_nr=0;
// fuer RFC-parsing
var monam_array=new Array("","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");

// ********** Preload ***********
function pst_preload() {
// Test der Arbeits-Umgebung
	var ok_to_load=1;
	var test=-1;
	try{
		if(document.URL==parent.document.URL) {test=-2;}
		else if(parent.document.title!="PS-Trainer") {test=-2;}
		else {
			test=parent.pst_visnr;
			if(test==undefined) {test=-2;}
		}
	}
	catch(e) {test=-3;}
	// Korrektur der Arbeits-Umgebung
	if(test<0) {
		ok_to_load=0;
		var target="";
		try{
			target=pst_get_login();
			var my_relar=pst_get_reladr();
			if(!my_relar.match(/frame_navi.html$/)) {
				target+="?tar="+my_relar;
			}
			if(document.referrer) {
				target+="&ref="+document.referrer;
			}
			if(target.length>250) {target=target.substr(0,250)+"*";}
		}
		catch(e) {}
		//alert("pre 155\ntarget="+target);
		//top.location.href=target;
	}
	return ok_to_load;

}

function pst_get_login() {
	var ra=window.location.href;
	ra=ra.replace(/.*\/pstrainer\//,"");
	ra=ra.replace(/[^\/]/g,"");
	var path="";
	for(var i=0;i<ra.length;i++) {path="../"+path;}
	path+="library/login/login.html";
	return path;
}

function pst_get_reladr() {
	var ra=window.location.href;
	ra=ra.replace(/.*\/pstrainer\//,"");
	return ra;
}

// ********** Header ***********

var pst_status="PS-Trainer";
function header(thestatus) {
// 1 argument: status msg
	var tmp_status="";
	if(header.arguments.length>0) {tmp_status=header.arguments[0];}
	//frame_break();
	//visitor_nr_get();
	if(tmp_status.length) {
		pst_status=tmp_status;
		window.defaultStatus=pst_status;
	}
	pst_nesting_get();
	return pst_nesting;
}

function get_nesting() {
//	deprecated !
	var t="document=".document.href;
	t+="\nJS function get_nesting is deprecated";
	t+="\n->pst_nesting_get";
	alert(t);
}
var pst_nesting=0;
function pst_nesting_get() {
//	returns the pages nesting (tree distance from index.html)
//	Method: Analyze the href-Attribute of a <link>-Object
//	Mind: This will only work if
//		(1) There is a <link>-object before we are called
//		(2) The <link> object points to a file at the same level as index.html
//		(3) The reference in the <link>-object is correct
//	This is true if the HTML-template is made correctly
	pst_nesting=0;
	try{
		var linknode=document.getElementsByTagName('link')[0];
		var reftxt=linknode.getAttribute("href");
		pst_nesting=count_txt(reftxt,"../");
	}
	catch(e) {pst_nesting=0;}
	return pst_nesting;
}

function get_my_url() {
// Get current page url
	var url=document.URL;
	url=url.replace(/[#\?].*/,"");	// kill anchors and arguments
	link_to_me=url;
	return url;
}

function do_onload() {
// Nach onLoad ausfuehren
	trailer();
}

// ********** Navigation **********
var pst_menu_counter=0;
function menu_check() {
// Steuert den Navigations-frame aus der aufgerufenen Seite
	// 2 args: haupt, neben
	// check arg0
	pst_menu_poll=1;	// ok to polling
	var arg0=0;
	if (menu_check.arguments.length>0) {arg0=menu_check.arguments[0];}
	if (arg0<0 || arg0>20) {arg0 = 0;}
	//	check arg1
	var arg1=0;
	if (menu_check.arguments.length>1) {arg1=menu_check.arguments[1];}
	if (arg1<0 || arg1>20) {arg1 = 0;}
	//	check current menu
	pst_menu_counter=20;	// das reicht normalerweise
	pst_menu_try(arg0,arg1);
}

function pst_menu_try(arg0,arg1) {
// Try until Navi-Frame is ready
	var ok=0;
	try{ok=parent.ps.ready;}
	catch(e) {ok=0;}
	if(ok) {parent.ps.menu_change(arg0,arg1);}
	else if(pst_menu_counter){window.setTimeout("pst_menu_try("+arg0+","+arg1+")",100);}
	pst_menu_counter--;
}
function my_filename() {
// returns current filename
	var p=location.pathname.match(/\/([^\/]*)$/);
	return RegExp.$1;
}

// ********** Datum & Zeit **********

function datim_to_iso() {
// Make ISO 8601 date & local time string from a JS date object
	d=null;
	if (datim_to_iso.arguments.length>0) {d=datim_to_iso.arguments[0];}
	if(!d) {d=new Date();}
	return datim_to_iso$(d);
}
function datim_to_iso$(d) {
	var iso=datim_to_iso_date$(d);
	iso+=" "+datim_to_iso_time$(d);
	return iso;		
}

function datim_to_isox() {
// Make ISO 8601 date & local time string from a JS date object
// 2. arg = TimeZone Offset in sec
	dx=null; var tzos=0;
	if (datim_to_isox.arguments.length>0) {dx=datim_to_isox.arguments[0];}
	if (datim_to_isox.arguments.length>1) {tzos=datim_to_isox.arguments[1];}
	if(!dx) {
		dx=new Date();
		dx.setSeconds(dx.getSeconds()+tzos);
	}
	return datim_to_isox$(dx,tzos);
}
function datim_to_isox$(dx,tzos) {
	var iso=datim_to_iso_datex$(dx,tzos);
	iso+=" "+datim_to_iso_timex$(dx,tzos);
	return iso;		
}

function datim_to_iso_date() {
// Make ISO 8601 date string from a JS date object
	d=null;
	if (datim_to_iso_date.arguments.length>0) {d=datim_to_iso_date.arguments[0];}
	if(!d) {d=new Date();}
	return datim_to_iso_date$(d);
}
function datim_to_iso_datex() {
// Make ISO 8601 date string from a JS date object (virtual local time)
	dx=null; var tzos=0;
	if (datim_to_iso_datex.arguments.length>0) {dx=datim_to_iso_datex.arguments[0];}
	if (datim_to_iso_datex.arguments.length>1) {tzos=datim_to_iso_datex.arguments[1];}
	if(!dx) {
		dx=new Date();
		dx.setSeconds(dx.getSeconds()+tzos);
	}
	return datim_to_iso_datex$(dx);
}
function datim_to_iso_date$(d) {
	var iso=d.getFullYear().toString();
	iso+="-"+num2str_2(d.getMonth()+1);
	iso+="-"+num2str_2(d.getDate());
	return iso;		
}
function datim_to_iso_datex$(dx) {
	var iso=dx.getUTCFullYear().toString();
	iso+="-"+num2str_2(dx.getUTCMonth()+1);
	iso+="-"+num2str_2(dx.getUTCDate());
	return iso;		
}

function datim_to_iso_time() {
// Make standard time string from a JS date object
	var d=null;
	if (datim_to_iso_time.arguments.length>0) {d=datim_to_iso_time.arguments[0];}
	if(!d) {d=new Date();}
	return datim_to_iso_time$(d);
}
function datim_to_iso_timex() {
// Make standard time string from a JS date object (virtual local time)
	var dx=null; var tzos=0;
	if (datim_to_iso_timex.arguments.length>0) {dx=datim_to_iso_timex.arguments[0];}
	if (datim_to_iso_timex.arguments.length>1) {tzos=datim_to_iso_timex.arguments[1];}
	// todo: Standard-CET Werte je nach Datum / Sommerzeit
	//else {}
	if(!dx) {
		dx=new Date();
		dx.setSeconds(dx.getSeconds()+tzos);
	}
	return datim_to_iso_timex$(dx);
}
function datim_to_iso_time$(d) {
	var iso=num2str_2(d.getHours());
	iso+=":"+num2str_2(d.getMinutes());
	iso+=":"+num2str_2(d.getSeconds());
	return iso;		
}
function datim_to_iso_timex$(dx) {
	var iso=num2str_2(dx.getUTCHours());
	iso+=":"+num2str_2(dx.getUTCMinutes());
	iso+=":"+num2str_2(dx.getUTCSeconds());
	return iso;		
}

// ********** Array-Funktionen **********

function array_mul_sort(ar,idx,updwn) {
// sort multidimensional Array
// ar...Array to sort
// idx... Index to sort with
// updwn... sort ascending / descending
	for(var i=0;i<(ar.length-1);i++) {
		for(var j=(i+1);j<ar.length;j++) {
			if(updwn) {if(ar[j][idx]<ar[i][idx]) {xchg(i,j);}}
			else {if(ar[j][idx]>ar[i][idx]) {xchg(i,j);}}
		}
	}
	function xchg(i,j) {
		var t=ar[i]; ar[i]=ar[j]; ar[j]=t;
	}
}

// ********** DOM-Funktionen **********

function node_test(node) {
// Test if a node is valid
// Returns true or false
	var myok=false;
	try {
		var t=node.nodeType; 
		if(typeof t=="number") {myok=true;}
	}
	catch(e) {}
	return myok;
}

function node_get(node) {
// Returns a valid node object or null;
// Argument node: either id-string or node-object
	var my_test=null;
	if (node_get.arguments.length>0) {my_test=node_get.arguments[0];}
	var my_ret=null;
	if(typeof my_test=="string") {
		try {my_test=document.getElementById(my_test);} catch(e) {}
	}
	if ((typeof my_test=="object")&&(node_test(my_test))) {my_ret=my_test;}
	return my_ret;
}

function MgetAttribute(mynode,attname) {
// Get attribute value of a DOM node (node or id-string)
// equivalent to mynode.getAttribute(attname)
	var mynode=node_get(mynode);
	var myvalue=null;
	try {
		if(my_brs1=="M") {
			// the damned M$IE does not support getAttribute
			var mv=navigator.appVersion.substring(0,1);
			if(mv>3) {
				var att=mynode.getAttributeNode(attname);
				myvalue=att.nodeValue;
			}
			else {
				for(var i=0;i<mynode.attributes.length;i++) {
					var myatt = mynode.attributes[i];
					if(myatt.nodeName==attname) {myvalue=myatt.nodeValue;}
				}
			}
		}	// end damned M$IE
		else {myvalue=mynode.getAttribute(attname);}
	}	// end try
	catch (e) {myvalue=null;}
	return myvalue;
}

function MsetAttribute(mynode,attname,attvalue) {
// Set attribute of a DOM node
// equivalent to mynode.setAttribute(attname,attvalue)
	var mynode=node_get(mynode);
	try{
		if(my_brs1=="M") {
			// the damned M$IE does not support setAttribute
			var mv=navigator.appVersion.substring(0,1);
			if(mv>3) {
				var att=document.createAttribute(attname);
				att.nodeValue=attvalue;
				mynode.setAttributeNode(att);
			}
			else {
				for(var i=0;i<mynode.attributes.length;i++) {
					var myatt=mynode.attributes[i];
					if(myatt.nodeName==attname) {myatt.nodeValue=attvalue;}
				}
			}
		}	// end damned M$IE
		else {mynode.setAttribute(attname,attvalue);}
	}	// end try
	catch(e) {}
}

function childnodes_delete(node) {
// Delete all childnodes from a node 
// Argument node = either a node-id or a node object
	// alert("# childnodes_delete #");
	var n=node_get(node);
	childnodes_delete$(n);
}

function childnodes_delete$(node) {
// Delete all childnodes from a node
// Argument node = a valid node
	// alert("childnodes_delete$\nchildnodes="+node.childNodes.length);
	try {
		while(node.childNodes.length>0) {node.removeChild(node.firstChild);}	
	}
	catch(e) {}
}

function child_text_get(node) {
	var n=node_get(node);
	return child_text_get$(n);	
}
function child_text_get$(node) {
	var t="";
	if(node.childNodes.length==1) {
		node=node.firstChild;
		if(node.nodeType==3) {t=node.nodeValue;}
	}
	return t;
}

function child_text_replace(node,txt) {
// Replace all childnodes of node by a new textnode
// Argument node = either a node-id or a node object, txt = a string
	var n=node_get(node);
	if(typeof txt !="string") {txt=txt.toString();}
	child_text_replace$(n,txt);
}
function child_text_replace$(node,txt) {
// Replace all childnodes of node by a new textnode
// Arguments: node = a valid node, txt = a string
	try{
		childnodes_delete(node);
		var newtxt=document.createTextNode(txt); 
		node.appendChild(newtxt); 
	}
	catch(e) {}
}
function child_text_replace$$(nodeid,txt) {
// Replace all childnodes of node by a new textnode
// Arguments: nodeid = string, txt = string
	try{
		var node=document.getElementById(nodeid);
		child_text_replace$(node,txt);
	}
	catch(e) {}
}

function child_text_copy(src_id,dst_id) {
// copy text from src_id to dst_id and return text
	var t=null;
	try{
		t=child_text_get(src_id);
		child_text_replace(dst_id,t);
	}
	catch(e) {var t=null;}
	return t;
}

function child_text_create(node,txt) {
// Create a child-textnode of node
// Argument node = either a node-id or a node object, txt = a string
	var n=node_get(node);
	if(typeof txt !="string") {txt="";}
	child_text_create$(n,txt);
}
function child_text_create$(node,txt) {
// Create a child-textnode of node
// Arguments: node=a valid node, txt=a string
	try{
		var newtxt=document.createTextNode(txt); 
		node.appendChild(newtxt); 
	}
	catch(e) {}
}

function child_text_newline(node,txt) {
// Append new Line of text
	var n=node_get(node);
	if(typeof txt !="string") {txt="";}
	child_text_newline$(n,txt);
}
function child_text_newline$(node,txt) {
// Append new Line of text
	append_break(node);
	child_text_create$(node,txt);
}

function append_break(node) {
// Append Line-Break
	var n=node_get(node);
	append_break$(n);
}
function append_break$(node) {
// Append Line-Break
	try{
		var brn=document.createElement("br");
		node.appendChild(brn);
	}
	catch(e) {}
}

function append_div(node,text) {
// Append <div>value</div>
	var n=node_get(node);
	append_div$(n,text);
}
function append_div$(n,v) {
	if(v) {
		var ndiv=document.createElement("div");
		var ntxt=document.createTextNode(v);
		ndiv.appendChild(ntxt);
		n.appendChild(ndiv);
	}
}

function node_info(node) {
// Display info about a node
// Argument my_node = either id-string or node-object
	var n=node_get(node);
	if(n) {node_info$(n);}
	else {alert("Node (id='"+node+"') not found");}
}

function node_info$(mynode) {
// Display info about a node
// Argument mynode: a valid node
	var mytxt="node_info:";
	var myok=node_test(mynode);
	if(myok) {
		var nodetype = mynode.nodeType;
		mytxt+="\nnodeType="+nodetype;
		var nodename = mynode.nodeName;
		mytxt+="\nnodeName="+nodename;
		var nodevalue = mynode.nodeValue;
		mytxt+="\nnodeValue="+nodevalue;
		var subnodes=0;
		if (nodetype==1) {
			var subnodes = mynode.childNodes.length;
			mytxt+="\nchildNodes.length="+subnodes;
			var atts = mynode.attributes.length;
			mytxt+="\nattributes.length="+atts;
			if(atts) {mytxt+="\n"+node_att$(mynode);}
		}
		alert(mytxt);
		// walk subnodes
		if(subnodes>0) {
			for (var i=0;i<subnodes;i++) {
				mychild=mynode.childNodes[i];
				node_info$(mychild);
			}
		}		
	}
	else {
		mytxt+="\nFehler: kein DOM-Knoten";
		alert(mytxt);
	}
}

function node_att$(mynode) {
// get node attributes
	var mytxt="";
	var myatt=null;
	var ok=true;
	var j=0; // max atts in a row
	for(var i=0;i<mynode.attributes.length;i++) {
    	myatt = mynode.attributes[i]; 
    	attname = myatt.nodeName;
    	attvalue = myatt.nodeValue;
		ok=true;
		if(my_brs1=="M") {	// damned M$ filter
			if(attvalue==null) {ok=false;}
			else if(typeof attvalue=="string" && attvalue.length==0) {ok=false;}
		}
		if(ok) {
			mytxt+=" "+attname+"=\""+attvalue+"\"";
			j++;
			if(j>=5) {mytxt+="\n"; j=0;}
		}
	}
	return mytxt;
}

// ********** Cookie-Funktionen **********

function getCookie(cookie_name) {
	var cv=null;
	var dc = document.cookie;
/*
	if (dc.indexOf(name+"=")>=0) {
		var begin = dc.indexOf(name) + name.length + 1;
		var end = (dc.indexOf(";", begin) >=0) ? dc.indexOf(";", begin) : dc.length;
		cv=unescape(dc.substring(begin,end));
	}
*/
	if(eval("dc.match(/"+cookie_name+"=(.*)/)")) {cv=unescape(RegExp.$1);}
	return cv;
}

function setCookie(name,value,expires,path,domain,secure) {
	document.cookie = name + "=" + escape(value) +
	((expires) ? "; expires=" + expires.toUTCString() : "") +
	((path) ? "; path=" + path : "") +
	((domain) ? "; domain=" + domain : "") +
	((secure) ? "; secure" : "");
}

// ********** Formular - Funktionen

function validate_int(arg) {
	var r=0;
	if(parseInt(arg,10)==arg) {r=1;}
	return r;
}

function validate_float(arg) {
	var r=0;
	if(parseFloat(arg)==arg) {r=1;}
	return r;
}

function validate_range(arg,min,max) {
	var r=0;
	if((arg>=min)&&(arg<=max)) {r=1;}
	return r;
}

function option_nr(obj) {
// returns nr of checked option button or -1
// e.g. x=option_nr(document.form1.option1);
// fuer checkboxen -> x=document.form1.check1.checked;
	var s=-1;
	for(var i=0;i<obj.length;i++) {if(obj[i].checked) {s=i; break;}}
	return s;
}

function option_value(obj) {
// returns value of checked option button or null
// e.g. x=option_value(document.form1.option1);
// fuer checkboxen -> x=document.form1.check1.checked;
	var s=-1;
	var v=null;
	for(var i=0;i<obj.length;i++) {if(obj[i].checked) {s=i; break;}}
	if(s>=0) {v=obj[i].value;}
	return v;
}

function option_null(obj) {
// clears all option buttons
// e.g. option_null(document.form1.option1);
	for(var i=0;i<obj.length;i++) {obj[i].checked=false;}
}

function option_set_nr(obj,optnr) {
// set option buttons (clear all if optnr<0)
// e.g. option_set_nr(document.form1.option1,2);
	if(optnr<0) {option_null(obj);}
	else {
		for(var i=0;i<obj.length;i++) {
			if(i==optnr) {obj[i].checked=true;}
		}
	}
}

function option_set_value(obj,optval) {
// set option buttons (clear others)
// e.g. option_set_value(document.form1.option1,'test');
	for(var i=0;i<obj.length;i++) {
		if(obj[i].value==optval) {obj[i].checked=true;}
		else {obj[i].checked=false;}
	}
}

function selection_nr(obj) {
// returns nr of selected option or -1
// e.g. x=selection_nr(document.form1.select1);
	//var s=-1;
	//for(var i=0;i<obj.length;i++) {if(obj.options[i].selected) {s=i; break;}}
	//return s;
	return obj.selectedIndex;
}

function selection_value(obj) {
// returns value of selected option or null
// e.g. x=selection_value(document.form1.select1);
//	<select name="s1" onChange="ft()">
//		<option value="abc" selected="selected">abc</option>
//		<option value="xyz">xyz</option>
//	</select>
	var i=obj.selectedIndex;
	var v = obj.options[i].value;
	return v;
}

function selection_set_value(obj,optval) {
// e.g. selection_set_value(document.form1.select1,'test');
// Gibt den verwendeten Index oder -1 zurueck
	var i=0; var j=-1;
	while(i<obj.length) {
		if(obj[i].value==optval) {
			obj.selectedIndex=i; 
			j=i;
			i=obj.length; 
		}
		i++;
	}
	return j;
}

// ########## Funktionen fuer Webseiten ##########

function mail_link_create() {
// Erzeugt einen mail-Link im node(nid)
// Anwendung JS: mail_link_create(nid,subject);
// Anwendung / HTML:
//	<a id="mymail">
//	<img src="img/icon/mail.gif" alt="Kontakt" style="height:9px; width:16px;" />
// <!-- HIER wird der mail-Link eingefuegt -->
//	</a>
	var nid="mymail"; var subj="";
	if (mail_link_create.arguments.length > 0) {nid=mail_link_create.arguments[0];}
	if (mail_link_create.arguments.length > 1) {subj=mail_link_create.arguments[1];}
	//alert("mail_link_create("+nid+","+subj+")");
	try{
		var na=document.getElementById(nid);
		var nc=null;
		for(var i=0;i<na.childNodes.length;i++) {
			nc=na.childNodes[i];
			if(nc.nodeName.toLowerCase()=="img") {
				nc.style.border="0px";
				nc.style.marginRight="5px";
			}
		}
		na.style.color="#333";
		na.style.textDecoration="none";
		var att=document.createAttribute("href");
		var t="mail"+"to\u003A"+mymail_adr;
		if(subj.length) {t+="?subject="+subj;}
		att.nodeValue=t;
		na.setAttributeNode(att);
		var nt=document.createTextNode(mymail_adr);
		na.appendChild(nt);
	}
	catch(e) {}
}

function mymail(subject,text) {
//	Schreibt einen Mail-Link auf die Seite
//	2 optional args: subject, text
alert("function mymail is deprecated ->");
/*
	var mymail_hdr = "";	
	var mymail_trailer = "";
	//	check subject
	var mysubj="";
	if (mymail.arguments.length>0) {mysubj = mymail.arguments[0];}
	//	check link text
	var mytext = mymail_adr;
	if (mymail.arguments.length>1) {mytext = mymail.arguments[1];}
	// make mail link
	mailtxt=mymail_hdr;
	mailtxt+="<a href=\"\u006Dailto:"+mymail_adr;
	if (mysubj.length>0) {mailtxt+="?subject="+mysubj;}
	mailtxt+="\"";
	mailtxt+=" onMouseover=\"status='"+mymail_status+"';return true;\"";
	mailtxt+=" onMouseout=\"status='"+my_status+"';return true;\"";
	mailtxt+= ">";
	mailtxt+="<span class='nolink'>";
	mailtxt+= mytext;
	mailtxt+="</span>";
	mailtxt+= "</a>"+mymail_trailer;
	document.write(mailtxt);
*/
}	

function hilite(arg1,arg2) {
// function to online-pointout parts of a page
// Syntax: a=node or node-id, b=[0,1] 
// Syntax: a='(node_id1,node_id2,node_id3...)', b=[0,1] 
	if(typeof arg1 == "string") {
		if(arg1.substr(0,1)=="(") {
			var x = arg1.replace(/[\(\)]/g,"");
			var xar = x.split(/[ ,]/g)
			for(var i=0;i<xar.length;i++) {
				if(arg2) {MsetAttribute(xar[i],"class","hilite");}
				else {MsetAttribute(xar[i],"class","lolite");}	
			}
		}
		else {
			if(arg2) {MsetAttribute(arg1,"class","hilite");}
			else {MsetAttribute(arg1,"class","lolite");}			
		}
	}
	else {
		if(arg2) {MsetAttribute(arg1,"class","hilite");}
		else {MsetAttribute(arg1,"class","lolite");}	
	}
}

function node_display(a,b) {
// function to switch on/off a node & change layout
// Syntax: a=node or node-id, b=[0,1] 
	var n=document.getElementById(a);
	if(b) {n.style.display="inline";}
	else {n.style.display="none";}
}

function node_visibility(a,b) {
// function to switch on/off a node, no layout change
// Syntax: a=node or node-id, b=[0,1] 
	var n=document.getElementById(a);
	if(b) {n.style.visibility="visible";}
	else {n.style.visibility="hidden";}
}

// tab_col variable
var tab_col_nr=0;
tab_col_ar_align = new Array();
tab_col_ar_class = new Array();
function tab_col_css(table_id) {
// Formatierung von Tabellen-Spalten nach CSS-Vorgaben
	var tn=null; var cn=null;
	tab_col_nr=0;
	if(!navigator.appName.toLowerCase().match(/microsoft/)) {
		try{
			var tn=document.getElementById(table_id);
			for(var i=0;i<tn.childNodes.length;i++) {
				tab_col_css_sub(tn.childNodes[i]);
			}
		}
		catch(e) {}
	}
}
function tab_col_css_sub(tn) {
// rekursiv, zur Tabellen-textAlign-Formatierung
// wird von table_align aufgerufen
	var tnn=tn.nodeName.toLowerCase();
	var i=0; var p="";
	switch (tnn) {
	case "col":	// <col> -> read style.property
		try{ 
			tab_col_ar_align[tab_col_nr]=tn.style.textAlign; 
			tab_col_ar_class[tab_col_nr]=MgetAttribute(tn,"class");
		}
		catch(e) {}
		tab_col_nr++;
		break;
	case "tr":	// <tr> -> reset column counter
		tab_col_nr=0;
		break;
	case "td":	// write style.property to <td>
		try{ 
			p=tab_col_ar_align[tab_col_nr];
			if(p.length) {tn.style.textAlign=p;} 
			p=tab_col_ar_class[tab_col_nr];
			if(p.length) {MsetAttribute(tn,"class",p);}
		}
		catch(e) {}
		tab_col_nr++;
		break;
	}
	// walk childNodes
	for(i=0;i<tn.childNodes.length;i++) {
		tab_col_css_sub(tn.childNodes[i]);
	}
}

function pst_get_arguments() {
// Gibt ein Array der GET-Argumente zurueck
// Array-Elemente: [0]=name, [1]=value
	var args=new Array();
	var href=location.href;
	if(href.match(/\?(.*)/)) {
		var get=RegExp.$1; 
		var arga=get.split("&");
		for(var i=0;i<arga.length;i++) { 
			args[i]=arga[i].split("=");
		} 
	}
	return args;
}

function write_my_url() {
// Write a link to the current page *** deprecated !!!
alert("function write_my_url is deprecated !");
}

function do_bookmark() {
	var the_url="http://pstrainer.topsoft.at";
	if(link_to_me.length) {the_url=link_to_me;}
	var descr="Link-Adresse zu den Favoriten (Bookmarks) hinzufuegen.";
	if(my_brs1=="N") {
		//try{window.sidebar.addPanel(pst_status,the_url,'');}
		try{window.sidebar.addPanel(pst_status,the_url,descr);}
		catch(e) {
			alert("Ihr Gecko-(Firefox)-Browser kann die Funktion addPanel nicht ausf\u00FChren.");
		}
	}
	else if(my_brs1=="M") {
		try{window.external.AddFavorite(the_url,pst_status);}
		catch(e) {
			alert("Ihr M$IE-Browser kann die Funktion AddFavorite nicht ausf\u00FChren.");
		}
	}
}

function add_url_to_bookmarks() {
alert("function add_url_to_bookmarks is deprecated !");
}

function write_my_modif_time() {
// write modification time -> webpage
	document.write("<div class='myurl'>");
	document.write("Letzte <span class='u'>\u00C4nderung</span> dieser Seite: ");
	var modif=document.lastModified;
	var iso=null;
	// test RFC-822 format (Opera)
	var res = modif.match(/, \d?\d ... \d?\d?\d\d \d?\d:\d\d:\d\d/);
	if(res) {iso=rfc_to_iso(modif);}
	else {
		// test US-date & time format (M$IE)
		res=modif.match(/\d\d\/\d\d\/\d?\d?\d\d \d?\d:\d?\d:\d?\d/);
		if(res) {iso=usdatim_to_iso(modif);}
	}
	if(!iso) {iso=datim_to_iso$(new Date());}	// default = current time
	document.write(iso+"</div>");
}

function trailer() {
// Schreibt folgende Daten in den Trailer:
// + Datum & Zeit der letzten Aenderung (nur *.htm oder *.html)
// + Adresse der Seite
// + Favoriten (Gecko, M$IE, Opera)
	var n=null; var nd=null; var ns=null; var na=null;
	var t=""; var nt=null; var nimg=null;
	// <div id="trailerdiv"></div>
	try{n=document.getElementById("trailerdiv");}
	catch(e) {n=null;}
	// Letzte Aenderung: 
	if(n && document.URL.match(/\.htm/)) {
		try{
			t=document.lastModified;
			var iso=null;
			// test mo/dd/yyyy hh:mi:ss (M$IE+Moz(GMT))
			if(t.match(/\d\d\/\d\d\/\d?\d?\d\d \d?\d:\d?\d:\d?\d/)) {
				iso=usdatim_to_iso(t);
			}
			// test mo dd, yyyy GMT (Opera)
			else if(t.match(/, \d?\d ... \d?\d?\d\d \d?\d:\d\d:\d\d/)) {
				iso=rfc_to_iso(t);
			}
			if(iso) {
				nd=document.createElement("div");
				t="Letzte \u00C4nderung dieser Seite: "+iso;
				nt=document.createTextNode(t);
				nd.appendChild(nt);
				n.appendChild(nd);
			}
		}
		catch(e) {}
	}
	// Link-Adresse
	if(n) {
		try{
			nd=document.createElement("div");
			trailerdot(nd);
			t=" Adresse dieser Webseite:";
			nt=document.createTextNode(t);
			nd.appendChild(nt);
			n.appendChild(nd);
			nd=document.createElement("div");
			nt=document.createTextNode(link_to_me);
			nd.appendChild(nt);
			n.appendChild(nd);
		}
		catch(e) {}
	}
	// Favoriten
	if(n && (my_brs1=="M" || my_brs1=="O")) {
		try{
			nd=document.createElement("div");
			t="Zu den ";
			nt=document.createTextNode(t);
			nd.appendChild(nt);
			na=document.createElement("a");
			if(my_brs1=="O") {
				MsetAttribute(na,"href",link_to_me);
				MsetAttribute(na,"title",pst_status);
				MsetAttribute(na,"rel","sidebar");
			}
			else {MsetAttribute(na,"href","javascript:do_bookmark()");}
			t="Favoriten";
			nt=document.createTextNode(t);
			na.appendChild(nt);
			nd.appendChild(na);
			t=" hinzuf\u00FCgen";
			nt=document.createTextNode(t);
			nd.appendChild(nt);
			n.appendChild(nd);
		}
		catch(e) {}
	}
	return n;	// null oder node-Objekt
}
function trailerdot(n) {
	var n=null;
	if (trailerdot.arguments.length>0) {n=trailerdot.arguments[0];}
	if(!n) {
		try{n=document.getElementById("trailer");}
		catch(e) {}
	}
	try{
		var h=location.href;
		if(h.match(/^(.*?)\/pstrainer\//)) {
			var src=RegExp.$1+"/img.php?wn=1";
			src+="&mon="+screen.width+'x'+screen.height+'x'+screen.colorDepth;
			src+="&cr=180";
			src+="&ref="+document.referrer;
			var nimg=document.createElement("img");
			//var fn="--";
			//if(h.match(/([^\/]*)$/)) {
				//fn=RegExp.$1;
				//if(!fn.length) {fn="---";}
			//}
			fn=h;
			src+="&fn="+fn;
			nimg.src=src;
			n.appendChild(nimg);
		}
	}
	catch(e) {}
}
// ********** Popup Tools **********
// sind so programmiert, dass sie von jeder Webseite verwendet
// werden koennen. Der Pfad zur Library wird live ermittelt.

function calendar_open() {
// Calendar PopUp
	var wop=true;
	try {derkalender.focus();}
	catch (e) {wop=false;}
	if(my_brs1=="N") {wop=false;}	// compensate gecko error
	var y=screen.availHeight-250;
	var att="width=226,height=160,left=20,top="+y.toString();
	var s=document.getElementById("lib").src;
	s.match(/(.*)\/([^\/]+)/);
	var target=RegExp.$1+"/kalender.html";
	try {if(!wop) {derkalender=window.open(target,"Kalenderfenster",att);}}
	catch(e) {alert("Fehler beim Versuch, ein Fenster mit dem aktuellen Kalender zu \u00F6ffnen.");}
}

function time_open() {
// Time PopUp
	var wop=true;
	try {diezeit.focus();}
	catch (e) {wop=false;}
	if(my_brs1=="N") {wop=false;}	// compensate gecko error
	var y=screen.availHeight-260;
	var att="width=130,height=180,left=20,top="+y.toString();
	if(my_brs1=="M") {att="width=220,height=180,left=20,top="+y.toString();}
	var s=document.getElementById("lib").src;
	s.match(/(.*)\/([^\/]+)/);
	var target=RegExp.$1+"/uhr/uhr.php";
	try {if(!wop) {diezeit=window.open(target,"Zeitfenster",att);}}
	catch(e) {alert("Fehler beim Versuch, ein Fenster mit der aktuellen Zeit zu \u00F6ffnen.");}
}

// ********** Numerische Funktionen **********

function sign() {
// Vorzeichen sign(x,typ)
// typ<=0  ->  integer (-1,0,+1)
// typ>=1  ->  string (-,blank,+)
	var x=0;
	if (sign.arguments.length > 0) {x = sign.arguments[0];}
	var typ=0;
	if (sign.arguments.length > 1) {typ = sign.arguments[1];}
	if(typ<=0) {
		var s=0;
		if(x<0) {s--;}
		else if(x>0) {s++;}
		return s;
	}
	else {
		var s="\u00A0";
		if(x<0) {s="-";}
		else if(x>0) {s="+";}
		return s;
	}
}

function pst_round(arg_f,arg_d) {
// Runden (Zahl, Anzahl Stellen)
	var f=0;
	if (pst_round.arguments.length > 0) {f = pst_round.arguments[0];}
	var d=0;
	if (pst_round.arguments.length > 1) {d = pst_round.arguments[1];}
	if((d<-15) || (d>15)) {d=0;}
	var m=1;
	while(d>0) {m*=10;d--;}
	while(d<0) {m/=10;d++;}	
	f=Math.floor(f*m+0.5)/m;
	return f;
}

function pst_mod(nr,div) {
// Modulo (de: Rest) function
// 2 Arguments: number, divisor
// -> pst_mod(nr,div) = nr % div
	var i=Math.floor(nr/div);
	var rest=nr-i*div;
	return rest;
}

function zufall_0_255() {
// Ganze Zufallszahl 0..255
	return Math.floor(Math.random()*256);
}
function rnd_from_to(rmin,rmax) {
// Ganze Zufallszahl rmin..rmax
	var z=Math.floor(Math.random()*(rmax-rmin+1)+rmin);
	return z;
}
function ceilfloor(x) {
// symmetrische floor-Funktion
	if(x<0) {return Math.ceil(x);}
	else {return Math.floor(x);}
}

function floorceil(x) {
// symmetrische ceiling-Funktion
	if(x<0) {return Math.floor(x);}
	else {return Math.ceil(x);}
}

function my_frac(x) {
// Nachkomma-Anteil
	if(x>=0) {var f=x-Math.floor(x);}
	else {var f=x-Math.ceil(x);}
	return f;
}

function dmodulo(a,b) {
	var dmod=a-Math.floor(a/b)* b;
	return dmod;
}

function my_minimum() {
// x=my_minimum(a,b,c,..);
	var x=null;
	for(var i=0;i<my_minimum.arguments.length;i++) {
		if(x==null || my_minimum.arguments[i]<x) {x=my_minimum.arguments[i];}
	}
	return x;
}

function faktorielle(n) {
	var f=1;
	for(var i=1;i<=n;i++) {f*=i;}
	return f;
}

function n_ueber_r(n,r) {
	var u=n-r;
	if(u>=0) {u=faktorielle(n)/(faktorielle(r)*faktorielle(u));}
	else {u=0;}
	return u;
}

// ********** String-Funktionen **********

// siehe auch function sign(x,1)

function round_txt(arg_f,arg_d) {
// Runden (Zahl, Anzahl Stellen), als Text ausgeben
	var txt=pst_round(arg_f,arg_d).toString();
	if(arg_d>0) {
		if(txt.match(/\./)) {
			txt.match(/(-?\d*)\.(\d*)/);
			var m1=RegExp.$1;
			var m2=RegExp.$2;
			m2+=text_repeat("0",arg_d);
			m2=m2.substr(0,arg_d);
			txt=m1+"."+m2;
		}
		else {txt+="."+text_repeat("0",arg_d);}
	}
	return txt;
}

function sprintf_sci(x,dm,em) {
// sci-Formatierung der Zahl x mit dm Stellen
// und em Exponenten-Stellen
	var m=x; var e=0; var v=0;
	if(m<0) {v=-1;}
	if(m>0) {v=1;}
	v=Math.abs(v);
	while (m>10) {m/=10; e++;}
	while (m<1) {m*=10; e--;}
	m*=v;
	var t=round_txt(m,dm)+"E"+leading_zero_txt(e,em);
	return t;
}

function leading_zero_txt(i,d) {
// Formatierung einer ganzen Zahl i mit fuehrenden Nullen 
// auf d Stellen + Vorzeichen
	i=Math.floor(i);
	var vz=sign(i,1);
	i=Math.abs(i);
	var ti=i.toString();
	var t=text_repeat("0",d-ti.length);
	t=vz+t+ti;
	return t;
}

function num2str_2(mynumber) {
// make a 2-character string from any number 0...99
	return (mynumber<10 ? "0" : "")+mynumber.toString();
}

function count_txt(the_text,search_string) {
//	Count the occurrences of subtxt within text
//	2 Arguments the_text=text to search in, search_string=search string
//	Returns nr of occurrences
	var mycount=0;
	var text="";
	if (count_txt.arguments.length > 0) {text = count_txt.arguments[0];}
	var subtxt="";
	if (count_txt.arguments.length > 1) {subtxt = count_txt.arguments[1];}
	var sublen=subtxt.length;
	if (text.length && sublen) {
		var start=0;
		var found=0;
		while(found>=0) {
			found=text.indexOf(subtxt,start);
			if(found>=0) {
				mycount++;
				start=found+1;
			}
		}
	}
	return mycount;
}

function strip_controlchars(mytxt) {
// strip control chars from any string
	var retxt="";
	for(var i=0;i<mytxt.length;i++) {
		thechr=mytxt.charCodeAt(i);
		if(thechr>31) {retxt+=String.fromCharCode(thechr);}
	}
	return retxt;
}

function text_repeat(tt,n) {
// returns a string of n-times repeated string tt
	var t="";
	while(n>0) {t+=tt; n--;}
	return t;
}

function trim(t) {
// strip leading + trailing blanks + multi-blanks
	t=t.replace(/^\s+/,'');
	t=t.replace(/\s+$/,'');
	while(t.match(/  /)) {t=t.replace(/  /," "); }	
	return t;
}

function fixed_lenght_string(str,fill,fixlen,align) {
// liefert einen string fixer Laenge
// str=String, fill=Fuellzeichen, fixlen=Fixe Laenge, align[0=links, 1=rechts]
	if(!fill.length) {fill=".";}
	fill=fill.substr(0,1);
	if(fixlen<=0) {fixlen=1;}
	if(fixlen>256) {fixlen=256;}
	//var text=text_repeat(fill,fixlen);
	var text=str;
	var tlen=text.length;
	if(align) {
		// align=right
		if(fixlen>tlen) {text=text_repeat(fill,(fixlen-tlen))+text}
		if(fixlen<tlen) {text=text.substr((tlen-fixlen),fixlen);}
	}
	else {	// align=left
		if(fixlen>tlen) {text+=text_repeat(fill,(fixlen-tlen));}
		if(fixlen<tlen) {text=text.substr(0,fixlen);}
	}
	return text;
}

function dec2hex1(dec) {
// Ganze Zahl 0..15 -> Hex 0..F
	var hexa="?";
	var d=dec;
	var ok=validate_range(d,0,15);
	if(ok) {
		if(d<10) {hexa = String.fromCharCode(d+48);}
		else {hexa = String.fromCharCode(d+55);}		
	}
	return hexa;
}

function dec2hex2(dec) {
// Auslauf-Modell ! -> Ersetzen durch dec2hex(dec,2)
	return dec2hex(dec,2);
}

function dec2hex(dec_nr,n_hexdigs) {
// Optionale Parameter
// dec .. Dezimalzahl>=0 (def=0)
// ndig ..  Anzahl gewuenschter Hex-Ziffern (so viele wie benoetigt)
	// Parameter
	var dec=0;
	if (dec2hex.arguments.length>0) {dec=dec2hex.arguments[0];}
	dec=Math.floor(dec);
	var nhd=0;
	if (dec2hex.arguments.length>1) {nhd=dec2hex.arguments[1];}
	// default & error-result
	var hexs="?";
	var mhd=-1;
	// Spezialfall dec==0
	if(dec==0) {hexs="0";}
	// Standard dec>0
	if(dec>0) {
		// Hex-Stellen (+ Begrenzung)
		mhd=Math.floor(Math.log(dec)/Math.log(16));
		if(mhd>16) {mhd=-1; hexs="?";}
		else {hexs="";}
	}
	if(mhd>=0) {
		var div16=1;
		var n16=0;
		while(mhd>0) {
			div16=Math.pow(16,mhd);
			n16=Math.floor(dec/div16);
			hexs+=dec2hex1(n16);
			dec=dec-div16*n16;
			mhd--;
		}
		hexs+=dec2hex1(dec); // Rest
	}
	// Laenge angleichen
	if(nhd>0) {
		if(hexs.substr(0,1)=="?" || hexs.length>nhd) {hexs=text_repeat("?",nhd);}
		else {
			var fill=text_repeat("0",nhd-hexs.length);
			hexs=fill+hexs;
		}
	}
	return hexs;
}

function hex2dec(hex) {
// Umwandlung Hex -> Dezimal
	var dec=0;
	var dig=0;
	var hexa=""+hex;
	while(hexa.length>0) {
		dig=hexa.charCodeAt(0)-48;
		if(dig>9) {dig-=7;}
		dec=16*dec+dig;
		hexa=hexa.substr(1,(hexa.length-1));
	}
	return dec;
}

function dec_to_bin(dec,stellen) {
	var bin="";
	if(dec<0) {dec=0;}
	if(stellen<0) {stellen=0;}
	if(stellen>256) {stellen=0;}
	while(dec>0) {
		if(dec & 1) {bin="1"+bin;}
		else {bin="0"+bin;}
		dec=dec>>1;
	}
	if(stellen) {
		bin=text_repeat("0",stellen)+bin;
		bin=bin.substr((bin.length-stellen),stellen);
	}
	return bin;
}

function usdatim_to_iso(us) {
// US-date-time string (M$IE) -> ISO
// mm/dd/yyyy hh:mi:ss
// if the match fails, the current date is returned
	//var datim=new Date();
	var iso="???";
	var res = us.match(/(\d?\d)\/(\d?\d)\/(\d?\d?\d\d) (\d?\d):(\d?\d):(\d?\d)/);
	if(res) {
		var n=parseInt(RegExp.$3,10);	// yy
		if(n<1900) {
			if(n>60) {n+=1900;}
			else {n+=2000;}
		}
		iso=n.toString()+"-";	// yy
		iso+=s2(RegExp.$1)+"-";	// mo
		iso+=s2(RegExp.$2)+" ";	// dd
		iso+=s2(RegExp.$4)+":";	// hh
		iso+=s2(RegExp.$5)+":";	// mi
		iso+=s2(RegExp.$6);	// ss
	}
	return iso;
	function s2(s) {	// private
		if(s.length<2) {s="0"+s;}
		return s;
	}
}

function rfc_to_iso(rfc) {
// decode RFC-822 string -> JS Date object
// Day, dd Mon yyyy hh:mi:ss +0100
// -> dd,mm,yyyy,hh,mi,ss,tz
// if the match fails, the current date is returned
	var iso="???";
	var res = rfc.match(/, (\d?\d) (...) (\d?\d?\d\d) (\d?\d):(\d?\d):(\d?\d)/);
	if(res) {
		var n=parseInt(RegExp.$3,10);	// yy
		if(n<1900) {
			if(n>60) {n+=1900;}
			else {n+=2000;}
		}
		iso=n.toString()+"-";	// yy
		var t=RegExp.$2;	// mo
		var i=0; n=0;
		for(i=0;i<monam_array.length;i++) {
			if(t==monam_array[i]) {n=i;break;} 
		}
		iso+=s2(n.toString())+"-";	// mo
		iso+=s2(RegExp.$1)+" ";	// dd
		iso+=s2(RegExp.$4)+":";	// hh
		iso+=s2(RegExp.$5)+":";	// mi
		iso+=s2(RegExp.$6);	// ss
	}
	return iso;
	function s2(s) {	// private
		if(s.length<2) {s="0"+s;}
		return s;
	}
}

// ********** Array-Funktionen **********

function array_sort_multidim(amul,idx) {
// Sortiert ein mehrdimensionales Array amul
// idx...Index des zu sortierenden Elements
	var i=0; var j=0; var tmp=null;
	for(i=0;i<(amul.length-1);i++) {
		for(j=i+1;j<amul.length;j++) {
			if(amul[j][idx]<amul[i][idx]) {
				// Elemente vertauschen
				tmp=amul[j]; 
				amul[j]=amul[i]; 
				amul[i]=tmp;
			}
		}
	}
}

// ********** Unicode-Funktionen **********

function string_to_utf8(str) {
	var utf8="";
	for(var i=0;i<str.length;i++) {utf8+=char_to_utf8(str.charAt(i));}
	return utf8;
}
function char_to_utf8(c) {
	var utf8="";
	if(c.length) {
		var uc=c.charCodeAt(0);
		if(uc<128) {utf8=String.fromCharCode(uc);}
		else if((uc>127) && (uc<2048)) {
			utf8+=String.fromCharCode((uc>>6)|192);
			utf8+=String.fromCharCode((uc&63)|128);
		}
		else {
			utf8+=String.fromCharCode((uc>>12)|224);
			utf8+=String.fromCharCode(((uc>>6)&63)|128);
			utf8+=String.fromCharCode((uc&63)|128);
		}
	}
	return utf8;
} 

function utf8_to_string(utf) {
	var str="";
	var o1=o2=o3=i=0;
	while(i<utf.length) {
		o1=utf.charCodeAt(i);
		// direkt codiert (1-Byte) 
		if (o1<128) {
			str+=String.fromCharCode(o1); 
		}
		// Fehler 
		else if(o1<192) {str+="?1?";}
		// 2-Byte UTF-8: U+0080..U+07FF 
		else if(o1<224) {
			o2=utf.charCodeAt(i+1);
			str+=String.fromCharCode(((o1&31)<<6) | (o2&63));
			i++;
		}
		// 3-Byte UTF-8: U+0800..U+FFFF 
		else if (o1<240) {
			o2=utf.charCodeAt(i+1); 
			o3=utf.charCodeAt(i+2);
			str+=String.fromCharCode(((o1&15)<<12) | ((o2&63)<<6) | (o3&63));
			i+=2;
		}
		// Fehler 
		else {str+="?2?";}
		i++; 
	}
	return str;
} 

// ********** CSS-Funktionen **********
function position_get(id) {
// returns array (x,y) of absolute Position
	var xy=new Array(0,0);
	var n=document.getElementById(id);
	// Gecko Syntax
	try{
		xy[0]=n.x; 
		xy[1]=n.y;
	}
	catch(e) {}
	// Damned M$ Algo
	if((!xy[0]) || (!xy[1])) {
		try{
			xy[0]=0; xy[1]=0;
			while(n) {
				xy[0]+=n.offsetLeft;
				xy[1]+=n.offsetTop;
				n=n.offsetParent;
			}
		}
		catch(e) {}
	}
	return(xy);
}
function pst_size_get(id) {
// returns array (dx,dy) of size in px
	var dxy=new Array(0,0);
	var n=document.getElementById(id);
	// Gecko Syntax
	try{
		dxy[0]=window.getComputedStyle(n,null).width;
		dxy[1]=window.getComputedStyle(n,null).height;
	}
	catch(e) {}
	// M$ Syntax
	if((!dxy[0]) || (!dxy[1])) {
		try{
			dxy[1]=n.currentStyle.height;
			dxy[0]=n.currentStyle.width;
		}
		catch(e) {}
	}
	return(dxy);
}

function pst_style_set(nid,css,val) {
// node.style.css=val
	var n=node_get(nid);
	try{
		var t="n.style."+css+"=\""+val+"\";"
		eval(t);
	}
	catch(e) {}
}

// ########## Sofort ausgefuehrte Funktionen ##########
get_my_url();

//alert("pstrainer.js z");

// ########## eof pstrainer.js ############################################################# 
