﻿/*
JavaScript file for the implementation of the NetSupport knowledgebase in a web page, for 
API and usage information see the associated readme.htm file.

Please report any problems with this code to webtools@netsupportsoftware.com

Please feel free to modify this code, however any if you make any improvements or bug fixes,
please email these to webtools@netsupportsoftware.com so that the original can be updated

Author:NetSupport Webtools
Email: Webtools@netsupportsoftware.com
Last Update: 14-8-2008
Version 1.0
*/

var ros=null;
var rprod=null;
var rs=null;
var nslkbsearch=null;

function GetStr(id,def){
    if (typeof(transtr)=='object'){
        if (transtr.length-1<id)
            return def;
        else
            return transtr[id];
    }
    else
        return def;

}


function NetSupportKB(targetElement,spath,providertype){
    nslkbsearch=this;
    this.oem=null;
    this.substitutions=new Array()
    this.OSSelectionClass='';
	this.targetElement=targetElement;
	this.debug=0;
	this.debugdiv=null;
	this.name='nslbk';
	this.OSBox=null;
	this.ProdBox=null;
    this.VerBox=null;
    this.QueryBox=null;
    this.MatchBox=null;
    this.ulclass='';
    this.liclass='';
    this.idspanclass='';
    this.titlespanclass='';
    this.resultdiv=null;
    this.lang='EN';
    this.path=addurlpaths(getDocPath(),'nslkb/');
    if (arguments.length>1){
        if (spath.indexOf('://')>0)
            this.path=spath;
        else
            this.path=addurlpaths(getDocPath(),spath);
    }
    
    this.xsl=this.path+'TechDoc.xsl';
    this.waitimgsrc=addurlpaths(this.path,'wait30.gif');
    this.workingurl=addurlpaths(this.path,'dotNet/c/kbprovider.aspx');
    if (arguments.length>2){
        providertype=providertype.toLowerCase();
        switch(providertype)
        {
            case 'php':
               this.workingurl=addurlpaths(this.path,'php/kbprovider.php');
               break;
            case 'asp':
               this.workingurl=addurlpaths(this.path,'asp/kbprovider.asp');
               break; 
            case 'net':
               this.workingurl=addurlpaths(this.path,'dotNet/c/kbprovider.aspx');
               break;  
            case 'netvb':
               this.workingurl=addurlpaths(this.path,'dotNet/vb/kbprovider.aspx');
               break;    
            case 'netc':
               this.workingurl=addurlpaths(this.path,'dotNet/c/kbprovider.aspx');
               break;                            
            default:
               this.workingurl=addurlpaths(this.path,'dotNet/c/kbprovider.aspx');
                                
        
        }
    }
}

NetSupportKB.prototype.displaySearch=displaySearchnslkb;
NetSupportKB.prototype.writeLog=writeLognslkb;
NetSupportKB.prototype.mostViewed=mostViewednslkb;
NetSupportKB.prototype.drawOS=drawOSnslkb;
NetSupportKB.prototype.drawProducts=drawProductsnslkb;
NetSupportKB.prototype.drawMatch=drawMatchnslkb;
NetSupportKB.prototype.drawSearchText=drawSearchTextnslkb;
NetSupportKB.prototype.search=searchnslkb;
NetSupportKB.prototype.addsubstitution=addsubstitutionnslkb;

function addsubstitutionnslkb(oldtext,newtext){
    this.substitutions[this.substitutions.length]=new Array(oldtext,newtext);
}

function addurlpaths(p1,p2){
    if (p2.charAt(0)=='/')
        return p2; 
        
    if (p1.indexOf('../')==-1 && p2.indexOf('../')==-1)
        return p1+p2;
  
          
    var ret=p1+p2;
    var pi=ret.split("/");
    ret='';
    for (i=0;i<pi.length;i++){
        if(i+1<pi.length){
            if (pi[i+1]!='..'){
                ret=ret+pi[i]+'/';
                
                }
                else
                i++;
        }
        else
        if(pi[i]!='' || ret.substring(ret.length-2,ret.length)==':/')
            ret=ret+pi[i]+'/';

    }

    return ret;
}
function getDocPath(){
   var s=document.location.href;
   s=s.substring(0,s.lastIndexOf("/"));
   return s+"/";
}


