function createNamedElement(doc, type, name) {
   var element = null;
   // Try the IE way; this fails on standards-compliant browsers
   try {
      element = doc.createElement('<'+type+' name="'+name+'">');
   } catch (e) {
   }
   if (!element || element.nodeName != type.toUpperCase()) {
      // Non-IE browser; use canonical method to create named element
      element = doc.createElement(type);
      element.name = name;
   }
   return element;
}

function trim(text) {
    return text.replace(/(^\s*)|(\s*$)/g, '');
}

function countWords(str) {
    var count = 0;
    var treatment = "";
    treatment = str.replace(/\s/g, " ");
    treatment = treatment.split(" ");
    for (var index = 0; index < treatment.length; index = index + 1) {
        if (treatment[index].length > 0) {
            count = count + 1;
        }
    }
    return count;
}

function delimparser(text) {
    var result = [];
    var token = "";
    var j = 0;
    for (var i = 0; i < text.length; i++) {
        var c = text.charAt(i);
        if (c == ';') {
            result.push(token);
            token = "";
        }
        else if (c == '\\') {
            token += text.charAt(++i);
        } else
            token += c;
    }
    return result;
}

function delimmake(array) {
    var s = "";
    for (var i = 0; i < array.length; i++) {
        var si = array[i];
        si = si.replace("\\", "\\\\");
        si = si.replace(";", "\\;");
        s += si + ';';
    }
    return s;
}

function addPageLoadListenerToWindow(fn, wn){
	/* Code for Mozilla-Gecko w3c Standards */
	if(typeof wn.addEventListener != 'undefined'){
		wn.addEventListener('load', fn, false);
	}
	/* Code For compatibility with Opera */
	else if(typeof wn.document.addEventListener != 'undefined'){
		wn.document.addEventListener('load', fn, false);
	}
	/* Code for IE */
	else if(wn.attachEvent('onload') != 'function'){
		wn.attachEvent('onload', fn);
	}
	/* Code for IE 5 Mac */
	else{
		var oldFn = wn.onload;
		if(typeof wn.onload != 'function'){
			wn.onload=fn;
		}
		else{
			wn.onload=function(){
				oldFn();
				fn();
			};
		}
	}
}

