// Copyright 2002,2005 Leslie Brown, Evidian 
// Copy 5 fixes index pages
// Copy 7 allows initally expanded items in left menus
// Copy 8: setuprolls also activates new-style minisearch
// Copy 9: retrofitted workaround for IE <A>pathname bug
// Copy 11: added workaround for IE not handling substr(-8)
// Copy 12: current pages have collapsible submenus
// Copy 13: rationalize
// Copy 14: set search button
// Copy 15: fixed search "and" parameter
// Copy 16: fixed contact us menu and subscribe menu
// Copy 17: mailme
// Oct 23 2007: use GSA-based search
// Padding

var toNext=""; // Legacy
var toPrev=""; // Legacy
var j=0;

// Mini-utilities
function rTrim(s)  { return s.replace(/\s+$/,"")}
function lTrim(s)  { return s.replace(/^\s+/,"")}
function bTrim(s)  { return s.replace(/\s+$|^\s+/g,"")}   // Replaces EV_Trim
function ns4resizekludge(){if((innerWidth!=document.ns4wide)||(innerHeight!=document.ns4high))location.reload();}
function toggledisplay(elid) { 
  el = document.getElementById(elid);
  if(el.style.display == "block") {
    el.style.display = "none";
  } else{
    el.style.display = "block";
  }
}

function jump(selObj){  // Replaces jumpMenu
  window.location=selObj.options[selObj.selectedIndex].value;
  return false;
}

function replay(elid) { // Reruns an animation
  el = document.getElementById(elid);
  el.src = el.src;
}

function mailMe (){
 var winSpecs='width=408,height=408';
 winSpecs +=',screenX=80,screenY=80,toolbar=no,location=no,directories=no,'
 winSpecs +='status=no,menubar=no,scrollbars=no,copyhistory=yes,resizable=yes';
 window.open ("/util/pagerec.htm", "mailMe", winSpecs);
}
function printMe(){ window.print(); }

function iwin(myUrl, myId, myW, myH){  // Opens a pop-up window
  // All it does is open a pop-up window called myId that the post can use as a target
  var winSpecs = 'width='+myW+',height='+myH+',screenX=100,screenY=80,'
               + 'toolbar=yes,location=yes,directories=yes,'
               + 'status=yes,menubar=yes,scrollbars=yes,'
               + 'copyhistory=yes,resizable=yes';
  win=window.open (myUrl, myId, winSpecs) ;
  if(win) win.focus();
  return true;
}

/* Cookie functions */
function setCookie(name, value, expires, path, domain, secure){
 var curCookie=name + "=" + escape(value) + 
 ((expires) ? "; expires=" + expires.toGMTString() : "") +
 ((path) ? "; path=" + path : "") +
 ((domain) ? "; domain=" + domain : "") +
 ((secure) ? "; secure" : "");
 document.cookie=curCookie;
}
function getCookie(name){
 var dc=document.cookie;
 var prefix=name + "=";
 var begin=dc.indexOf("; " + prefix);
 if (begin==-1){
  begin=dc.indexOf(prefix);
  if (begin !=0) return null;
 } else {
  begin +=2;
 }
 var end=document.cookie.indexOf(";", begin);
 if (end==-1) end=dc.length;
 return unescape(dc.substring(begin + prefix.length, end));
}
function deleteCookie(name, path, domain){
 if (getCookie(name)){
  document.cookie=name + "=" 
  + ((path) ? "; path=" + path : "")
  + ((domain) ? "; domain=" + domain : "")
  + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
 }
}
// Set up cookies for backtracking
  var now = new Date();
  now.setTime(now.getTime() + 90 * 24 * 60 * 60 * 1000);
  var cameto = getCookie("cameto");
  var camefrom = getCookie("camefrom");
  var firstcame = getCookie("firstcame");
  var firstref = getCookie("firstref");
  if (!cameto) {
    camefrom = ((!document.referrer)||(document.referrer=="")) ? "Not supplied" : document.referrer ; 
    cameto = location.href; 
    setCookie("camefrom", camefrom, null, "/") ;
    setCookie("cameto", cameto, null, "/") ;
    if (!firstcame) {
      setCookie("firstcame", cameto, now, "/");
    } else {  // Extend for 3 months
      setCookie("firstcame", firstcame, now, "/") ;
    } 
    if (!firstref) {
      setCookie("firstref", camefrom, now, "/");
    } else {  // Extend for 3 months
      setCookie("firstref", firstref, now, "/") ;
    }
  }

