/*
  ZWF Basic Insert Partial Content Utility System
  (c) 2010 - Jelmer van der Meer - ZWF Ontwerp
*/
var zwfb_bipcus = null;

function ZWFB_BipcusClient(comp, url, blocking, filler){
  this.blocking  = blocking;
  this.type      = 'GET';
  this.params    = new Array();
  this.component = comp;
  this.remoteUrl = url;
  this.request   = null;
  this.result    = '';
  this.filler    = filler;
  this.element   = null;

  this.setPost = function(params){
    this.type = 'POST';
    this.params = params;
  }
  this.setTarget = function(elem){
    this.element = elem;
  }

  this.execute = function(){
    this.loading();
    this.request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    this.request.bipcusClient = this;
    this.request.open(this.type, this.remoteUrl, !this.blocking);
    if(!this.blocking){
      this.request.onreadystatechange = function(){
        if(this.readyState==4){
          if(this.status==200) zwfb_bipcus.removeClient(this);
        }
      }
    }
    if(this.type=='POST') this.request.send(this.params.join('&'));
    else this.request.send();
    if(this.blocking) zwfb_bipcus.removeClient(this.request);
  }
  this.loading = function(){
    if(this.component=='return') return;
    if(this.component=='reload') return;
    if(this.component=='')       return;
    if(this.filler=='nochange')  return;

    if(!this.element) this.element = document.getElementById(this.component);
    if(this.element==null) return;

    this.updateInnerHTML(this.element, this.filler==null || this.filler==false || this.filler=='' ? zwfb_bipcus.filler : this.filler);
  }
  this.updateTRInnerHTML = function(elem, filler){
    filler = filler.replace(/&euro;/g, '&#8364;');
    filler = filler.replace(/&nbsp;/g, ' ');
    
    filler = '<body>'+filler+'</body>';

    var doc   = new ActiveXObject('Microsoft.XMLDOM');
    doc.async = 'false';
    doc.loadXML(filler);
    
    var nodes = doc.childNodes;
    for(var i=0; i<nodes.length; ++i){
    	var body = nodes[i];
    	if(body.tagName!='body') continue;
      var tdlist = body.childNodes;
      for(var j=0; j<tdlist.length; ++j){
      	var oldtd = tdlist[j];
       	var newtd = elem.insertCell(-1);

    		newtd.innerHTML = oldtd.xml;
    		
    		var attrs = oldtd.attributes;
     		for(var k=0; k<attrs.length; ++k) newtd.setAttribute(attrs[k].nodeName, attrs[k].nodeValue);
      }
    }  	
  } 
  this.updateInnerHTML = function(elem, filler){
  	var etype = isIE() ? elem.tagName.toLowerCase() : 'default';
    while(elem.firstChild) elem.removeChild(elem.firstChild);
  	switch(etype){
  		case 'tr':
        if(window.ActiveXObject){
          if(filler=='') return;
          this.updateTRInnerHTML(elem, filler);
        }
        else{
          var parser=new DOMParser();
          var doc=parser.parseFromString(filler,'text/xml');
        }
  		  break;
  		default:
  		  elem.innerHTML = filler;
  		  return;
  	}
  }
  this.finish = function(){
    if(this.component=='reload'){
      window.location.href = window.location.href;
      return;
    }
    else if(this.component=='return'){
      this.result = this.request.responseText;
      return;
    }
    else if(this.component=='') return;

    if(!this.element) this.element = document.getElementById(this.component);
    if(this.element==null) return;

    var content = this.request.responseText;
    var temp = this.clean(content);

    this.updateInnerHTML(this.element, '');

    if(temp[1]!=''){
      var ins = document.createElement('style');
      ins.text = temp[1];
      ins.type = 'text/css';
      document.getElementsByTagName('head')[0].appendChild(ins);
    }

    if(temp[3].length>0){
      for(var i=0; i<temp[3].length; ++i){
        if(zwfb_bipcus.checkCSS(temp[3][i])) continue;
        var ins = document.createElement("link");
        ins.setAttribute("rel", "stylesheet");
        ins.setAttribute("type", "text/css");
        ins.setAttribute("href", temp[3][i]);
        document.getElementsByTagName('head')[0].appendChild(ins);
      }
    }

    this.updateInnerHTML(this.element, temp[0]);

    if(temp[2]!=''){
      var ins = document.createElement('script');
      ins.setAttribute('type', 'text/javascript');
      ins.text = temp[2];
      document.getElementsByTagName('head')[0].appendChild(ins);
    }
  }
  this.clean = function(contents){
    var temp = new Array();
    temp[0] = '';
    temp[1] = '';
    temp[2] = '';
    temp[3] = new Array();
    var index1 = 0, index2 = 0;
    while( (index1 = contents.indexOf('<style')) >= 0){
      index2 = contents.indexOf('</style', index1);
      if(index2>=0){
        temp[0] += contents.substring(0, index1);
        index1 = contents.indexOf('>', index1)+1;
        temp[1] += ' '+contents.substring(index1, index2);
        index2 = contents.indexOf('>', index2)+1;
        contents = contents.substring(index2);
      }
      else break;
    }

    contents = temp[0] + contents;
    temp[0] = '';

    var index1 = 0, index2 = 0;
    while( (index1 = contents.indexOf('<link')) >= 0){
      index2 = contents.indexOf('/>', index1);
      if(index2>=0){
        temp[0] += contents.substring(0, index1);
        index1 = contents.indexOf('href=', index1)+1;
        index1 = contents.indexOf('"', index1)+1;
        var index3 = contents.indexOf('"', index1);
        temp[3][temp[3].length] = contents.substring(index1, index3);
        contents = contents.substring(index2+2);
      }
      else break;
    }

    contents = temp[0] + contents;
    temp[0] = '';

    var index1 = 0, index2 = 0;
    while( (index1 = contents.indexOf('<script')) >= 0){
      index2 = contents.indexOf('</script', index1);
      if(index2>=0){
        temp[0] += contents.substring(0, index1);
        index1 = contents.indexOf('>', index1)+1;
        temp[2] += ' '+contents.substring(index1, index2);
        index2 = contents.indexOf('>', index2)+1;
        contents = contents.substring(index2);
      }
      else break;
    }

    temp[0] += contents;
    return temp;
  }
}

