/*
	This is the library of generic functions that can be included using $.include("functionName"); in any bookmarklet.
	Use it to share functionality that is needed by multiple bookmarklets so that you only have to update one copy.
*/

var $={
			
	getElementsByClass:function(/*nodeName*/n,/*className*/c){
		try{
			var /*outputList*/o=[];
			var /*unfilteredNodeList*/e=document.getElementsByTagName(/*nodeName*/n);
			for(var i=0;i</*unfilteredNodeList*/e.length;i++)
				if(/*unfilteredNodeList*/e[i].className==/*className*/c)
					/*outputList*/o.push(/*unfilteredNodeList*/e[i]);
			return /*outputList*/o;
		}catch(e){alert("getElementsByClass "+e.description);}
	},

	attributesMatch:function(/*targetNode*/e,/*matchExpression*/r /*,attribName1, attribName2,...*/){
		try{
			var /*arguments*/a=arguments;
			for(var i=2;i</*arguments*/a.length;i++)
				if(/*targetNode*/e.getAttribute(/*arguments*/a[i]) && /*targetNode*/e.getAttribute(/*arguments*/a[i]).match(/*matchExpression*/r))
					return true;
		}catch(e){alert("attributesMatch "+e.description);}
	},

	propertiesMatch:function(/*targetNode*/e,/*matchExpression*/r /*,propName1, propName2,...*/){
		try{
			var /*arguments*/a=arguments;
			for(var i=2;i</*arguments*/a.length;i++)
				if(/*targetNode*/e[/*arguments*/a[i]] && /*targetNode*/e[/*arguments*/a[i]].match(/*matchExpression*/r))
					return true;
		}catch(e){alert("propertiesMatch "+e.description);}
	},

	fixScope:function(/*targetFunction*/t,/*scopeObject*/s){
		try{
			return(function(){
				return /*targetFunction*/t.apply(/*scopeObject*/s,arguments);
			});
		}catch(e){alert("fixScope "+e.description);}
	},

	silenceEvt:function(/*event*/e){
		try{
			/*event*/e.preventDefault();
			/*event*/e.stopPropagation();
		}catch(e){alert("silenceEvt "+e.description);}
	},

	addEventListener:function(/*targetNode*/e,/*eventType*/t,/*callbackFunc*/f){
		try{
			if(/*targetNode*/e.addEventListener){
				/*targetNode*/e.addEventListener(/*eventType*/t,/*callbackFunc*/f,false);
				return /*callbackFunc*/f;
			}else if(/*targetNode*/e.attachEvent){
				/*targetNode*/e.attachEvent("on"+/*eventType*/t,/*callbackFunc*/f);
				return /*callbackFunc*/f;
			}
		}catch(e){alert("addEventListener "+e.description);}
	},
	
	removeNonEssentialWhitespaces:function(/*inputString*/s){
		try{
			var /*spaceProtectors*/f=/(?:var\s|let\s|typeof\s|\sinstanceof\s|return\s|const\s|continue\s|export\s|for\s+each|import\s|label\s|case\s|throw\s|new\s|delete\s|get\s|set\s|\sin\s|void\s)/g,
				/*lastOffset*/p=0,
				/*match*/m,
				/*output*/o="";
			while(/*match*/m=/*spaceProtectors*/f.exec(/*inputString*/s)){
				/*output*/o+=/*inputString*/s.substring(/*lastOffset*/p,/*spaceProtectors*/f.lastIndex-/*match*/m[0].length).replace(/\s/g,"")+m[0].replace(/\s+/g," ");
				/*lastOffset*/p=/*spaceProtectors*/f.lastIndex;
			}
			if(/*lastOffset*/p</*inputString*/s.length)
				/*output*/o+=/*inputString*/s.substring(/*lastOffset*/p,/*inputString*/s.length).replace(/\s/g,"");
			return(/*output*/o);
		}catch(e){alert("removeNonEssentialWhitespaces "+e.description);}
	},
	
	removeNonLiteralWhitespaces:function(/*inputString*/s){
		try{
			var /*findDelimiters*/f=/(\\*)([\/"'])/g,
				/*lastDelimiter*/l="",
				/*output*/o="",
				/*lastOffset*/p=0,
				/*match*/m;
			
			while(/*match*/m=/*findDelimiters*/f.exec(/*inputString*/s)){
				if((/*match*/m[1].length%2)==1) continue;
				
				if(/*lastDelimiter*/l==""){
					/*output*/o+=$.removeNonEssentialWhitespaces(/*inputString*/s.substring(/*lastOffset*/p,/*findDelimiters*/f.lastIndex));
					/*lastOffset*/p=/*findDelimiters*/f.lastIndex;
					/*lastDelimiter*/l=/*match*/m[2];
				}else if(/*lastDelimiter*/l==/*match*/m[2]){
					/*output*/o+=/*inputString*/s.substring(/*lastOffset*/p,/*findDelimiters*/f.lastIndex);
					/*lastOffset*/p=/*findDelimiters*/f.lastIndex;
					/*lastDelimiter*/l="";
				}
			}
			
			if(/*lastOffset*/p</*inputString*/s.length) /*output*/o+=$.removeNonEssentialWhitespaces(/*inputString*/s.substring(/*lastOffset*/p,/*findDelimiters*/f.lastIndex+/*inputString*/s.length+1));
			
			return /*output*/o;
		}catch(e){alert("removeNonLiteralWhitespaces "+e.description);}
	},

	json2html:function(tree){
		try{
			if(typeof(tree)!="object") return document.createTextNode(String(tree));
			
			var node=document.createElement(tree[0]);
			for(var i=1;i<tree.length;i++){
				if(tree[i] instanceof Array) for(var j=0;j<tree[i].length;j++) node.appendChild(arguments.callee(tree[i][j]));
				else for(var j in tree[i]) node.setAttribute(j,String(tree[i][j]));
			}
			
			return node;
		}catch(e){alert("json2html "+e.description);}
	},
	
	xmlToJs:function(xmlDoc){
		try{
			var out;
			//alert(xmlDoc.childNodes[1].childNodes[0].childNodes[5].childNodes[0].nodeName);
			var textProp=(xmlDoc.textContent!=undefined?"textContent":"text");
			if(xmlDoc.nodeName=="#text" || xmlDoc.nodeName=="#cdata-section") return xmlDoc[textProp];
			else if(xmlDoc.childNodes){
				out={};
				for(var i=0;i<xmlDoc.childNodes.length;i++){
					var name=xmlDoc.childNodes[i].nodeName;
					if(name.substr(0,1)=="#") name=textProp;
					if(out[name]==undefined) out[name]=arguments.callee(xmlDoc.childNodes[i]);
					else if(out[name] instanceof Array) out[name].push(arguments.callee(xmlDoc.childNodes[i]));
					else out[name]=[out[name],arguments.callee(xmlDoc.childNodes[i])];
				}
			}
			
			return out;
		}catch(e){alert("xmlToJs "+e.description);}
	},
	
	include:function(){}
}

$.HttpRequest=function(url,targetfnc){
	if(!(this instanceof arguments.callee)) return new arguments.callee(url,targetfnc);
	try{
		this.targetfunc=targetfnc;
		this.http_request = new XMLHttpRequest();
		if(this.http_request.overrideMimeType) this.http_request.overrideMimeType('text/xml');

		this.http_request.onreadystatechange = $.fixScope(this.responseHandler,this);
		this.http_request.open("GET", url);
		this.http_request.send(null);
	}catch(e){alert("HttpRequest "+e.description);}
}

$.HttpRequest.prototype.responseHandler=function(response){
	if ((this.http_request.readyState == 4) && (this.http_request.status == 200 || (this.http_request.status == 0)))
		this.targetfunc(this.http_request);
}