function searchnslkb(){

    url=nslkbsearch.workingurl+'?results=1';
    if (nslkbsearch.ProdBox==null)
        url=url+'&product=any';
    else
        url=url+'&product='+escape(nslkbsearch.ProdBox.value);
    if (nslkbsearch.VerBox==null)
        url=url+'&ProductVer=any';
    else
        url=url+'&ProductVer='+escape(nslkbsearch.VerBox.value);
    
    if (nslkbsearch.OSBox==null)
        url=url+'&OSSelection=any';
    else
        url=url+'&OSSelection='+escape(nslkbsearch.OSBox.value);
    
    if (nslkbsearch.MatchBox==null)
        url=url+'&Match=exact';
    else
        url=url+'&Match='+escape(nslkbsearch.MatchBox.value);
        
    if (nslkbsearch.QueryBox==null)
        url=url+'&query=';
    else        
        url=url+'&query='+escape(nslkbsearch.QueryBox.value);
    
    for (i=0;i<nslkbsearch.substitutions.length;i++){
        url=url+'&SUB'+i+'='+escape(nslkbsearch.substitutions[i][0]+';'+nslkbsearch.substitutions[i][1]);
    
    }
    if (nslkbsearch.oem!=null){
        url=url+'&productset='+escape(nslkbsearch.oem);
    }
    
    nslkbsearch.writeLog(url);
    rs=new Request('searchReq');
    rs.url=url;
    var rsbox=nslkbsearch.resultdiv;
    if (nslkbsearch.resultdiv==null)
        rsbox=nslkbsearch.name+"results";
    if (!document.getElementById(rsbox))
    {
        var t=document.createElement('div');
        t.id=rsbox;
        document.body.appendChild(t);    
    }
    
    document.getElementById(rsbox).innerHTML='<div style="text-align:center"><img style="vertical-align:middle" src="'+nslkbsearch.waitimgsrc+'" alt="'+GetStr(0,'Please Wait')+'" border="0" />&nbsp;'+GetStr(0,'Please Wait')+'..</div>';
    
    rs.oncomplete="displayresults('"+rsbox+"','"+nslkbsearch.ulclass+"','"+nslkbsearch.liclass+"','"+nslkbsearch.idspanclass+"','"+nslkbsearch.titlespanclass+"')";
    rs.send();



}
function nsltd(tdid)
{

    if (typeof(displaytd)=='function')
    {
        displaytd(tdid);
        return;
    
    }

    url=nslkbsearch.workingurl+'?gettd='+tdid+"&lang="+nslkbsearch.lang+'&xsl='+escape(nslkbsearch.xsl);
    
    for (i=0;i<nslkbsearch.substitutions.length;i++){
        url=url+'&SUB'+i+'='+escape(nslkbsearch.substitutions[i][0]+';'+nslkbsearch.substitutions[i][1]);
    
    }
    if (nslkbsearch.oem!=null){
        url=url+'&productset='+escape(nslkbsearch.oem);
    }
    
    nslkbsearch.writeLog(url);
    var tdw=window.open (url);
}

function displayresults(ta,c1,c2,c3,c4){
   if (document.getElementById(ta))
        var t=document.getElementById(ta);
    else
    {
        var t=document.createElement('div');
        t.id=ta;
        document.body.appendChild(t);
    }   
    t.innerHTML='';
    var results=rs.responseXML.getElementsByTagName('techdoc');
    var countdiv=document.createElement('div');
    countdiv.id=nslkbsearch.name+'listheader';
    countdiv.innerHTML=results.length+GetStr(1,' Technical Documents Found');
    t.appendChild(countdiv);
    var ul=document.createElement('ul');
    ul.className=c1;
    t.appendChild(ul);
    for (i=0;i<results.length;i++){
        var li=document.createElement('li');
        li.className=c2;
        ul.appendChild(li);
        var a=document.createElement('a');
        a.href='javascript:nsltd('+results[i].getAttribute('id')+')';
        li.appendChild(a);
        var idspan=document.createElement('span');
        idspan.innerHTML='TD'+results[i].getAttribute('id');
        idspan.id='tdid'+results[i].getAttribute('id');
        idspan.className=c3;
        a.appendChild(idspan);
        var sp=document.createTextNode(" ");
        a.appendChild(sp);
        var tspan=document.createElement('span');
        if(tspan.innerHTML=results[i].text)
            tspan.innerHTML=results[i].text;
        else
            tspan.innerHTML=results[i].textContent;
        tspan.id='tdtitle'+results[i].getAttribute('id');
        tspan.className=c3;
        a.appendChild(tspan);
    }
}