function ZWFB_BipcusClientManager(){
	this.filler   = '<div class="zwfb_loading">Pagina wordt geladen ... </div>';	
  this.csslinks = new Array();
  this.clients  = new Array();

  this.checkCSS = function(url){
    for(var i=0; i<this.csslinks.length; ++i) if(this.csslinks[i]==url) return true;
    this.csslinks[this.csslinks.length] = url;
    return false;
  }
  this.addRawClient = function(newclient, clean){
    this.clients.push(newclient);
    newclient.execute();
    if(clean){
      var result = newclient.result;
      result = result.replace(/^\s+/g,'');
      result = result.replace(/\s+$/g,'');
      newclient.result = result;
    }
    return result;
  }
  this.addResultClient = function(comp_id, url, filler){
    var newclient = new ZWFB_BipcusClient('return', url, true, filler);
    this.clients.push(newclient);
    newclient.execute();
    var result = newclient.result;
    result = result.replace(/^\s+/g,'');
    result = result.replace(/\s+$/g,'');
    return result;
  }
  this.addBlockClient = function(comp_id, url, filler){
    var newclient = new ZWFB_BipcusClient(comp_id, url, true, filler);
    this.clients.push(newclient);
    newclient.execute();
    return true;
  }
  this.addClient = function(comp_id, url, filler){
    var newclient = new ZWFB_BipcusClient(comp_id, url, false, filler);
    this.clients.push(newclient);
    newclient.execute();
    return true;
  }
  this.removeClient = function(client_req){
    var new_array = new Array();
    for(var i in this.clients){
      if(this.clients[i].request==client_req) this.clients[i].finish();
      else new_array.push(this.clients[i]);
    }
    this.clients = new_array;
  }
}

zwfb_bipcus = new ZWFB_BipcusClientManager();

function ZWFB_ReloadItem(url, item){
  this.url  = url;
  this.item = item;

  this.equals = function(item, all){
    if(item.item!=this.item) return false;
    if(!all) return true;
    return item.url==this.url;
  }
  this.reloadSelf = function(){
    zwfb_bipcus.addClient(this.item, this.url);
  }
}
function ZWFB_ReloadPath(name, url, item){
  this.name  = name;
  this.paths = new Array();
  this.items = new Array();

  this.register = function(ipath, iurl, item){
    if(ipath.length<=0) this.items[this.items.length] = new ZWFB_ReloadItem(iurl, item);
    else{
      var next = ipath.pop();
      for(var i in this.paths){
        if(this.paths[i].name!=next) continue;
        this.paths[i].register(ipath, iurl, item);
        return;
      }
      var tmp = new ZWFB_ReloadPath(next, iurl, item);
      tmp.register(ipath, iurl, item);
      this.paths[this.paths.length] = tmp;
    }
  }
  this.unregister = function(ipath){
    if(ipath.length<=0) this.items = new Array();
    else{
      var next = ipath.pop();
      for(var i in this.paths) if(this.paths[i].name==next) this.paths[i].unregister(ipath.slice(0));
    }
  }
  this.reload     = function(ipath, event){
    if(ipath.length<=0) for(var i in this.items) event.register(this.items[i]);
    else{
      var next = ipath.pop();
      for(var i in this.paths) if(this.paths[i].name==next) this.paths[i].reload(ipath.slice(0), event);
    }
  }
}