/* Overall control */
var mc         ; // Define menu controller item but don't set it yet

function initrsm(){ 
  pageloc=document.location.pathname; // Set canonical address of this page
  if(pageloc.charAt(0) != "/") { // i.e. same problem as IE for href pathnames
    pageloc = "/" + pageloc; // covers php and htm
  }
  if(pageloc.charAt(pageloc.length-1) == "/") { // i.e. it's a folder
    pageloc += "index."; // covers php and htm
  }
  // setUpOverlays(); Set up main menu overlays
  setUpYertiz();   // Mark current page in contextual menu and add previous/next pointers where appropriate
  setUpRolls();    // Set up rollovers in top and trailer menus
}

/* Menu 0 functions */
function startSearch(evt){  // Launches search on return in mini search box
  if(window.event) {
    evt = window.event;
  } else if(evt) {
    tgt = evt.target;
  } else return;
  if(evt.keyCode) {
    var keycode = evt.keyCode;
  } else if(evt.which) {
    var keycode = evt.which;
  } else return;
  if(keycode == 13) {
    this.doSearch();
  } 
}

function startSearchFR(evt){  // Launches search on return in mini search box
  if(window.event) {
    evt = window.event;
  } else if(evt) {
    tgt = evt.target;
  } else return;
  if(evt.keyCode) {
    var keycode = evt.keyCode;
  } else if(evt.which) {
    var keycode = evt.which;
  } else {
		return;
	}
  if(keycode == 13) {
    this.doSearchFR();
  } 
}

function doSearch(){  // Replaces miniSearch
  var mySearch=bTrim(this.value);
  srchString = (mySearch=="") ? "/search/index.php" : "/search/index.php?q=" + escape(mySearch.replace(/\s+/g,"+"));
  window.location.href=srchString;
	return;
}

function doSearchFR(){  // Replaces miniSearch
  var mySearch=bTrim(this.value);
  srchString = (mySearch=="") ? "/fr/search/index.php" : "/fr/search/index.php?q=" + escape(mySearch.replace(/\s+/g,"+"));
  window.location.href=srchString;
}

function miniSearch(){
  document.getElementById("m0search").doSearch();
  return false;
}

/* Rollover functions */
function rollOn() { this.src = this.ovrsrc; }
function rollOff(){ this.src = this.orgsrc; }
function setUpRoll(el) {
	if(el.src.lastIndexOf("-n.") != el.src.length - 6) return false;
  var temp       = el.src.replace(/\-n\.(gif|png|jpg)/, "-y.$1"); // Set rollover image
  if(temp == el.src) return false; // No roll if image is already "active"
	el.orgsrc      = el.src;  // Remember original image
	el.ovrsrc      = temp;  // Remember original image
	el.onmouseover = rollOn;
	el.onmouseout  = rollOff;
  return true;
}

function miniSrch(){
	// alert("Run minisearch");
  document.getElementById("searchform").submit();
  return false;
}

function primeSearchbox(){
	// On first keypress in a searchbox, clear the "search" value and activate the text link to send the form
	// alert("Key pressed");
	if(this.className == "used") return true;
	this.value = "";
  document.getElementById("minisearch").onclick = miniSrch;
	this.className = "used";
  return true;
}