function ClearSel(SelObj){
var x=SelObj.options.length;
for (i=0;i<x;i++){
	SelObj.options[0]=null;
	}
}
function changeProd(evt){
    var e_out;
	var ie_var = "srcElement";
	var moz_var = "target";
	var prop_var = "value";
	// "target" for Mozilla, Netscape, Firefox et al. ; "srcElement" for IE
	evt[moz_var] ? e_out = evt[moz_var][prop_var] : e_out = evt[ie_var][prop_var];
	var selectedProd=e_out;
	prop_var = "id";
	evt[moz_var] ? e_out = evt[moz_var][prop_var] : e_out = evt[ie_var][prop_var];

    var verBox=document.getElementById(e_out+'Ver');
    ClearSel(verBox);
    verBox.options[verBox.options.length]=new Option(GetStr(6,'Any Version'),'Any');    
    var proditems=rprod.responseXML.getElementsByTagName('product');
    for (i=0;i<proditems.length;i++)
    {
        if (proditems[i].getAttribute('name')==selectedProd)
        {
           for (j=0; j<proditems[i].childNodes.length;j++)
           {
           if (proditems[i].childNodes[j].nodeName=='pver')
            verBox.options[verBox.options.length]=new Option(proditems[i].childNodes[j].getAttribute('version'),proditems[i].childNodes[j].getAttribute('id'));
           }
        }
    }    
}

function drawSearchTextnslkb(TargetElement,size)
{
    if (this.QueryBox==null){
       this.QueryBox=document.createElement('input');
        this.QueryBox.id=this.name+'query';
        this.QueryBox.type='text';
         if (!isNaN(size)){
            this.QueryBox.size=size;
        }
        if (window.ActiveXObject)
            this.QueryBox.onkeypress=sbkp;
        else
            this.QueryBox.onkeypress='sbkp(event)';
    }
    else
        document.getElementById(this.name+'query').value='';
    if (document.getElementById(TargetElement)){
        document.getElementById(TargetElement).appendChild(this.QueryBox);
        }
    else
        {
        document.body.appendChild(this.QueryBox);
        }  
    return this.QueryBox;
        
}

function sbkp(evnt){if (document.all){keyCode=window.event.keyCode;}else{keyCode=window.evnt.which;} if (keyCode==13){nslkbsearch.search();return false;}}


function drawMatchnslkb(TargetElement)
{
    if (this.MatchBox==null){
        this.MatchBox=document.createElement('select');
        this.MatchBox.id=this.name+'Match';
        this.MatchBox.className=this.MatchSelectionClass;
    }
    else
        ClearSel(this.MatchBox);
    this.MatchBox.options[this.MatchBox.options.length]=new Option(GetStr(2,'Exact Phrase'),'exact');
    this.MatchBox.options[this.MatchBox.options.length]=new Option(GetStr(3,'Any Word'),'any');
    this.MatchBox.options[this.MatchBox.options.length]=new Option(GetStr(4,'All Words'),'all');
    if (document.getElementById(TargetElement)){
        document.getElementById(TargetElement).appendChild(this.MatchBox);
        }
    else
        {
        document.body.appendChild(this.MatchBox);
        }
    return this.MatchBox;
}

function testevent(evt){
	var e_out;
	var ie_var = "srcElement";
	var moz_var = "target";
	var prop_var = "value";
	// "target" for Mozilla, Netscape, Firefox et al. ; "srcElement" for IE
	evt[moz_var] ? e_out = evt[moz_var][prop_var] : e_out = evt[ie_var][prop_var];
	alert(e_out);
	prop_var = "id";
	evt[moz_var] ? e_out = evt[moz_var][prop_var] : e_out = evt[ie_var][prop_var];
	alert(e_out);
}