function ZWFB_ReloadEvent(){
  this.items = new Array();

  this.register = function(item){
    for(var i in this.items) if(this.items[i].equals(item, false)) return;
    this.items[this.items.length] = item;
  }
  this.reload   = function(){
    for(var i in this.items) this.items[i].reloadSelf();
  }
}

function ZWFB_ReloadManager(){
  this.item = new ZWFB_ReloadPath('ROOT', '');

  this.register   = function(ipath, iurl, item){
    var patharray = ipath.split('/');
    patharray = patharray.reverse();
    this.item.register(patharray, iurl, item);
  }
  this.unregister = function(ipath){
    var patharray = ipath.split('/');
    patharray = patharray.reverse();
    this.item.unregister(patharray);
  }
  this.reload     = function(ipath){
    var patharray = ipath.split('/');
    patharray = patharray.reverse();
    var result    = new ZWFB_ReloadEvent();
    this.item.reload(patharray, result);
    result.reload();
  }
}

var zwfb_reloadmanager = new ZWFB_ReloadManager();

function zwfb_popuppresetclass(url, con){
  this.url     = url;
  this.content = con;
}

function zwfb_popupwindowclass(){
  this.presets  = new Array();
  this.popupbox = false;
  this.url      = false;
  this.x        = 0;
  this.y        = 0;
  this.count    = 0;
  this.nohide   = false;

  this.registerPreset = function(url, content){
    for(var i in this.presets){
      if(url!=this.presets[i].url) continue;
      else{
        this.presets[i].content = content;
        return;
      }
    }
    this.presets[this.presets.length] = new zwfb_popuppresetclass(url, content);
  }
  this.registerBox = function(item){
    this.popupbox = item;
    var elem = document.getElementById(item);
    if(elem!=null) return;
    var nelem = document.createElement('div');
    //nelem.setAttribute('class', 'popupwindow');
    nelem.setAttribute('id'   , item);
    nelem.setAttribute('style', 'position: fixed;');
    nelem.className   = 'popupwindow';
    nelem.onmouseover = function(){this.nohide = true; return false;};
    //nelem.onmouseout  = function(){this.nohide = false; zwfb_popup_box.hide(null); return false;};
    nelem.onclick     = function(){zwfb_popup_box.hide(null); return false;};
    nelem.style.left  = '2px';
    nelem.style.top   = '2px';

    var _body = document.getElementsByTagName('body')[0];
    if(_body==null) return;
    _body.appendChild(nelem);
    nelem.style.display = 'none';
  }
  this.show        = function(evt, url, show){
    if(!evt) evt = window.event;
    if(this.url==url && !show) return;
    this.url     = url;
    if(show==true){
    	this.move(evt);
    	this.delay(this.count);
    	this.nohide = true;
    }
  }
  this.hide        = function(evt){
  	if(this.nohide==true) return;
    var elem = document.getElementById(this.popupbox);
    if(elem==null) return;
    this.count++;
    elem.style.display = 'none';
  }
  this.delay       = function(inval){
    if(inval < this.count) return;
    if(this.url==false) return;
    var elem = document.getElementById(this.popupbox);
    if(elem==null){
      zwfb_popup_box.registerBox('mypopupbox');
      elem = document.getElementById(this.popupbox);    	
    	if(elem==null) return;
    }
    
    if(elem.style.display=='block') return;

    var found = false;
    for(var i in this.presets){
      if(this.presets[i].url==this.url){
        if(this.presets[i].content=='') elem.innerHTML = 'Geen extra informatie';
        else elem.innerHTML = this.presets[i].content;
        found = true;
      }
    }
    if(!found) zwfb_bipcus.addBlockClient(this.popupbox, this.url, ' ');
    elem.style.display = 'block';

    var window_w = 0;
    var window_h = 0;
    if(typeof(window.innerWidth)=='number'){
      window_w = window.innerWidth;
      window_h = window.innerHeight;
    }
    else{
      window_w = document.documentElement.clientWidth;
      window_h = document.documentElement.clientHeight;
    }

    if((this.x+elem.offsetWidth+20)>window_w) elem.style.left = (this.x - 5 - elem.offsetWidth)+'px';
    else elem.style.left    = (this.x + 5)+'px';

    if((this.y+elem.offsetHeight+5)>window_h) elem.style.top = (this.y - 5 - elem.offsetHeight)+'px';
    else elem.style.top     = (this.y + 5)+'px';
  }
  this.move       = function(evt){
    if(evt==null) evt = window.event;
    var nx = Math.abs(evt.clientX-this.x);
    var ny = Math.abs(evt.clientY-this.y);

    this.count++;
    this.x       = evt.clientX;
    this.y       = evt.clientY;

    if(nx > 5 || ny > 5) this.hide();
    if(nx < 4  || ny < 4 ) setTimeout('zwfb_popup_box.delay('+this.count+')', 250);
  }
  this.out       = function(url){
    if(this.url==url) this.url = false;
  }
}

