Password Composer

By meena Last update Jun 14, 2008 — Installed 104 times.
 // ==UserScript==
		   // @name		   Password Composer
		   // @namespace   Rajputgal's pasword composer
		   // @description  Generate site specific passwords based on a master password
		   // @include	   *
		   // @version	   1.08
		   // ==/UserScript==

		   // based on code by Rajptgal
		   // and included here with their gracious permission

		   var clearText = false; // show generated passwds in cleartext
		   var topDomain = false; // use top domain instead of full host
		   function errLog(msg) {
			   if (typeof(GM_log == "function")) {
				   GM_log(msg);
			   } else {
				   window.status = msg;
			   }
		   }
		   
		   function hex_md5(s) {
			   return binl2hex(core_md5(str2binl(s), s.length * 8));
		   }
		   function core_md5(x, len) {
			   x[len >> 5] |= 0x80 << ((len) % 32);
			   x[(((len + 64) >>>9) << 4) + 14] = len;
			   var a = 1732584193;
			   var b = -271733879;
			   var c = -1732584194;
			   var d = 271733878;
			   for (var i = 0; i < x.length; i += 16) {
				   var olda = a;
				   var oldb = b;
				   var oldc = c;
				   var oldd = d;
				   a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
				   d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
				   c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
				   b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
				   a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
				   d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
				   c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
				   b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
				   a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
				   d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
				   c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
				   b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
				   a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
				   d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
				   c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
				   b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
				   a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
				   d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
				   c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
				   b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
				   a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
				   d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
				   c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
				   b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
				   a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
				   d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
				   c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
				   b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
				   a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
				   d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
				   c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
				   b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
				   a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
				   d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
				   c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
				   b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
				   a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
				   d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
				   c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
				   b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
				   a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
				   d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
				   c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
				   b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
				   a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
				   d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
				   c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
				   b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
				   a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
				   d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
				   c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
				   b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
				   a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
				   d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
				   c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
				   b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
				   a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
				   d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
				   c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
				   b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
				   a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
				   d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
				   c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
				   b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
				   a = safe_add(a, olda);
				   b = safe_add(b, oldb);
				   c = safe_add(c, oldc);
				   d = safe_add(d, oldd);
				}
				return Array(a, b, c, d);
			} 
			function md5_cmn(q, a, b, x, s, t) {
				return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),
			b);
		}
		function md5_ff(a, b, c, d, x, s, t) {
			return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
		}
		function md5_gg(a, b, c, d, x, s, t) {
			return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
		}
		function md5_hh(a, b, c, d, x, s, t) {
			return md5_cmn(b ^ c ^ d, a, b, x, s, t);
		}
		function md5_ii(a, b, c, d, x, s, t) {
			return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
		}
		function safe_add(x, y) {
			var lsw = (x & 0xFFFF) + (y & 0xFFFF);
			var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
			return (msw << 16) | (lsw & 0xFFFF);
		}
		function bit_rol(num, cnt) {
			return (num << cnt) | (num >>>(32 - cnt));
		}
		function str2binl(str) {
			var bin = Array();
			var mask = (1 << 8) - 1;
			for (var i = 0; i < str.length * 8; i += 8) {
				bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << (i % 32);
			}
			return bin;
		}
		function binl2hex(binarray) {
			var hex_tab = '0123456789abcdef';
			var str = '';
			for (var i = 0; i < binarray.length * 4; i++) {
				str+=hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF)+
				hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF);
			}
			return str;
		}

		function mpwd_getHostname() {
			var re = new RegExp('https*://([^/]+)');
			var url = document.location.href.toLowerCase();
			var host = url.match(re)[1];
			// look at minimum domain instead of host
			// see http://labs.zarate.org/passwd/
			if (topDomain) {
				host = host.split('.');
				if (host[2] != null) {
				s = host[host.length-2] + '.' + host[host.length-1];
				domains='ab.ca|ac.ac|ac.at|ac.be|ac.cn|ac.il|ac.in|ac.jp|'+
		'ac.kr|ac.nz|ac.th|ac.uk|ac.za|adm.br|adv.br|agro.pl|ah.cn|aid.pl|alt'+
		'.za|am.br|arq.br|art.br|arts.ro|asn.au|asso.fr|asso.mc|atm.pl|auto.p'+
		'l|bbs.tr|bc.ca|bio.br|biz.pl|bj.cn|br.com|cn.com|cng.br|cnt.br|co.ac'+
		'|co.at|co.il|co.in|co.jp|co.kr|co.nz|co.th|co.uk|co.za|com.au|com.br'+
		'|com.cn|com.ec|com.fr|com.hk|com.mm|com.mx|com.pl|com.ro|com.ru|com.'+
		'sg|com.tr|com.tw|cq.cn|cri.nz|de.com|ecn.br|edu.au|edu.cn|edu.hk|edu'+
		'.mm|edu.mx|edu.pl|edu.tr|edu.za|eng.br|ernet.in|esp.br|etc.br|eti.br'+
		'|eu.com|eu.lv|fin.ec|firm.ro|fm.br|fot.br|fst.br|g12.br|gb.com|gb.ne'+
		't|gd.cn|gen.nz|gmina.pl|go.jp|go.kr|go.th|gob.mx|gov.br|gov.cn|gov.e'+
		'c|gov.il|gov.in|gov.mm|gov.mx|gov.sg|gov.tr|gov.za|govt.nz|gs.cn|gsm'+
		'.pl|gv.ac|gv.at|gx.cn|gz.cn|hb.cn|he.cn|hi.cn|hk.cn|hl.cn|hn.cn|hu.c'+
		'om|idv.tw|ind.br|inf.br|info.pl|info.ro|iwi.nz|jl.cn|jor.br|jpn.com|'+
		'js.cn|k12.il|k12.tr|lel.br|ln.cn|ltd.uk|mail.pl|maori.nz|mb.ca|me.uk'+
		'|med.br|med.ec|media.pl|mi.th|miasta.pl|mil.br|mil.ec|mil.nz|mil.pl|'+
		'mil.tr|mil.za|mo.cn|muni.il|nb.ca|ne.jp|ne.kr|net.au|net.br|net.cn|n'+
		'et.ec|net.hk|net.il|net.in|net.mm|net.mx|net.nz|net.pl|net.ru|net.sg'+
		'|net.th|net.tr|net.tw|net.za|nf.ca|ngo.za|nm.cn|nm.kr|no.com|nom.br|'+
		'nom.pl|nom.ro|nom.za|ns.ca|nt.ca|nt.ro|ntr.br|nx.cn|odo.br|on.ca|or.'+
		'ac|or.at|or.jp|or.kr|or.th|org.au|org.br|org.cn|org.ec|org.hk|org.il'+
		'|org.mm|org.mx|org.nz|org.pl|org.ro|org.ru|org.sg|org.tr|org.tw|org.'+
		'uk|org.za|pc.pl|pe.ca|plc.uk|ppg.br|presse.fr|priv.pl|pro.br|psc.br|'+
		'psi.br|qc.ca|qc.com|qh.cn|re.kr|realestate.pl|rec.br|rec.ro|rel.pl|r'+
		'es.in|ru.com|sa.com|sc.cn|school.nz|school.za|se.com|se.net|sh.cn|sh'+
		'op.pl|sk.ca|sklep.pl|slg.br|sn.cn|sos.pl|store.ro|targi.pl|tj.cn|tm.'+
		'fr|tm.mc|tm.pl|tm.ro|tm.za|tmp.br|tourism.pl|travel.pl|tur.br|turyst'+
		'yka.pl|tv.br|tw.cn|uk.co|uk.com|uk.net|us.com|uy.com|vet.br|web.za|w'+	
		'eb.com|www.ro|xj.cn|xz.cn|yk.ca|yn.cn|za.com';
				domains=domains.split('|');
				for(var i=0; i<domains.length; i++) {
				if (s==domains[i]) {
				s=host[host.length-3]+'.'+s;
				break;
				}
				}
				} else {
				s = host.join('.');
				}
				return s;
			} else {
				// no manipulation (full host name)
				return host;
			}
		}
		
		// generate the password and populate original form
		function mpwd_doIt() {
			if (!mpwd_check_password()) { return; }
			var master = document.getElementById('masterpwd').value;
			var domain = document.getElementById('mpwddomain').value.toLowerCase();
			// remove panel before messing with passwd fields
			mpwd_remove();
			if (master != '' && master != null) {
				var i=0, j=0, p=hex_md5(master+':'+domain).substr(0,8);
				var inputs = document.getElementsByTagName('input');
				for(i=0;i<inputs.length;i++) {
				var inp = inputs[i];
				if(inp.getAttribute('type') == 'password') {
				inp.value=p;
				if (clearText) {
				inp.type = 'text';
				var cl = inp.getAttribute("class") || "";
				// hack to mark passwd fields by setting class name
				// intentde to find them on a second pass, if
				// type is modified to text
				if (cl.indexOf("mpwdpasswd") == -1) {
				inp.setAttribute("class", cl + " mpwdpasswd");
				}
				}
				// inp.focus();
				} else if(inp.getAttribute('type') == 'text') {
				var nm = inp.getAttribute('name').toLowerCase();
				var cl = inp.getAttribute("class") || "";
				// field named something like passwd or class mpwdpasswd
				if (nm.indexOf('password')!=-1 ||
				nm.indexOf('passwd')!=-1 ||
				cl.indexOf("mpwdpasswd") != -1) {
				inp.value=p;
				if (! clearText) inp.type = 'password';
				// inp.focus();
				}
				}
			}
			// give focus to first password field
			getPwdFld().focus();
		}
	};

	// check for multiple passwd fields per form (e.g. 'verify passwd')
	function hasMultiplePwdFields() {
		// find any form that has 2+ password fields as children
		// note literal '>' char in xpath expression!
		var xpres = document.evaluate(
			"count(//form[count(//input[@type='password']) > 1])",
			document, null, XPathResult.ANY_TYPE, null);
		return(xpres.numberValue > 0);
	}
	// find first password field
	function getPwdFld() {
		var L = document.getElementsByTagName('input');
		for (var i = 0; i < L.length; i++) {
			var nm, tp, cl;
			try { nm = L[i].getAttribute("name") || ""; } catch(e) { };
			try { tp = L[i].getAttribute("type") || ""; } catch(e) { };
			try { cl = L[i].getAttribute("class") || ""; } catch(e) { };
			if ((tp == "password") ||
				(tp == "text" && nm.toLowerCase().substring(0,5) == "passw") ||
				(cl.indexOf("mpwdpasswd") > -1)) {
				return L[i];
			}
		}
		return null;
	}
	function mpwd_remove() {
		var body = document.getElementsByTagName('body')[0];
		body.removeChild(document.getElementById('mpwd_bgd'));
		body.removeChild(document.getElementById('mpwd_panel'));
	}
	function mpwd_keyup(e) {
		mpwd_check_password();
		if (e.keyCode == 13 || e.keyCode == 10) {
			mpwd_doIt();
		} else if (e.keyCode == 27) {
			mpwd_remove();
		}
	}
	function mpwd_check_password() {
		var pwd = document.getElementById('masterpwd');
		var pwd2 = document.getElementById('secondpwd');
		if (!pwd2) return 1;
		if (pwd.value != pwd2.value && pwd2.value != '') {
			pwd2.style.background='#f77';
			pwd2.style.borderColor='red';
			return 0;
		} else {
			pwd2.style.background = 'white';
			pwd2.style.borderColor='#777';
			return 1;
		}
	}
	function mpwd_panel(event) {
		var pwdTop = 0;
		var pwdLeft = 0;
		if (document.getElementById('mpwd_panel')) {
			mpwd_remove();
			return;
		}
		try {
			var obj = getPwdFld();
			if (obj.offsetParent) {
				while (obj.offsetParent) {
				pwdTop += obj.offsetTop;
				pwdLeft += obj.offsetLeft;
				obj = obj.offsetParent;
				}
			}
		} catch (e) {
		  pwdTop = 10;
		  pwdLeft = 10;
		}
		// full document width and height as rendered in browser:
		var html = document.getElementsByTagName('html')[0];
		var pag_w = parseInt(document.defaultView.getComputedStyle(html,
			'').getPropertyValue('width'));
		var pag_h = parseInt(document.defaultView.getComputedStyle(html,
			'').getPropertyValue('height'));

		var div = document.createElement('div');
		div.style.color='#777';
		div.style.padding='5px';
		div.style.backgroundColor='white';
		div.style.border='1px solid black';
		div.style.borderBottom='3px solid black';
		div.style.borderRight='2px solid black';
		div.style.MozBorderRadius='10px';
		div.style.fontSize='9pt';	
		div.style.fontFamily='sans-serif';
		div.style.lineHeight='1.8em';
		div.style.position='absolute';
		div.style.width='230px';
		// keep panel at least 10 px away from right page edge
		div.style.left = ((250 + pwdLeft > pag_w)? pag_w - 250 : pwdLeft) +
	'px';
		div.style.top = pwdTop + 'px';
		div.style.zIndex = 9999; // make sure we're visible/on top
		div.setAttribute('id', 'mpwd_panel');
		div.appendChild(document.createTextNode('Master password: '));

		var icnShow = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAA'+
	'AAMCAIAAADZF8uwAAAAkUlEQVR4nGL4TwRgwCWxc%2BfOU6dOQRUZowKI6N%2B%2Ff93c'+
	'3Ly8vBCKMI3Ztm1bZ2dnenr65cuXcSoKCwt7%2BPDh4cOHs7KysCt6%2Ffo1Pz%2B%2Fs'+
	'7Ozk5MTkPH582csiiZMmDBlyhQIu6amZubMmVgUGRkZvXr1CsK%2Bffu2oaEhdjdBAFyK'+
	'aEV4AFQRLmOQAQAAAP%2F%2FAwB27VC%2BrCyA0QAAAABJRU5ErkJggg%3D%3D';
		var icnHide = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAA'+
	'AAMAgMAAAArG7R0AAAADFBMVEX%2F%2F%2F%2FMzMxmZmYzMzM7z8wMAAAAJ0lEQVQImW'+
	'NgAIMEhv%2FH0hgOMEYwHGAD0kD%2BAaAoBBuA8f%2F%2FH0AKARI5DD%2FY1kZdAAAAA'+
	'ElFTkSuQmCC';
		var show = document.createElement('img');
		show.setAttribute('src', (clearText) ? icnShow : icnHide);
		show.setAttribute('id', "icnShow");
		show.setAttribute('title', 'Show or hide generated password');
		show.style.paddingRight = '4px';
		show.style.display='inline'; // some stupid sites set this to block
		show.style.cursor = 'pointer';
		show.addEventListener('click', function(event) {
			clearText = !clearText;
			document.getElementById("icnShow").setAttribute('src',
				(clearText) ? icnShow : icnHide);
			document.getElementById('masterpwd').focus();
		}, true);
		div.appendChild(show);

		var pwd = document.createElement('input');
		pwd.style.border='1px solid #777';
		pwd.setAttribute('type','password');
		pwd.setAttribute('id','masterpwd');
		pwd.style.width = '100px';
		pwd.style.fontSize='9pt';
		pwd.style.color='#777';
		// fire action if RETURN key is typed
		div.appendChild(pwd);
		div.appendChild(document.createElement('br'));
		if (hasMultiplePwdFields()) {
			// only of a 'verify field' is on original page
			div.appendChild(document.createTextNode('Check password: '));
		var pwd2 = document.createElement('input');
		pwd2.setAttribute('type','password');
		pwd2.setAttribute('id','secondpwd');
		pwd2.style.width = '100px';
		pwd2.style.color='#777';
		pwd2.style.border='1px solid #777';	
		pwd2.style.fontSize='9pt';
		div.appendChild(pwd2);
		div.appendChild(document.createElement('br'));
	}
	
	div.appendChild(document.createTextNode('Domain: '));
	
	var subicn = document.createElement('img');
	subicn.setAttribute('src', 'data:image/png;base64,iVBORw0KGgoAAAAN'+
  'SUhEUgAAAAkAAAAJCAAAAADF%2BlnMAAAAGUlEQVR42mNogQGGlv8QgIvFAAL%2FCaqDA'+
  'QCbtDxVGHcjrgAAAABJRU5ErkJggg%3D%3D');
	subicn.setAttribute('id', "icnSubdom");
	subicn.setAttribute('title', 'Toggle use sub domain');
	subicn.style.display='inline';
	subicn.style.paddingRight = '4px';
	subicn.style.cursor = 'pointer';
	subicn.addEventListener('click', function(event) {
		toggleSubdomain();
		document.getElementById('masterpwd').focus();
	}, true);
	div.appendChild(subicn);

	var domn = document.createElement('input');
	domn.setAttribute('type','text');
	domn.setAttribute('value', mpwd_getHostname());
	domn.setAttribute('id','mpwddomain');	
	domn.setAttribute('title','Edit domain name for different password');
	domn.style.width = '150px';
	domn.style.border = 'none';
	domn.style.fontSize='9pt';
	domn.style.color='#777';
	div.appendChild(domn);

	div.addEventListener('keyup', mpwd_keyup, true);

	var bgd = document.createElement('div');
	bgd.setAttribute('id','mpwd_bgd');
	bgd.style.position='absolute';
	bgd.style.top='0px';
	bgd.style.left='0px';
	bgd.style.backgroundColor='black';
	bgd.style.opacity='0.35';
	bgd.style.height = pag_h + 'px';
	bgd.style.width = pag_w + 'px';
	bgd.style.zIndex='9998';
	bgd.addEventListener('click', mpwd_remove, true);
		var body = document.getElementsByTagName('body')[0];
		body.appendChild(bgd);
		body.appendChild(div);
		setTimeout("document.getElementById('masterpwd').focus();", 333);
		initSubdomainSetting();
	};

	// Setting: use sub domain
	function initSubdomainSetting() {
		if (typeof(GM_getValue) == 'function') {
			topDomain = GM_getValue('topDomain', false);
		}
		updateSubDomainSetting();
	}

	function toggleSubdomain() {
		topDomain = !topDomain;
		if (typeof(GM_setValue) == 'function') {
			GM_setValue('topDomain', topDomain);
		}
		updateSubDomainSetting();
	}
	
	function updateSubDomainSetting() {
		var icnPlus = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAA'+
	'AAJCAAAAADF%2BlnMAAAAHUlEQVR42mNogQGGlv8QAGExYLAYQACnLFwvDAAA6Fk4WdfT'+
	'%2FgAAAAAASUVORK5CYII%3D';
		var icnMin = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAA'+
	'AJCAAAAADF%2BlnMAAAAGUlEQVR42mNogQGGlv8QgIvFAAL%2FCaqDAQCbtDxVGHcjrgA'+
	'AAABJRU5ErkJggg%3D%3D';
		 document.getElementById("icnSubdom").setAttribute('src',
			(topDomain) ? icnMin : icnPlus);
		document.getElementById("mpwddomain").setAttribute('value',
			 mpwd_getHostname());
	}

	function mpwd_launcher() {
		// image 12px
		var bullet = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAA'+
	'AMCAYAAABWdVznAAAAX0lEQVR4nGL4%2F%2F8%2FAykYwkhL%2B08IR0VFIWkAUn%2F%2'+
	'B%2FMGJoRqysGoASRKtAWw9SOjMGRTN%2BG0AKgYLQzUT1AC3iVgNcGdBMVE2EOVpQhhV'+
	'AxCDBAhhFA3EYgAAAAD%2F%2FwMAKhyYBtU1wpoAAAAASUVORK5CYII%3D';
		var pwdTop = 0;
		var pwdLft = 0;
		var obj;
		try {
			obj = getPwdFld();
			if (obj.offsetParent) {
				while (obj.offsetParent) {
				pwdTop += obj.offsetTop;
				pwdLft += obj.offsetLeft;
				obj = obj.offsetParent;
				}
				}
				} catch (e) {
				    pwdTop = 10;
				pwdLft = 10;
				}
				// return if no passwd field is found
				if (! obj) return;
				var bull = document.createElement('img');
				bull.style.position='absolute';
				bull.style.top = pwdTop + 'px';
				bull.style.left = (pwdLft - 12) + 'px';
				bull.setAttribute('src', bullet);
				bull.setAttribute('title', 'Open Password Composer');
				bull.style.cursor = 'pointer';
				bull.addEventListener('click', mpwd_panel, true);
				bull.style.zIndex = 9999;
				document.getElementsByTagName('body')[0].appendChild(bull);
			}
			
			mpwd_launcher();
			// add menu command to manually launch passwd composer
			if (typeof(GM_registerMenuCommand == 'function')) {
				GM_registerMenuCommand("Show Password Composer", mpwd_panel);
			}