function drawProductsnslkb(TargetElement)
{
    if (this.ProdBox==null){
        this.ProdBox=document.createElement('select');
        this.ProdBox.id=this.name+'Product';

if (this.ProdBox.addEventListener){
  this.ProdBox.addEventListener('change', changeProd, false); 
} else if (this.ProdBox.attachEvent){
  this.ProdBox.attachEvent('onchange', changeProd);
}        

    }
    else
        ClearSel(this.ProdBox);

    this.ProdBox.options[this.ProdBox.options.length]=new Option(GetStr(5,'Any Product'),'Any');
    
    if (this.VerBox==null){
        this.VerBox=document.createElement('select');
        this.VerBox.id=this.name+'ProductVer';
        }
    else
        ClearSel(this.VerBox);    
        
    this.VerBox.options[this.VerBox.options.length]=new Option(GetStr(6,'Any Version'),'Any');
    
    
    if (document.getElementById(TargetElement))
    {
        document.getElementById(TargetElement).appendChild(this.ProdBox);
        document.getElementById(TargetElement).appendChild(this.VerBox);
        }
    else
    {
        document.body.appendChild(this.ProdBox);
        document.body.appendChild(this.VerBox);
        }
    
    rprod=new Request('prodreq');
    var url=this.workingurl+'?getProd=1';
    for (i=0;i<nslkbsearch.substitutions.length;i++){
        url=url+'&SUB'+i+'='+escape(nslkbsearch.substitutions[i][0]+';'+nslkbsearch.substitutions[i][1]);
    
    }
    if (this.oem!=null){
        url=url+'&productset='+escape(this.oem);
    }
    nslkbsearch.writeLog(url);
    rprod.url=url;
    rprod.oncomplete='popProd(\''+this.name+'Product'+'\')';
    rprod.send();
    
    return this.ProdBox
}

function popProd(el){
    var proditems=rprod.responseXML.getElementsByTagName('product');
    var ProdBox=document.getElementById(el);
    for (i=0;i<proditems.length;i++)
    {
        
        ProdBox.options[ProdBox.options.length]=new Option(proditems[i].getAttribute('description'),proditems[i].getAttribute('name'));
    }
}

function drawOSnslkb(TargetElement){
    if (this.OSBox==null){
        this.OSBox=document.createElement('select');
        this.OSBox.id=this.name+'OSSelection';
    }
    else
        ClearSel(this.OSBox);
        
    this.OSBox.options[this.OSBox.options.length]=new Option(GetStr(7,'Any'),'Any');
    
    
    if (document.getElementById(TargetElement))
        document.getElementById(TargetElement).appendChild(this.OSBox);
    else
        document.body.appendChild(this.OSBox);
    
    ros=new Request('osreq');
    ros.url=this.workingurl+'?getos=1';
    nslkbsearch.writeLog(ros.url);
    ros.oncomplete='popos(\''+this.name+'OSSelection'+'\')';
    ros.send();
    
    return this.OSBox;
}

function popos(el){
    var ositems=ros.responseXML.getElementsByTagName('os');
    var osbox=document.getElementById(el);
    for (i=0;i<ositems.length;i++)
    {
        
        osbox.options[osbox.options.length]=new Option(ositems[i].text || ositems[i].textContent,ositems[i].getAttribute('id'));

    }
}

function displaySearchnslkb(targetElement)
{
    this.targetElement=targetElement;
    //create a table to hold the fields
    var tb=document.createElement('table');
    tb.id=this.name+'t';
    var rd=document.createElement("div");
    rd.id=this.name+"results";
    
    if (document.getElementById(targetElement)){
        document.getElementById(targetElement).appendChild(tb);
        document.getElementById(targetElement).appendChild(rd);
        }
    else
    {
        document.body.appendChild(tb);
        document.body.appendChild(rd);
    }
    var t=document.createElement('tbody');
    tb.appendChild(t);
    var r=document.createElement('tr');
    t.appendChild(r);
    var td=document.createElement('td');
    td.innerHTML= GetStr(8,'My Search is about:');
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.id=this.name+'ProdSelect';
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.innerHTML=GetStr(9,'Using this Operating System');
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);   
    td=document.createElement('td');
    td.id=this.name+'OSSelect';
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.innerHTML=GetStr(10,'Find documents that match');
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.id=this.name+'MatchSelect';
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.innerHTML=GetStr(11,'I want to search for');
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.id=this.name+'searchText';
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    td.innerHTML=GetStr(12,'If you know the Document Number You can enter it here');
    r.appendChild(td);
    r=document.createElement('tr');
    t.appendChild(r);
    td=document.createElement('td');
    r.appendChild(td);
    var sb=document.createElement('input');
    sb.value=GetStr(13,'Search');
    sb.type="button";
    sb.onclick=nslkbsearch.search;
    td.appendChild(sb);
    this.drawProducts(this.name+"ProdSelect");
    this.drawOS(this.name+'OSSelect');
    this.drawMatch(this.name+"MatchSelect")
    this.drawSearchText(this.name+"searchText",70)


            
}