var zwfb_popup_box = new zwfb_popupwindowclass();

function isIE(){return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent);}
function getBaseURL() {
  var url     = location.href;
  var baseURL = url.substring(0, url.indexOf('/', 14));

  if(baseURL.indexOf('http://localhost') != -1){
    var url = location.href;  // window.location.href;
    var pathname = location.pathname;  // window.location.pathname;
    var index1 = url.indexOf(pathname);
    var index2 = url.indexOf("/", index1 + 1);
    var baseLocalUrl = url.substr(0, index2);
    return baseLocalUrl + "/";
  }
  else return baseURL + "/";
}
function findPos(obj){
  if(!obj) return 0;
  var curleft = 0;
  var curtop  = 0;
  if(obj.offsetParent){
    do{
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    }while(obj = obj.offsetParent);
  }
  return curleft;
}

function findPosition(obj){
  if(!obj) return 0;
  var curleft = 0;
  var curtop  = 0;
  if(obj.offsetParent){
    do{
      curleft += obj.offsetLeft;
      curtop += obj.offsetTop;
    }while(obj = obj.offsetParent);
  }
  else return [obj.offsetLeft, obj.offsetTop];
  return [curleft, curtop];
}

function findScrollPosition(){
  var position = [0, 0];
  if(typeof window.pageYOffset!='undefined') position = [window.pageXOffset,window.pageYOffset];
  else if(typeof document.documentElement.scrollTop!='undefined' && document.documentElement.scrollTop>0) position = [document.documentElement.scrollLeft,document.documentElement.scrollTop];
  else if(typeof document.body.scrollTop!='undefined') position = [document.body.scrollLeft,document.body.scrollTop];
  return position;
}

function findMousePosition(obj, evt){
	if(!obj) return [0,0];
	if(!evt) evt = window.event;
	
	var obj_pos = findPosition(obj);
	var scl_pos = findScrollPosition();			
	return [evt.clientX + scl_pos[0] - obj_pos[0], evt.clientY + scl_pos[1] - obj_pos[1]];
}

function getChildNodes(elem){
  if(elem==null) return new Array();
  var nodes = elem.childNodes;
  var result = new Array();
  for(var i=0; i<nodes.length; ++i){
    if(nodes[i].className) result.push(nodes[i]);
  }
  return result;
}

function openMyLink(elem){
	if(!elem) elem = document;
	var lst = elem.getElementsByTagName('a');
	if(lst.length<=0) return;
	window.location = lst[0].href;
}

function getChildNodesByClass(elem, clss, only_direct){
	if(!elem) elem = document.body;
	var elems  = only_direct ? elem.childNodes : document.getElementsByTagName('*');
	var result = new Array();
	for(var i=0; i<elems.length; ++i){
		if(!hasClass(elems[i], clss)) continue;
		else result.push(elems[i]);
	}
	return result;
}
function getElementByClass(clss, elem){
	if(!elem) elem = document;
	var elems = elem.getElementsByTagName('*');
	for(var i=0; i<elems.length; ++i) if(hasClass(elems[i], clss)) return elems[i];
	return null;
}
function getElementsByClass(clss, elem){
	if(!elem) elem = document;
	var elems = elem.getElementsByTagName('*');
	var result = new Array();
	for(var i=0; i<elems.length; ++i) if(hasClass(elems[i], clss)) result.push(elems[i]);
	return result;
}
function hasClass(elem,clss){
  if(elem==null) return false;
	if(!elem.className) return false;	
  return elem.className.match(new RegExp('(\\s|^)'+clss+'(\\s|$)'));
}
function addClass(elem,clss){
	if(!elem) return;
  if(!hasClass(elem,clss)){
  	if(elem.className) elem.className += " "+clss;
  	else elem.className = clss;
  }
}
function removeClass(elem,clss){
  if(hasClass(elem,clss)){
    var reg = new RegExp('(\\s|^)'+clss+'(\\s|$)');
    elem.className=elem.className.replace(reg,' ');
  }
}
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 eraseCookie(name){createCookie(name,"",-1);}