function addPageLoadListener(fn){
    addPageLoadListenerToWindow(fn, window);
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function imgHover(obj, img) {
    obj.src = obj.src.substring(0, obj.src.lastIndexOf("_")) + "_hover.gif";
}

function imgNormal(obj, img) {
    obj.src = obj.src.substring(0, obj.src.lastIndexOf("_")) + "_normal.gif";
}

function imgPressed(obj, img) {
    obj.src = obj.src.substring(0, obj.src.lastIndexOf("_")) + "_pressed.gif";
}

var DOM_ELEMENT_NODE = 1;
var DOM_ATTRIBUTE_NODE = 2;
var DOM_TEXT_NODE = 3;
var DOM_CDATA_SECTION_NODE = 4;
var DOM_ENTITY_REFERENCE_NODE = 5;
var DOM_ENTITY_NODE = 6;
var DOM_PROCESSING_INSTRUCTION_NODE = 7;
var DOM_COMMENT_NODE = 8;
var DOM_DOCUMENT_NODE = 9;
var DOM_DOCUMENT_TYPE_NODE = 10;
var DOM_DOCUMENT_FRAGMENT_NODE = 11;
var DOM_NOTATION_NODE = 12;

function xmlParse(xml) {
    if(window.ActiveXObject) {
        var doc = new ActiveXObject("Microsoft.XMLDOM");
        doc.async = "false";
        doc.loadXML(xml);
        return doc;
    }
    else {
        var parser = new DOMParser();
        return parser.parseFromString(xml, "text/xml");
    }
}

function xmlText(doc) {
    if(window.ActiveXObject) {
        return doc.xml;
    }
    else {
        var serializer = new XMLSerializer();
        return serializer.serializeToString(doc);
    }
}

function createXmlDocument() {
    if(window.ActiveXObject) {
        var doc = new ActiveXObject("Microsoft.XMLDOM");
        doc.async = "false";
        return doc;
    }
    else {
        return document.implementation.createDocument("","",null);
    }
}

// Returns the text value if a node; for nodes without children this
// is the nodeValue, for nodes with children this is the concatenation
// of the value of all children.
function xmlValue(node) {
  if (!node) {
    return '';
  }

  var ret = '';
  if (node.nodeType == DOM_TEXT_NODE ||
      node.nodeType == DOM_CDATA_SECTION_NODE ||
      node.nodeType == DOM_ATTRIBUTE_NODE) {
    ret += node.nodeValue;

  } else if (node.nodeType == DOM_ELEMENT_NODE ||
             node.nodeType == DOM_DOCUMENT_NODE ||
             node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
    for (var i = 0; i < node.childNodes.length; ++i) {
      ret += arguments.callee(node.childNodes[i]);
    }
  }
  return ret;
}

function xmlResolveEntities(s) {

  var parts = stringSplit(s, '&');

  var ret = parts[0];
  for (var i = 1; i < parts.length; ++i) {
    var rp = stringSplit(parts[i], ';');
    if (rp.length == 1) {
      // no entity reference: just a & but no ;
      ret += parts[i];
      continue;
    }

    var ch;
    switch (rp[0]) {
      case 'lt':
        ch = '<';
        break;
      case 'gt':
        ch = '>';
        break;
      case 'amp':
        ch = '&';
        break;
      case 'quot':
        ch = '"';
        break;
      case 'apos':
        ch = '\'';
        break;
      case 'nbsp':
        ch = String.fromCharCode(160);
        break;
      default:
        // Cool trick: let the DOM do the entity decoding. We assign
        // the entity text through non-W3C DOM properties and read it
        // through the W3C DOM. W3C DOM access is specified to resolve
        // entities.
        var span = window.document.createElement('span');
        span.innerHTML = '&' + rp[0] + '; ';
        ch = span.childNodes[0].nodeValue.charAt(0);
    }
    ret += ch + rp[1];
    for(var j = 2; j < rp.length; j++) {
        ret += ";" + rp[j];
    }
  }

  return ret;
}

// Split a string s at all occurrences of character c. This is like
// the split() method of the string object, but IE omits empty
// strings, which violates the invariant (s.split(x).join(x) == s).
function stringSplit(s, c) {
  var a = s.indexOf(c);
  if (a == -1) {
    return [ s ];
  }

  var parts = [];
  parts.push(s.substr(0,a));
  while (a != -1) {
    var a1 = s.indexOf(c, a + 1);
    if (a1 != -1) {
      parts.push(s.substr(a + 1, a1 - a - 1));
    } else {
      parts.push(s.substr(a + 1));
    }
    a = a1;
  }

  return parts;
}

function wconfirm(message, yesUrl) {
    if(confirm(message))
        location.href = yesUrl;
}

function gotoProfile(category) {
    var profile = document.getElementById("profile");
    var href = "adminProfile.jsp?category=" + category;
    if(profile)
        href += "&profile.id=" + profile.value;
    window.location.href = href;
}

function showFeedbackForm() {
    var href = "feedbackForm.jsp";
    if(typeof(getFeedbackFormPrefillText) != "undefined") {
        href += "?source-text=" + encodeURIComponent(getFeedbackFormPrefillText());
    }
    window.location.href = href;
}

function isFirefox3() {
    return navigator.userAgent.indexOf("Firefox/3.") != -1;
}

function hasGoodExt(filename) {
    for(var i = 0; i < _fileexts.length; i++) {
        var ext = _fileexts[i];
        if(ext.length <= filename.length && filename.substring(filename.length - ext.length) == ext)
            return true;
    }
    fileTranslator._invalidExtension = true;
    return false;
}

function verifyFilename(filename) {
       if(filename == '')
        return false;
    if(window._fileexts && !hasGoodExt(filename))
        return false;
    if(filename.length < 4)
        return false;
    /**
     * There is the path in the filename
     */
    if (filename.indexOf("\\", 2) != -1
            || filename.indexOf("/") != -1) {
        if(filename.charAt(0) == '/')
            return true;
        if(filename.substring(0, 2) == "\\\\")
            return filename.indexOf("\\", 2) != -1;
        if(filename.charAt(1) != ':')
            return false;
        return filename.charAt(2) == '\\';
    }
    /**
     * No path in filename, we directly have the filename
     */
    return true;
}

// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com

var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function encode64(input) {
 var output = "";
 var chr1, chr2, chr3;
 var enc1, enc2, enc3, enc4;
 var i = 0;

 do {
 chr1 = input.charCodeAt(i++);
 chr2 = input.charCodeAt(i++);
 chr3 = input.charCodeAt(i++);

 enc1 = chr1 >> 2;
 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
 enc4 = chr3 & 63;

 if (isNaN(chr2)) {
 enc3 = enc4 = 64;
 } else if (isNaN(chr3)) {
 enc4 = 64;
 }

 output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
 keyStr.charAt(enc3) + keyStr.charAt(enc4);
 } while (i < input.length);

 return output;
}

function decode64(input) {
 var output = "";
 var chr1, chr2, chr3;
 var enc1, enc2, enc3, enc4;
 var i = 0;

 // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

 do {
 enc1 = keyStr.indexOf(input.charAt(i++));
 enc2 = keyStr.indexOf(input.charAt(i++));
 enc3 = keyStr.indexOf(input.charAt(i++));
 enc4 = keyStr.indexOf(input.charAt(i++));

 chr1 = (enc1 << 2) | (enc2 >> 4);
 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
 chr3 = ((enc3 & 3) << 6) | enc4;

 output = output + String.fromCharCode(chr1);

 if (enc3 != 64) {
 output = output + String.fromCharCode(chr2);
 }
 if (enc4 != 64) {
 output = output + String.fromCharCode(chr3);
 }
 } while (i < input.length);

 return output;
}