function writeLognslkb(msg)
{
if (this.debug==0){
    return ;
}

   if(document.getElementById('nslkbdebug'))
        this.debugdiv=document.getElementById('nslkbdebug');
   else
    {
        this.debugdiv=CreateDebugDiv();
    }

    if(document.getElementById('nslkbdebug')){
        var msgd=document.createElement('div');
        var uid=new Date();
        msgd.innerHTML='<b>'+uid+'</b>&nbsp;'+msg;
        this.debugdiv.appendChild(msgd);
    }
}

function CreateDebugDiv(){
    var debugdiv=document.createElement('div');
    debugdiv.id='nslkbdebug';
    debugdiv.style.height='200px';
    debugdiv.style.width='100%';
    debugdiv.style.overflow='auto';
    document.body.appendChild(debugdiv);
    return debugdiv
}

function mostViewednslkb(targetelement, ntop)
{

}    
    




var activeRequests=new Array();
function Request(ReqName){
	this.active=false;
	this.url='';
	this.Trim=true;
	this.response='';
	this.responseXML=null;
	this.debug=false;
	this.req=null;
	this.name=ReqName;
	this.oncomplete=null;
	this.XMLErrorCount=0;
	this.MaxError=10;
	this.XMLEnabled=CheckXML();
	this.requestindex=activeRequests.length ;
	activeRequests[activeRequests.length]=this;
}


Request.prototype.send=SendRequest;
Request.prototype.writeLog=writeLog;
Request.prototype.isActive=function (){return this.active};
Request.prototype.resetErrCount=function (){XMLErrorCount=0};
Request.prototype.sendUsingIframe=sendUsingIframe;

function writeLog(Msg){
	if(!this.debug)
		return;
	if(!document.getElementById("ReqDebug"))
		CreateDebug();
	document.getElementById("ReqDebug").value+='\n'+this.name+":"+Msg;
}
function CreateDebug(){
	var DebugText=document.createElement("textarea");
	DebugText.id="ReqDebug";
	DebugText.style.width="100%";
	DebugText.style.height="300px";
	document.body.appendChild(DebugText);
}


function SendRequest() 
{
	if (arguments.length>0)
		this.url=arguments[0];
	
	if (this.url=='')
		return false;
	
	if (this.active)
		return false;
		
	if (!this.XMLEnabled){
		this.sendUsingIframe(this.url);
		return true;
		
	}
		
    
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        this.req = new XMLHttpRequest();
        this.writeLog("getting url:"+this.url);
        this.req.onreadystatechange = ProcessRequests;       
        this.req.open('GET', this.url, true);
        this.active=true;
        this.req.send(null);
        //branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
		this.req = new ActiveXObject("Microsoft.XMLHTTP");
		this.req.onreadystatechange = ProcessRequests;        
        if (this.req) {
			this.writeLog("getting url:"+this.url);
            this.req.open("GET", this.url, true);
            this.active=true;
            this.req.send();
        }
    }
    return true;
}