function setUpRolls() { // Sets rollovers for the images in the top menu 
  var el;
// Set up rollovers on all images marked as rollovers (filename ends in -n)
  var els = document.getElementsByTagName("IMG"); // Main menu links
  for (var i=0; i<els.length; i++){ setUpRoll(els[i]); }  
	// Set up rollovers on offer boxes 
	var offerbox;
	if( offerbox = document.getElementById("offers") ) { // Only present on home pages
	  document.getElementById("boxsso").onmouseover = iamOn;
	  document.getElementById("boxsso").onmouseout  = iamOff;
	  document.getElementById("boxidm").onmouseover = iamOn;
	  document.getElementById("boxidm").onmouseout  = iamOff;
	  document.getElementById("boxrm").onmouseover  = iamOn;
	  document.getElementById("boxrm").onmouseout   = iamOff;
	  document.getElementById("boxom").onmouseover  = oskOn;
	  document.getElementById("boxom").onmouseout   = oskOff;
	  document.getElementById("boxsk").onmouseover  = oskOn;
	  document.getElementById("boxsk").onmouseout   = oskOff;
	}
	setupactiveboxes();
	setupdropmenus();
	

  if(document.getElementById("sbox") ) document.getElementById("sbox").onkeydown  = primeSearchbox; // Trigger search on entry

  if(document.getElementById("m0search") ) { // Legacy
    document.getElementById("m0search").onkeyup  = startSearch; // Trigger search on entry
    document.getElementById("m0search").doSearch = doSearch;    // Perform search
    if(document.getElementById("minisearch") ) { 
      document.getElementById("minisearch").onclick  = miniSearch; // Trigger search on entry
    }
  }
  if(document.getElementById("m0searchFR") ) { // Legacy
    document.getElementById("m0searchFR").onkeyup  = startSearchFR; // Trigger search on entry
    document.getElementById("m0searchFR").doSearchFR = doSearchFR;    // Perform search
    if(document.getElementById("minisearchFR") ) { 
      document.getElementById("minisearchFR").onclick  = miniSearchFR; // Trigger search on entry
    }
  }
  if(document.getElementById("trailer") ) { // Legacy 
    var els = document.getElementById("trailer").getElementsByTagName("IMG"); // Main menu links
    if (els) for (var i=0; i<els.length; i++){ setUpRoll(els[i]); } 
  }
}

/* Collapsible menu functions */
function lsflip(evt){
  if(window.event) {
    evt = window.event;
    tgt = evt.srcElement;
  } else if(evt) {
    tgt = evt.target;
  } else return;
  if (tgt.src == tgt.orgsrc) {
    tgt.src = tgt.ovrsrc;
    tgt.kid.style.display = "block";
  } else {
    tgt.src = tgt.orgsrc;
    tgt.kid.style.display = "none";
  }
  if(window.event)       { 
    window.event.cancelBubble = true; 
  } else if (evt.target) { 
    evt.stopPropagation();
  }
  return false;
}
  
function setUpYertiz() {
  if(document.getElementById("lsmenu")) {
    var lsmenu = document.getElementById("lsmenu");
  } else {
    return false ;
  }
  presetYertiz = document.getElementById("yerTiz");
  var uls = lsmenu.getElementsByTagName("UL");
  var lis = lsmenu.getElementsByTagName("LI");
  var myLi, myLoc, myDad, myPrev, myPic, bingo;
  var currentpagedone = 0;
  for (var i=0; i<uls.length; i++){
    uls[i].dad = uls[i].parentNode;
    uls[i].dad.kid = uls[i];
  }
  for (var i=0; i<lis.length; i++){
    myLi = lis[i];
    if(myLi.firstChild.tagName == "A") {
      myLi.lnk = myLi.firstChild;
      if(myLi.lnk.firstChild.tagName == "IMG") {
        myLi.pic = myLi.lnk.firstChild;
      }
    } else if (myLi.firstChild.tagName == "IMG") {
      myLi.pic = myLi.firstChild;
    }
    if(myLi.pic) myPic = myLi.pic.src.substr(myLi.pic.src.length - 8);

    if(myLi.lnk) {
      if(currentpagedone == 0) {
        bingo = false;
        if (presetYertiz) {
          bingo = (myLi == presetYertiz);
        } else {
          myLoc = myLi.lnk.pathname;
          if(myLoc.charAt(0) != "/") { // i.e. same problem as IE for href pathnames
            myLoc = "/" + myLoc; // covers php and htm
          }
          bingo = (myLoc.indexOf(pageloc) == 0);
        }
        if(bingo) {
          myPic = "here.gif";
          myLi.pic.src = myLi.pic.src.substr(0, myLi.pic.src.length - 8) + myPic;
          myLi.lnk.className = "currentpage";
          myDad = myLi.parentNode;
          while(myDad.tagName != "DIV") { 
            if(myDad.tagName == "UL") myDad.style.display = "block";
            // if(myDad.tagName == "LI") myDad.pic.src       = myDad.pic.ovrsrc;
            myDad = myDad.parentNode;        
          }
          currentpagedone = 1;
        }
      }
    }
    if((myLi.kid) && (myLi.pic)) {
      myLi.pic.kid = myLi.kid;
      switch (myPic){
        case "more.gif": // Collapsed submenu
          myLi.pic.orgsrc  = myLi.pic.src;
          myLi.pic.ovrsrc  = myLi.pic.src.replace(myPic, "less.gif");
          break;
        case "less.gif": // Expanded submenu
        case "here.gif": // Expanded submenu (current)
          myLi.pic.ovrsrc  = myLi.pic.src;
          myLi.pic.orgsrc  = myLi.pic.src.replace(myPic, "more.gif");
          myLi.kid.style.display="block";
          break;
      }
      myLi.pic.onclick = lsflip;
    }
  }
}

