/* (c) 2004 by Phil Ronan *//*****************************************************	randomName():		Produces names for functions & variables that are	random but unique. Uses no vowels, so the only reserved	word we need to check for is 'try'.*****************************************************/var rn = new Array();nrn = 0;function randomName(a,b){	var i, x, n, f, cons='bcdfghjklmnpqrstvwxyz_';		do {		f = false;		x='';		n=Rnd(a)+b;		for (i=0; i<n; i++) x += cons.charAt(Rnd(cons.length));		if (x=='try') f = true;		else for (i=0; i<nrn; i++) if (x == rn[i]) { f=true; i=rn; }	} while (f);	rn[nrn++] = x;	return x;}/*****************************************************	scramble():		Encodes an email address with two random keys*****************************************************/function scramble(){	var nameTxt, emailTxt;	var okLink = new RegExp("^[a-z0-9\-\.& ]+$", "gi");	nameTxt = tidyUp(document.forms['s'].elements['n'].value);	emailTxt = tidyUp(document.forms['s'].elements['e'].value);			/* Check for a valid email address */		if (emailTxt == '') {		alert('Please enter an email address first.');		return;	}	if (!validEmailAddress(emailTxt) && !confirm('"'+emailTxt+'" doesn\'t look like a valid address. Continue ayway?')) return;			/* Generate the two keys */		do {		key_f = Rnd(255)+1;		key_s = Rnd(255)+1;	} while (key_f==key_s);		/* Generate the human-readable email address */		hr = emailTxt.replace(/\./g,' [dot] ');	hr = hr.replace(/@/,' [at] ');			/* Incorporate the user's name into the email address */		if (nameTxt != '') {		if (hasNonAscii(nameTxt))			alert('The name "'+nameTxt+'" will be rendered as "'+(nameTxt=stripAccents(nameTxt))+'".');		nameTxt = nameTxt.replace(/"/g,'\'');		if ( !(okLink.test(nameTxt)) ) nameTxt = '"'+nameTxt+'"';		emailTxt = escape(nameTxt)+'%20%3c'+emailTxt+'%3e';	}		/* Get some random function & variable names */		rn.length = 0;	var decodeLink = randomName(3,4);	var fixedKey = randomName(2,3);	var slidingKey = randomName(2,1);	var src = randomName(2,1);	var mailTo_ = randomName(2,1);	var plainText = randomName(2,1);	var get1Char = randomName(2,1);	var count = randomName(2,1);	var tmpChar = randomName(2,1);	var thisChar = randomName(2,1);		var t='';	var hex1 = 256+Rnd(256);	var hex2 = ('0x'+hex1) * 1 - key_f;		/* Spool out the results */		t += '\<SCRIPT type="text/javascript"\>\n';	t += 'var '+fixedKey+'=\'0x\';'+_crlf();	t += 'function '+decodeLink+'('+src+')';	t += '{'+_crlf();	t += 'var '+mailTo_+','+plainText+'=\'\','+count+'=0,'+tmpChar+','+slidingKey+'='+get1Char+'()^'+fixedKey+';'+_crlf();	t += 'for('+count+'++;'+count+'<'+src+'.length;'+count+'++)'+_crlf()+'{';	t += tmpChar+'='+get1Char+'()^'+slidingKey+';';	t += tmpChar+'=(('+tmpChar+'&170)>>1|('+tmpChar+'&85)<<1);';	t += plainText+'+=String.fromCharCode('+tmpChar+'); ';	t += slidingKey+' = (++'+slidingKey+_spc()+'%'+_spc()+'256);';	t += '}';	t += mailTo_+'=\'l\\164o\';';	t += mailTo_+'=\'m\\141i\'+'+mailTo_+'+\'\\072\';'+_crlf();	t += 'if((/^[a-z0-9\\*@\\-_\\+\\.\\/%]+$/gi.test('+plainText+'))&&'+_spc()+'confirm(\'S\\145nd a\\156 e\'+'+mailTo_+'.substr(0,4)+\' to \'+unescape('+plainText+')+\'?\'))'+_spc()+'location.href='+mailTo_+'+'+plainText+';'+_crlf();	t += 'return false;'+_crlf();	t += 'function '+get1Char+'()'+_crlf()+'{';	t += 'var '+thisChar+'='+src+'.charAt('+count+');';	t += 'if(/[0-9a-f]/.test('+thisChar+'))'+_crlf();	t += 'return 1*(\'0x\'+'+src+'.substr('+count+'++,2));'+_crlf();	t +='else return '+src+'.charCodeAt('+count+');'+_crlf();	t += '}'+_crlf();	t += '}'+_crlf();	t += fixedKey+'+='+hex1+';'+_crlf();	t += 'document.write(\'\<A href="#" onclick="return '+decodeLink+'(\\\''+munge(emailTxt,key_f,key_s)+'\\\');"\>\');\n';	t += '\</SCRIPT\>'+hr+'\<SCRIPT type="text/javascript"\>\n';	t +='document.write(\'\<\'+\'/A\>\');';	t += 'setTimeout(\''+fixedKey+'-='+hex2+'\','+(Rnd(20)+190)*1+');';	t += '\</SCRIPT\>';		document.forms['s'].elements['t'].value = t;	document.forms['s'].elements['tb'].disabled = false;}/*****************************************************	hasNonAscii():		Checks for non-ASCII characters in a string	(I know a RegExp would be faster, but some browsers	seem to have problems with 8-bit characters. This is	slower, but safer.)*****************************************************/function hasNonAscii(a){	var f=false;	if (a.length > 0) for (var i=0; i<a.length; i++) if (a.charCodeAt(i) > 127) f=true;	return f;}/*****************************************************	_spc(), _crlf():		Return a space or carriage return. Sometimes.	Used to randomize output.*****************************************************/function _spc(){	if (Rnd(3)==0) return ' '; else return '';}function _crlf(){	if (Rnd(2)==0) return '\n'; else return '';}/*****************************************************	munge():		This is the guts of the encoding scheme*****************************************************/function munge(srcTxt,fkey,skey){	var i, encTxt='', c, skey, e='0123456789abcdef';	if (srcTxt.length > 0) {		addch((skey & 0xaa)>>1|(skey & 0x55)<<1,0);		skey ^= fkey;		for (i=0; i<srcTxt.length;i++) {			addch(srcTxt.charCodeAt(i),skey);			skey = (++skey % 256);		}	}	return encTxt;		function addch(x,z) {		var y = ( ((x & 0xaa) >> 1) | ((x & 0x55) << 1) ) ^ z;		if ( (y>=48 && y<=57) || (y>=97 && y<=102) || y<=34 || y>126 || y==92 || y==60 || y==62 || y==39 ) {			encTxt += e.charAt((y & 0xf0) >> 4);			encTxt += e.charAt(y & 0x0f);		} else encTxt += String.fromCharCode(y);	}}/*****************************************************	validEmailAddress():		Standard email address checker*****************************************************/function validEmailAddress(em){	var t_split, t_name, t_domain, t_result;	var re_bad = /(@)|(\.\.)|(^\.)|(\.$)/;	var re_ok1 = /^[^\x00-\x1f <>"]+$/;	var re_ok2 = /^([A-Za-z0-9\-_]+\.){1,5}[A-Za-z]{2,5}$/;		t_split = em.split("@");	t_name = t_split[0];	t_domain = t_split[1];		t_result = false;		if (t_name && t_domain && (t_split.length == 2)) {		if (!re_bad.test(t_name)	 &&				re_ok1.test(t_name)		 &&				!re_bad.test(t_domain) &&				re_ok2.test(t_domain)	 ) {			t_result = true;		}	}	return t_result;}/*****************************************************	insert_tool():		Creates the HTML interface for this tool*****************************************************/function insert_tool(){	document.write('\<FORM action="#" id="s" onsubmit="return false"\>\n');	document.write('\<P\>\<TABLE border="0" cellpadding="0" cellspacing="0"\>\n');	document.write('\<TR\>\<TD class="l"\>');	document.write('\<LABEL for="n"\>Full name \<SMALL\>(optional)\<\/SMALL\>:\<\/LABEL\>');	document.write('\<\/TD\>\<TD class="r"\>');	document.write('\<INPUT id="n" type="text" class="f" value="Your Name Here" size="30" maxlength="60"\>');	document.write('\<\/TD\><\/TR\>\n');	document.write('\<TR\>\<TD class="l"\>');	document.write('\<LABEL for="e"\>Email address:\<\/LABEL\>');	document.write('\<\/TD\>\<TD class="r"\>');	document.write('\<INPUT id="e" type="text" class="f" value="username@domain.com" size="30" maxlength="60"\>');	document.write('\<\/TD\><\/TR\>\n');	document.write('\<\/TABLE\>\<\/P\>\n');	document.write('\<P\>\<INPUT type="button" value="Generate code" onclick="scramble(); return false;"\> &nbsp; \<INPUT type="reset" value="Clear form" onclick="return clear_form();"\>\<\/P\>\n');	document.write('\<P\>Results (copy into your HTML source):\<BR\>\n');	document.write('\<TEXTAREA cols="50" rows="16" id="t" class="g" wrap="off"\>(Results will appear here when you press the &quot;Generate code&quot; button)\</TEXTAREA\>\</P\>\n');	document.write('\<P class="center"\><SMALL>If your browser allows pop-ups, you can test the code by clicking here &rarr;</SMALL> \<INPUT id="tb" type="button" disabled="disabled" value="Test" onclick="testResults(); return false;"\>\</P\>\n');	document.write('\</FORM\>\n');}/* This is executed when the reset button is pressed   Note: the default text is provided as an example to   the user. This rouine is needed to remove it. */function clear_form(){	var el = document.forms[0].elements;	el[0].value = el[1].value = el[4].value = "";	document.forms['s'].elements['tb'].disabled = true;	return false;}/*****************************************************	stripAccents():		Strips 8-bit characters from ISO-8859-1 encoded 	text and replaces them with unaccented equivalents	whenever possible*****************************************************/var iso2ASCII;iso2ASCII = new Array('','','','','','','','','','','','','','','','',											'','','','','','','','','','','','','','','','',											' ','','cent','pound','','yen','|','','','(c)','a','<<','-','-','(r)','^',											'deg', '+/-', '2', '3', '\'', 'u', '', '.','','1','o','>>','1/4','1/2','3/4','',											'A','A','A','A','A','A','AE','C','E','E','E','E','I','I','I','I',											'TH','N','O','O','O','O','O','x','O','U','U','U','U','Y','TH','ss',											'a','a','a','a','a','a','ae','c','e','e','e','e','i','i','i','i',											'th','n','o','o','o','o','o','/','o','u','u','u','u','y','th','y');function stripAccents(a){	var b, i, c;	if (a.length > 0) {		b = '';		for (i=0; i<a.length; i++) {			c = a.charCodeAt(i);			if (c >= 128 && c <= 255) b += iso2ASCII[c-128]; else if (c < 128) b += String.fromCharCode(c);		}		a = b;	}	return a;}/*****************************************************	testResults():		Open a pop-up window where the user can test the	results*****************************************************/var popWin = false;var popReloadFlag = false;function testResults(){	var wTxt, w, p, o, x, t = document.forms['s'].elements['t'].value;		if (t==document.forms['s'].elements['t'].defaultValue || t=='') {		alert('Please press the "Generate code" button first.');		return false;	}	popReloadFlag = true;	if (!popWin || popWin.closed) {		w = setTimeout('noPopError()',500);		popWin=window.open('','Results','width=400,height=240,resizable,status=1,scrollbars=1,screenX=300,screenY=200,left=300,top=200');		clearTimeout(w);		o = typeof(popWin);		if ( (!(/object/i.test(o)) && !(/window/i.test(o))) || popWin.closed ) return noPopError();	} else popWin.focus();		wTxt = '\<!DOCTYPE HTML PUBLIC "-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN" "http:\/\/www.w3.org\/TR\/html4\/loose.dtd"\>\n';	wTxt += '\<HTML lang="en"\>\n';	wTxt += '\<HEAD\>\n';	wTxt += '\<META http-equiv="Content-Type" content="text\/html; charset=iso-8859-1"\>\n';	wTxt += '\<META http-equiv="Content-Script-Type" content="text\/javascript"\>\n';	wTxt += '\<TITLE\>Results\<\/TITLE\>\n';	wTxt += '\<\/HEAD\>\n';	wTxt += '\<BODY onunload="opener.reloadChild();"\>\n';	wTxt += '\<H3\>Test results:\</H3\>\n';	wTxt += '\<P\>This is what your link looks like in a browser with Javascript enabled:\n';	wTxt += t;	wTxt += '\n\</P\>\n';	wTxt += '\<P\>And this is what your link looks like in a browser without Javascript:\n';	while ((x=t.indexOf('\<SCRIPT')) >= 0) {		t = t.substring(0,x) + t.substring(t.indexOf('\</SCRIPT\>')+9,t.length)	}	wTxt += t;	wTxt += '\n\</P\>\n';	wTxt += '\<HR\>\n\<P align="center"\>\<A href="#" onclick="window.close()"\>(Close this window)\</A\>\</P\>\n';	wTxt += '\</BODY\>\n\</HTML\>\n';	// alert(wTxt);	popWin.document.open('text/html');	popWin.document.write(wTxt);	popWin.document.close();	popReloadFlag = false;	return false;}function reloadChild(){	if (!popReloadFlag) setTimeout('if (!popWin.closed) testResults()', 100);}function noPopError(){	alert('Sorry, but I can\'t show you anything because your browser won\'t let me open a pop-up window.');	popReloadFlag = false;	return false;}/*****************************************************	UTILITY FUNCTIONS*****************************************************/function LTrim(str){	for (var i=0; i<str.length && str.charAt(i) <= ' '; i++);	return str.substring(i,str.length);}function RTrim(str){	for (var i=str.length-1; i>=0 && str.charAt(i) <= ' '; i--);	return str.substring(0,i+1);}function Trim(str){	return LTrim(RTrim(str));}function tidyUp(str){	str = str.replace(/[\000-\037]/g,' ');	str = Trim(str);	return str;}function Rnd(n){	return Math.floor(Math.random()*0.9999999*n);}