function addLoadEvent(func) { 
  var oldonload = window.onload; 
  if(typeof window.onload != 'function') window.onload = func;
	else{ 
	  window.onload = function(){ 
	    if(oldonload) oldonload(); 
	    func();
	  }
  }
}






/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Copyright (C) Paul Johnston 1999 - 2000.
 * Updated by Greg Holt 2000 - 2001.
 * See http://pajhome.org.uk/site/legal.html for details.
 */

/*
 * Convert a 32-bit number to a hex string with ls-byte first
 */
var hex_chr = "0123456789abcdef";
function rhex(num){
  str = "";
  for(j = 0; j <= 3; j++)
    str += hex_chr.charAt((num >> (j * 8 + 4)) & 0x0F) +
           hex_chr.charAt((num >> (j * 8)) & 0x0F);
  return str;
}

/*
Convert a string to a sequence of 16-word blocks, stored as an array.
Append padding bits and the length, as described in the MD5 standard.
*/
function str2blks_MD5(str){
  nblk = ((str.length + 8) >> 6) + 1;
  blks = new Array(nblk * 16);
  for(i = 0; i < nblk * 16; i++) blks[i] = 0;
  for(i = 0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << ((i % 4) * 8);
  blks[i >> 2] |= 0x80 << ((i % 4) * 8);
  blks[nblk * 16 - 2] = str.length * 8;
  return blks;
}

/* 
Add integers, wrapping at 2^32. This uses 16-bit operations internally 
to work around bugs in some JS interpreters.
*/
function 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 rol(num, cnt){return (num << cnt) | (num >>> (32 - cnt));}

/* These functions implement the basic operation for each round of the algorithm. */
function cmn(q, a, b, x, s, t){return add(rol(add(add(a, q), add(x, t)), s), b);}
function ff(a, b, c, d, x, s, t){return cmn((b & c) | ((~b) & d), a, b, x, s, t);}
function gg(a, b, c, d, x, s, t){return cmn((b & d) | (c & (~d)), a, b, x, s, t);}
function hh(a, b, c, d, x, s, t){return cmn(b ^ c ^ d, a, b, x, s, t);}
function ii(a, b, c, d, x, s, t){return cmn(c ^ (b | (~d)), a, b, x, s, t);}

/* Take a string and return the hex representation of its MD5. */
function calcMD5(str){
  x = str2blks_MD5(str);
  a =  1732584193;
  b = -271733879;
  c = -1732584194;
  d =  271733878;

  for(i = 0; i < x.length; i += 16){
    olda = a;
    oldb = b;
    oldc = c;
    oldd = d;

    a = ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = ff(c, d, a, b, x[i+10], 17, -42063);
    b = ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = ff(d, a, b, c, x[i+13], 12, -40341101);
    c = ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = ff(b, c, d, a, x[i+15], 22,  1236535329);    

    a = gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = gg(c, d, a, b, x[i+11], 14,  643717713);
    b = gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = gg(c, d, a, b, x[i+15], 14, -660478335);
    b = gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = gg(b, c, d, a, x[i+12], 20, -1926607734);
    
    a = hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = hh(b, c, d, a, x[i+14], 23, -35309556);
    a = hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = hh(d, a, b, c, x[i+12], 11, -421815835);
    c = hh(c, d, a, b, x[i+15], 16,  530742520);
    b = hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = ii(c, d, a, b, x[i+10], 15, -1051523);
    b = ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = ii(d, a, b, c, x[i+15], 10, -30611744);
    c = ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = add(a, olda);
    b = add(b, oldb);
    c = add(c, oldc);
    d = add(d, oldd);
  }
  return rhex(a) + rhex(b) + rhex(c) + rhex(d);
}