/* Drop-down menu functions */
function setUpOverlays() { // Positions the drop-down menus under the images in the top menu 
  var els = document.getElementById("dtopstuff1").getElementsByTagName("A"); // Main menu links
  var el, baseloff, basetoff;

	// Get the offsets of the first element
	el=els[0].firstChild; // The image inside the first menu link
	basetoff = 1 + parseInt(el.offsetHeight); // Top offset for associated menu (BELOW the image element)
	baseloff = 0; // Left offset for associated menu
	do{
		baseloff += parseInt(el.offsetLeft);
		basetoff += parseInt(el.offsetTop);
		el = el.offsetParent;
	} while( (el.tagName != "BODY") && (el.tagName != "HTML")) ;

	// Now apply the offsets to all the elements
  for (var i=0; i<els.length; i++){
    el = els[i].firstChild;  // Get the image element inside the link
		// Set the offsets
    el.loff   = baseloff; // Left offset for associated menu
    el.toff   = basetoff; 
		// Update the left offsets (Note that the separators should be at the right of the images)
    baseloff += el.offsetWidth; // Add width of image to get offset of next
		// Set the rollover info
		el.orgsrc = el.src;  // Remember original image
		el.ovrsrc = el.src.replace(/\-n\.(gif|png|jpg)/, "-y.$1"); // Set rollover image
		// Set the dropdown menu info
    el.twin   = document.getElementById("o" + el.parentNode.id); // Get the matching overlay menu
    el.twin.style.display  = "none";  // Set twin to the same position
    el.twin.style.position = "absolute";
		// Position the dropdown menus
    el.twin.style.left     = el.loff + "px";
    el.twin.style.top      = el.toff  + "px";
		// Set the rollover handlers
    el.onmouseover         = dodrop;
    el.twin.onmouseover    = flatten;
		// Ensure the positions adjust when the window gets resized
    window.onresize = setUpOverlays ;
  }
}

function flatten(evt){ // Prevent mouseovers on dropdown components from bubbling
  if(window.event) {
    window.event.cancelBubble = true; 
  } else if (evt.target)  {
    evt.stopPropagation();
  }
}

function undrop(){ // Kill a dropdown menu
  if(mc) {
    dedrop(mc);
    document.onmouseover = null;
    mc = null;
  }
}

function dedrop(mc){ // Remove a dropdown menu
  mc.dropper.style.display = "none";   // Undisplay the dropdown
  mc.trigger.src = mc.trigger.orgsrc;  // Restore the original image
  mc.trigger.onmouseover = dodrop;     // Restore default rollover behaviour
}

function dodrop(evt){ // Event handler for a top-level menu image whose dropdown menu isn't activated
  if(window.event) {  // IE event model
    evt = window.event;
    tgt = evt.srcElement;
  } else if(evt) {   // DOM event model
    tgt = evt.target;
  } else return;     // Unknown event model... give up now, before creating any garbage we can't get rid of
  if(mc) dedrop(mc); // Kill existing dropdown
  mc = new menuController(tgt, evt); // And build a new one
}