function ProcessRequests(){
	for (j=0;j<activeRequests.length;j++){
		if(activeRequests[j].req!=null){
			if (activeRequests[j].req.readyState){
				if (activeRequests[j].req.readyState == 4  ) {
					activeRequests[j].writeLog("Document Processed");
				    // only if "OK"
				    if (activeRequests[j].req.status == 200) {
						activeRequests[j].writeLog("Document OK");
						activeRequests[j].XMLErrorCount=0;
						activeRequests[j].responseXML=activeRequests[j].req.responseXML;
				        activeRequests[j].response=activeRequests[j].req.responseText;
				        if (activeRequests[j].Trim){
				            re = /<(.*)INFO\"/;
				            activeRequests[j].response=trim(activeRequests[j].response.replace(re,''));
				            re = /-->/;
				            activeRequests[j].response=activeRequests[j].response.replace(re,'');
				        }
				        activeRequests[j].writeLog("Response:\n"+activeRequests[j].response);
							
				    } else {
						activeRequests[j].XMLErrorCount++;
				        if (activeRequests[j].XMLErrorCount>activeRequests[j].MaxError){
							alert("There was a problem retrieving the data");
				        }
				    }

						
						activeRequests[j].req=null;
						activeRequests[j].active=false;
						if (activeRequests[j].oncomplete!=null)
							//activeRequests[j].oncomplete
							window.setTimeout(activeRequests[j].oncomplete,2);

				}			
			}
		}
	}
}


function trim(str)
{
   return str.replace(/^\s*|\s*$/g,"");
}
function CheckXML(){
	if (window.XMLHttpRequest) {
		return true; 
     //branch for IE/Windows ActiveX version
    }
    else if (window.ActiveXObject) {
		return true;
    }
    
    return false;

}

function sendUsingIframe(url){
	this.writeLog("Send Using Iframe");
	if (url.indexOf("?")>0)
	url+="&CallBack=requestCallback("+this.requestindex+",document.body.innerHTML)";
	this.writeLog("Send using URL:" +url);
	
	this.active=true;
	CreateIFrame("iframeRequest_"+ this.name,url,200,200);
	this.writeLog("Iframe Created Waiting for a Response");
}
function requestCallback(requestIdx,Response){

	if (activeRequests[requestIdx]){
		activeRequests[requestIdx].writeLog("Iframe Response");
		activeRequests[requestIdx].response=Response;
		activeRequests[requestIdx].writeLog("Response:\n"+Response);
		activeRequests[requestIdx].active=false;
		if (activeRequests[requestIdx].oncomplete!=null)
			//activeRequests[requestIdx].oncomplete
			window.setTimeout(activeRequests[requestIdx].oncomplete,50);
		
	}

}



function CreateIFrame(id,url){

	var Framewidth=0;
	var Frameheight=0;
	
	if (arguments.length>2){
		Framewidth=arguments[2];
	}
	if (arguments.length>3){
		Frameheight=arguments[3];
	}
	
	if(!window.frames[id]){
	try{
			var iFrame = document.createElement("iframe");
			iFrame.setAttribute('id',id);
			iFrame.setAttribute('name',id);
			iFrame.style.width = Framewidth+"px";
			iFrame.style.height = Frameheight+"px";
			iFrame.src = url;
			createdframe = document.body.appendChild(iFrame);
			
			if (document.frames) {
				createdframe = document.frames[id];
			}
			
		}catch(e){
			var iframeHTML = '\<iframe id="' + id + '"';
			iframeHTML += ' style="border:0px; width:'+Framewidth+'px; height:'+Frameheight+'px;';
			iframeHTML += '"><\/iframe>';
			document.body.innerHTML += iframeHTML;
			iframe = new Object();
			iframe.document = new Object();
			iframe.document.location = new Object();
			iframe.document.location.createdframe = 
			document.getElementById(id);
			iframe.document.location.replace = 
			function(location) {
				this.iframe.src = location;
			}
		}	
	
	}
	else
	{
		window.frames[id].location.href=url;
	}
}

function addEvent(obj, evType, fn) {
    if (obj.addEventListener) {
        obj.addEventListener(evType, fn, false);
        return true;
    } else if (obj.attachEvent) {
        var r = obj.attachEvent("on" + evType, fn);
        return r;
    } else {
        return false;
    }
}
function removeEvent(obj, evType, fn, useCapture) {
    if (obj.removeEventListener) {
        obj.removeEventListener(evType, fn, useCapture);
        return true;
    } else if (obj.detachEvent) {
        var r = obj.detachEvent("on" + evType, fn);
        return r;
    } else {
        alert("Handler could not be removed");
    }
}