function menuController(el, evt){
  this.trigger     = el;                  // Level 1 menu item
  this.dropper     = el.twin;             // Level 2 menu
  this.trigger.src = this.trigger.ovrsrc; // Roll...
  this.dropper.style.display = "block";   // ...and drop
  this.trigger.onmouseover   = flatten;   // Prevent bubbling on Level 1 item (set by init on level 2)
  flatten(evt);                           // and do it RIGHT NOW!...
  document.onmouseover = undrop;          // Kill menu on "mouse out"
}

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test() {
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len) {
  /* append padding */
  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);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
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);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data) {
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++) {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y) {
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt) {
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str) {
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin) {
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray) {
  var hex_tab = hexcase ? "0123456789ABCDEF" : "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;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray) {
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3) {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++) {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

function geteffectivestyle(el, IEprop, W3prop) {
  if(W3prop == null) W3prop = IEprop;
  if (el.currentStyle) {
    return el.currentStyle[IEprop];
  } else if (window.getComputedStyle) {
    var compStyle = window.getComputedStyle(el, "");
    return compStyle.getPropertyValue(W3prop);
  }
  return false;
}

function mex( namepart, numme, numstart, numend) {
// Mutual EXclude: if parameters are 'arc', 3, 0, 5 sets display "none" for elements with id arc0 to arc5 and to "block" for arc3
  // alert("Running mex");
  if (!document.getElementById) return;
  for(var i = numstart; i <= numend; i++) {
    elid = namepart + i ;
    // alert("Hiding " + elid);
    if ((i != numme) && (document.getElementById(elid))) {
        document.getElementById(elid).style.display = "none";
    }
  }
  elid = namepart + numme;
  // alert("Showing " + elid);
  toggledisplay(elid);
}

/* Functions to control icon slider */
function slideSetup(noLinks) {
  slideDiv = document.getElementById("slideDiv");
  slideImg = document.getElementById("slideImg");
  if( !noLinks) {
    slideImg.onclick = slideJump;
    slideDiv.onclick = slideJump;
  }
  slideDiv.style.backgroundPosition = xpos + "px " + ypos + "px";
  slideImg.pointer = idx;
  slideDiv.pointer = idx;
  timesUp = setTimeout("startSlide()", changems);
}
function slideJump() {
  if(this.pointer < 0 ) {
    // alert("running slidejump, with no target");
    return false;
  } else {
    // slidertarget needs to be set inside the page
    window.location = slidertarget + idx;
  }
}

function startSlide() {
  // For debugging
  var msg1, msg2, msg3, msg4;
  // Normalize start position (set 0 to table width/height)
  xpos = (xpos) ? xpos : xct * xtile;
  ypos = (ypos) ? ypos : yct * ytile;
  xstop = xpos;
  ystop = ypos;
  // Set bearing:   0 (North), 1 (East), 2 (South) or 3 (West)
  bearing = (bearing + 3 + parseInt(3 * Math.random())) % 4 ; // 3 + (0-2) Excludes going back to previous
  // Set increments
  switch (bearing) {
    case 1: // Slide background to left to see next cell to East
      msg1  = ("Move background to left to see next cell to East\n");
      idx   = idx + 1; // Increase image ID number
      if((idx % xct) == 0 ) idx = idx - xct;  // Wrap when crossing right edge of the table
      xstop = xstop - xtile; 
      movesUp = setInterval("slideLeft()", movems);
      break;
    case 2: // Slide background up to see next cell to South
      msg1  = ("Move background up to see next cell to South\n");
      idx   = idx + xct; // Increase image ID number by one row
      if(idx >= (xct * yct)) idx = idx % xct;  // Wrap when crossing bottom edge of the table
      ystop = ystop - ytile; 
      movesUp = setInterval("slideUp()", movems);
      break;
    case 3: // Slide background right to see next cell to West
      msg1  = ("Move background right to see next cell to West\n");
      if ((idx % xct) == 0 ) {   // When crossing right edge of table
        idx   =  idx + xct - 1 ; // ...wrap to end of row
      } else {                   // ...and otherwise
        idx   =  idx - 1 ;       // ...decrease image ID number by 1
      }
      xstop = xstop + xtile; 
      movesUp = setInterval("slideRight()", movems);
      break;
    case 0: // Slide background down to see next cell to North
    default: 
      msg1  = ("Move background down to see next cell to North\n");
      if (idx < xct ) {                   // When crossing top edge of table
        idx   =  idx + (xct * (yct - 1)) ; // ...wrap to bottom of table
      } else {                             // ...and otherwise
        idx   =  idx - xct ;                 // ...decrease image ID number by one row
      }
      ystop = ystop + ytile; 
      movesUp = setInterval("slideDown()", movems);
      break;
  }
  slideImg.pointer = -1 ; // Disactivate links while picture is moving
  slideDiv.pointer = -1 ; // Disactivate links while picture is moving
}
function slideLeft() {
  xpos -= xinc;
  if(xpos <= xstop) {
    xpos = xstop;
    clearInterval(movesUp);
    timesUp = setTimeout("startSlide()", changems);
    slideImg.pointer = idx;
    slideDiv.pointer = idx;
  }
  slideDiv.style.backgroundPosition = xpos + "px " + ypos + "px";
}
function slideRight() {
  xpos += xinc;
  if(xpos >= xstop) {
    xpos = xstop;
    clearInterval(movesUp);
    timesUp = setTimeout("startSlide()", changems);
    slideImg.pointer = idx;
    slideDiv.pointer = idx;
  }
  slideDiv.style.backgroundPosition = xpos + "px " + ypos + "px";
}
function slideUp() {
  ypos -= yinc;
  if(ypos <= ystop) {
    ypos = ystop;
    clearInterval(movesUp);
    timesUp = setTimeout("startSlide()", changems);
    slideImg.pointer = idx;
    slideDiv.pointer = idx;
  }
  slideDiv.style.backgroundPosition = xpos + "px " + ypos + "px";
}
function slideDown() {
  ypos += yinc;
  if(ypos >= ystop) {
    ypos = ystop;
    clearInterval(movesUp);
    timesUp = setTimeout("startSlide()", changems);
    slideImg.pointer = idx;
    slideDiv.pointer = idx;
  }
  slideDiv.style.backgroundPosition = xpos + "px " + ypos + "px";
}
function setLocalRolls() {
  if(document.getElementById) {
    for(i=1; i<6; i++) {
      if(document.getElementById("roller"+i)) setUpRoll(document.getElementById("roller"+i));  
    }
  }
}
function swap(){
	this.className="msieFix";
}
function swapBack(){
	this.className="trigger";
}
function toggle(){
	(this.parentNode.className=="trigger")?this.parentNode.className="msieFix":this.parentNode.className="trigger";
	return false;
}
function hereiam(){
	return false;
}
function reveal(){
	this.parentNode.parentNode.parentNode.className="msieFix";
}
function cleanUp(){
	var zA;
	var LI = document.getElementsByTagName("li");
	var zLI= LI.length;
		for(var k=0;k<zLI;k++){
		if(LI[k]!=this.parentNode){
			LI[k].className="trigger";
		}
	}	
}
function iamOn() {
  if(! document.getElementById ) return;
	var maxheight = document.getElementById("offers").clientHeight + "px";
	this.style.height = maxheight;
	this.style.backgroundImage = "url(/s/pix/bg-iam-y.png)";
}
function iamOff() {
	this.style.height = "auto";
	this.style.backgroundImage = "none";
}
function oskOn() {
  if(! document.getElementById ) return;
	var maxheight = document.getElementById("offers").clientHeight + "px";
	this.style.height = maxheight;
	this.style.backgroundImage = "url(/s/pix/bg-osk-y.png)";
}
function oskOff() {
	this.style.height = "auto";
	this.style.backgroundImage = "none";
}
function shineOn() {
  if(! document.getElementById ) return;
	var maxheight = document.getElementById("offers").clientHeight + "px";
	var bgbox     = this.parentNode.parentNode.parentNode;
	bgbox.style.height = maxheight;
	bgbox.style.backgroundImage = "url(/s/pix/bg-offers-v.png)";
}
function shineOff() {
  if(! document.getElementById ) return;
	var maxheight = document.getElementById("offers").offsetHeight + "px";
	var bgbox     = this.parentNode.parentNode.parentNode;
	bgbox.style.height = "auto";
	bgbox.style.backgroundImage = "none";
}
function usebglink() {
	document.location.href = this.bglink;
}
function setupactiveboxes(){
	// alert("Setting up active boxes");
	activeboxes = new Array("boxexpert", "boxsector", "boxclients", "boxwebsem", "boxkeynote");
	for (n=0;n<activeboxes.length; n++) {
		elid = activeboxes[n];
		// alert("Looking for element " + elid);
		if (el = document.getElementById(elid)) {
			// alert("Found it: " + elid);
			var elinks = el.getElementsByTagName("A");
			if (elinks.length > 0) {
				el.bglink = elinks[0].href;
				el.onclick = usebglink;
			}
		}
	}
}
function swap(){
	this.className="msieFix";
}
function swapBack(){
	this.className="trigger";
}
function reveal(){
	this.parentNode.parentNode.parentNode.className="msieFix";
}
function setupdropmenus(){
	if(!document.getElementById('mainmenu')) return false;
	var LI = document.getElementById('mainmenu').getElementsByTagName("li");
	var zLI= LI.length;
	for(var k=0;k<zLI;k++){
		if(LI[k].id){
			LI[k].className="trigger";
			LI[k].onmouseover=swap;
			LI[k].onmouseout=swapBack;
		}
	}
}


