if (!document._commonsIncluded_) {
  document._commonsIncluded_ = true;

  function byId(id) {return document.getElementById(id);}

  function deepCopy(val) {
    if (typeof(val) == 'object' && typeof(val.length) == 'number') {
      var ret = [];
      for (var i = 0; i < val.length; ++i) {
        ret.push(deepCopy(val[i]));
      }
      return ret;
    } else if (typeof(val) == 'object') {
      var ret = {};
      for (var idx in val) {
        ret[idx] = deepCopy(val[idx]);
      }
      return ret;
    } else {
      return val;
    }
  }

  function saveAsJSON(val,indent,strings,namePath) {
    var returnString = false;
    if (!strings) {
      strings = [];
      returnString = true;
    }
    if (val == null) {
      strings.push(indent == null ? "var null;\n\n" : "null");
    } else if (typeof(val) == 'object' && typeof(val.length) != 'number' && indent == null) {
      for (var key in val) {
        strings.push("var " + key + " = ");
        saveAsJSON(val[key],"",strings,key);
        strings.push(";\n\n");
      }
    } else if (typeof(val) == 'object' && typeof(val.length) == 'number') {
      if (val.length == 0) {
        strings.push("[]");
      } else {
        var objStrings = [];
        var totalLength = 0;
        for (var i = 0; i < val.length; ++i) {
          var valStr = saveAsJSON(val[i],indent + "  ",null,namePath+"."+i);
          objStrings.push(valStr);
          totalLength += valStr.length;
        }
        if (totalLength <= 80) {
          strings.push("[" + objStrings.join(",") + "]");
        } else {
          strings.push("[\n" + indent + "  " + objStrings.join(",\n" + indent + "  ") + "\n" + indent + "]");
        }
      }
    } else if (typeof(val) == 'object') {
      strings.push("{\n");
      var isFirst = true;
      for (var key in val) {
        strings.push((isFirst ? "" : ",\n") + indent + "  \"" + key + "\": ");
        isFirst = false;
        saveAsJSON(val[key],indent + "  ",strings,namePath+"."+key);
      }
      strings.push("\n" + indent + "}");
    } else if (typeof(val) == 'number') {
      strings.push(val);
    } else if (typeof(val) == 'string') {
      // Notice: ' intentionally not masked since that is not necessary and would cause trouble to PHP's jason_decode()
      strings.push('"' + val.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/``/g,"\\\"").replace(/`/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t") + '"');
    } else if (typeof(val) == 'boolean') {
      strings.push(val ? "true" : "false");
    } else {
      alert('unknown type: ' + typeof(val) + ' for value ' + val + ' namePath=' + namePath);
    }
  
    if (returnString) {
      return strings.join("");
    } else {
      return strings;
    }
  }
  
  function saveAsBD(val,indent,strings,namePath) {
    var returnString = false;
    if (typeof(strings) == 'undefined' || strings == null) {
      strings = [];
      returnString = true;
    }
    if (typeof(indent) == 'undefined') {
      if (!(typeof(val) == 'object' && typeof(val.length) != 'number')) {
        alert('saveAsBD: invalid data');
      }
      var objStrings = [];
      for (var key in val) { objStrings.push(key + "=" + saveAsBD(val[key],"",null,key)); }
      strings.push(objStrings.join("\r\n"));
    } else if (typeof(val) == 'object' && typeof(val.length) == 'number') {
      var objStrings = [];
      for (var i = 0; i < val.length; ++i) {
        var valStr = indent+key+"="+saveAsBD(val[i],indent + " ",null,namePath+"."+i);
        objStrings.push(valStr);
      }
      if (objStrings.length==0) {strings.push("{}");}
      else {strings.push("{\r\n" + indent + " " + objStrings.join("\r\n" + indent + " ") + "\r\n" + indent + "}");}
    } else if (typeof(val) == 'object') {
      var objStrings = [];
      for (var key in val) {
        var valStr = indent+key+"="+saveAsBD(val[key],indent + " ",null,namePath+"."+key);
        objStrings.push(valStr);
      }
      if (objStrings.length==0) {strings.push("{}");}
      else {strings.push("{\r\n" + indent + " " + objStrings.join("\r\n" + indent + " ") + "\r\n" + indent + "}");}
    } else if (typeof(val) == 'number') {
      strings.push(val);
    } else if (typeof(val) == 'string') {
      if (val.indexOf("\r\n") >= 0 || trim(val) == "{") {
        strings.push('"<{'+val+'}>"');
      } else {
        strings.push(val);
      }
    } else if (typeof(val) == 'boolean') {
      strings.push(val ? "true" : "false");
    } else {
      alert('unknown type: ' + typeof(val) + ' for value ' + val + ' namePath=' + namePath);
    }
  
    if (returnString) {
      return strings.join("");
    } else {
      return strings;
    }
  }

  // initialize global variables
  var detectableWithVB = false;
  var pluginFound = false;
  var javascriptVersion1_1=false;

  function goURL(daURL) {
    // if the browser can do it, use replace to preserve back button
    if(javascriptVersion1_1) { window.location.replace(daURL); } 
    else { window.location = daURL; }
    return;
  }

  function redirectCheck(pluginFound, redirectURL, redirectIfFound) {
    // check for redirection
    if( redirectURL && ((pluginFound && redirectIfFound) || (!pluginFound && !redirectIfFound)) ) {
      goURL(redirectURL); return pluginFound;
    } else {
     // stay here and return result of plugin detection
     return pluginFound;
    }
  }

  function canDetectPlugins() {
    if( detectableWithVB || (navigator.plugins && navigator.plugins.length > 0) ) { return true; } 
    else { return false; }
  }

  function detectFlash(redirectURL, redirectIfFound) {
    pluginFound = detectPlugin('Shockwave','Flash'); 
    // if not found, try to detect with VisualBasic
    if(!pluginFound && detectableWithVB) { pluginFound = detectActiveXControl('ShockwaveFlash.ShockwaveFlash.1'); }
    // check for redirection
    return redirectCheck(pluginFound, redirectURL, redirectIfFound);
  }

  function detectDirector(redirectURL, redirectIfFound) { 
    pluginFound = detectPlugin('Shockwave','Director'); 
    // if not found, try to detect with VisualBasic
    if(!pluginFound && detectableWithVB) { pluginFound = detectActiveXControl('SWCtl.SWCtl.1'); }
    // check for redirection
    return redirectCheck(pluginFound, redirectURL, redirectIfFound);
  }

  function detectQuickTime(redirectURL, redirectIfFound) {
    pluginFound = detectPlugin('QuickTime');
    // if not found, try to detect with VisualBasic
    if(!pluginFound && detectableWithVB) { pluginFound = detectQuickTimeActiveXControl(); }
    return redirectCheck(pluginFound, redirectURL, redirectIfFound);
  }

  function detectReal(redirectURL, redirectIfFound) {
    pluginFound = detectPlugin('RealPlayer');
    // if not found, try to detect with VisualBasic
    if(!pluginFound && detectableWithVB) {
      pluginFound = (detectActiveXControl('rmocx.RealPlayer G2 Control') ||
      detectActiveXControl('RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)') ||
      detectActiveXControl('RealVideo.RealVideo(tm) ActiveX Control (32-bit)'));
    }
    return redirectCheck(pluginFound, redirectURL, redirectIfFound);
  }

  function detectWindowsMedia(redirectURL, redirectIfFound) {
    pluginFound = detectPlugin('Windows Media');
    // if not found, try to detect with VisualBasic
    if(!pluginFound && detectableWithVB) { pluginFound = detectActiveXControl('MediaPlayer.MediaPlayer.1'); }
    return redirectCheck(pluginFound, redirectURL, redirectIfFound);
  }

  function detectPlugin() {
    // allow for multiple checks in a single pass
    var daPlugins = detectPlugin.arguments;
    // consider pluginFound to be false until proven true
    var pluginFound = false;
    // if plugins array is there and not fake
    if (navigator.plugins && navigator.plugins.length > 0) {
      var pluginsArrayLength = navigator.plugins.length;
      // for each plugin...
      for (pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ ) {
        // loop through all desired names and check each against the current plugin name
        var numFound = 0;
        for(namesCounter=0; namesCounter < daPlugins.length; namesCounter++) {
          // if desired plugin name is found in either plugin name or description
          if( (navigator.plugins[pluginsArrayCounter].name.indexOf(daPlugins[namesCounter]) >= 0) || 
              (navigator.plugins[pluginsArrayCounter].description.indexOf(daPlugins[namesCounter]) >= 0) 
          ) {
           // this name was found
           numFound++;
          }   
        }
        // now that we have checked all the required names against this one plugin,
        // if the number we found matches the total number provided then we were successful
        if(numFound == daPlugins.length) {
          pluginFound = true;
          // if we've found the plugin, we can stop looking through at the rest of the plugins
          break;
        }
      }
    }
    return pluginFound;
  } // detectPlugin


  // Here we write out the VBScript block for MSIE Windows
  if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
    document.writeln('<script language="VBscript">');

    document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
    document.writeln('detectableWithVB = False');
    document.writeln('If ScriptEngineMajorVersion >= 2 then');
    document.writeln('  detectableWithVB = True');
    document.writeln('End If');

    document.writeln('\'this next function will detect most plugins');
    document.writeln('Function detectActiveXControl(activeXControlName)');
    document.writeln('  on error resume next');
    document.writeln('  detectActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('     detectActiveXControl = IsObject(CreateObject(activeXControlName))');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('\'and the following function handles QuickTime');
    document.writeln('Function detectQuickTimeActiveXControl()');
    document.writeln('  on error resume next');
    document.writeln('  detectQuickTimeActiveXControl = False');
    document.writeln('  If detectableWithVB Then');
    document.writeln('    detectQuickTimeActiveXControl = False');
    document.writeln('    hasQuickTimeChecker = false');
    document.writeln('    Set hasQuickTimeChecker = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")');
    document.writeln('    If IsObject(hasQuickTimeChecker) Then');
    document.writeln('      If hasQuickTimeChecker.IsQuickTimeAvailable(0) Then ');
    document.writeln('        detectQuickTimeActiveXControl = True');
    document.writeln('      End If');
    document.writeln('    End If');
    document.writeln('  End If');
    document.writeln('End Function');

    document.writeln('</scr' + 'ipt>');
  }

  function playSound(sndFile,callingObj,xOffs,yOffs) {
    setTimeout(function() {startPlayingSound(sndFile,callingObj,xOffs,yOffs);}, 100);
    return true;
  }
  function startPlayingSound(sndFile,callingObj,xOffs,yOffs) {
    if (detectFlash()) {
      var sndContainer = document.getElementById("sndContainer");
      if (!sndContainer) {
        sndContainer = document.createElement("div");
        sndContainer.id="sndContainer";
        sndContainer.style.borderWidth = 0;
        sndContainer.style.position = 'absolute';
        sndContainer.style.display = "block";
        sndContainer.style.zIndex = 200;
        document.body.appendChild(sndContainer);
      }
      if (callingObj) {
        var pos = getElemPos(callingObj);
        sndContainer.style.top = pos.top+yOffs;
        sndContainer.style.left = pos.left+xOffs;
      } else {
        sndContainer.style.top = 0;
        sndContainer.style.left = -20;
      }
      // Ich verstehe es noch nicht ganz - aber Dateiaufruf ueber ../../cut/LN/rec.mp3 funktioniert auf Server nicht (lokal dagegen schon).
      // Daher wenn Datei unter ../../cut gefunden, Dateiname fuer Link einkuerzen auf ../cut.
      // Das wird dann ueber .htaccess richtig geroutet und funktioniert.
      if (sndFile.substr(0,9)=='../../cut') {sndFile=sndFile.substr(3);}
      sndContainer.innerHTML = '<object id="sndembend" type="application/x-shockwave-flash" data="./musicplayer.swf?&song_url=' + sndFile +
       '&autoplay=true&autoload=true" width="17" height="17" alt="Chinesischen Satz vorlesen"> ' +
       '<param name="movie" value="./musicplayer.swf?&song_url=' + sndFile + '&autoplay=true&autoload=true"/> ' +
       '<img src="noflash.gif" width="17" height="17" alt="" /> </object>';
    } else { // IE
      var s = document.getElementById('bgsound');
      if (!s) {
        s = document.createElement("bgsound");
        s.id = "bgsound"; s.loop = 1;
        document.body.appendChild(s);
      }
      s.src = sndFile;
    }
  }

  function escapeForHtmlAttr(str) {
    return str.replace(/\\/g,'\\\\').replace(/&/g,"&amp;").replace(/'/g,'\\\'').replace(/"/g,'&quot;').replace(/</g,"&lt;").replace(/>/g,"&gt").replace(/\n/g,"\\n").replace(/\r/g,"\\r");
  }
  function escapeForHtml(str) {
    return str.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt");
  }
  
  var cookieParsed = null;

  function parseCookie() {
    cookieParsed = {};
    if (document.cookie) {
      var entries = document.cookie.split('; ');
      for (nr in entries) {
        var entr = entries[nr];
        var equalIdx = entr.indexOf('=');
        if (equalIdx == 0 || entr.length == 0) {continue;}
        if (equalIdx < 0) {
          cookieParsed[entr] = "";
        } else {
          cookieParsed[entr.substring(0,equalIdx)] =
            entr.substring(equalIdx+1).replace(/-\./g, ";");
        }
      }
    }
  }

  function getCookieVal(name) {
    if (cookieParsed == null) {parseCookie();}
    var val = cookieParsed[name];
    if (!val) {return '';}
    return val;
  }

  function setCookieVal(name, val) {
    if (cookieParsed == null) {parseCookie();}
    cookieParsed[name] = val;

    var val = cookieParsed[name];
    if (typeof(val) == 'string') {val = val.replace(/;/g, "-.");}
    c = name + '=' + val;

    expdate = new Date();
    expdate.setTime(expdate.getTime() + (10 * 365 * 24 * 60 * 60 * 1000));
    c += "; expires=" + expdate.toGMTString();
 
    document.cookie = c;
  }

  function isSpace(c) {return (c == ' ' || c == '\n' || c == '\r' || c == '\t');}
  function trim(s) {
    while (s.length && isSpace(s.charAt(0))) {s = s.substr(1);}
    while (s.length && isSpace(s.charAt(s.length-1))) {s = s.substr(0,s.length-1);}
    return s;
  }

function basename(val) {
  var slashpos = val.lastIndexOf('/');
  var backslashpos = val.lastIndexOf('\\');
  if (slashpos > backslashpos) {
    return val.substr(slashpos + 1);
  } else if (backslashpos > slashpos) {
    return val.substr(backslashpos + 1);
  } else {
    return val;
  }
}

  // element position in screen coordinates
  function getElemPos (elem) {
      var pos = {left: elem.offsetLeft,
      top: elem.offsetTop,
      width: elem.offsetWidth,
      height: elem.offsetHeight};
      var offsetParent = elem;
      while ((offsetParent = offsetParent.offsetParent) != null) {
      pos.left += offsetParent.offsetLeft;
      pos.top += offsetParent.offsetTop;
      if (offsetParent != document.body) {
      pos.left -= offsetParent.scrollLeft;
      pos.top -= offsetParent.scrollTop;
      }
      }
      pos.right = pos.left + pos.width;
      pos.bottom = pos.top + pos.height;
      return pos;
  }

  function posToStr(pos) {
      var str = 'left=' + pos.left + ' right=' + pos.right + ' width=' + pos.width + '<br/>' +
      'top=' + pos.top + ' bottom=' + pos.bottom + ' height=' + pos.height + '<br/>';
      return str;
  }

  function ptIsInElem(x,y,elemPos,margin) {
      if (margin == null) {margin = 0;}
      if (x - 1 > elemPos.left - margin && x <= elemPos.right  + margin &&
      y - 1 > elemPos.top  - margin && y <= elemPos.bottom + margin
      ) {
      return true;
      } else {
      return false;
      }
  }
  
  function posVerticalOverlap(pos1,pos2) {
    if ( ( ( pos1.left   > pos2.left && pos1.left   < pos2.right  ) ||
           ( pos1.right  > pos2.left && pos1.right  < pos2.right  ) ) &&
         ( ( pos1.top    > pos2.top  && pos1.top < pos2.bottom ) ||
           ( pos1.bottom > pos2.top  && pos1.bottom < pos2.bottom ) )
    ) {
      if (pos2.top - pos1.bottom > pos2.bottom - pos1.top) {
        return pos2.top - pos1.bottom;
      } else {
        return pos2.bottom - pos1.top;
      }
    } else {
      return -1;
    }
  } 
  
  function getClientWindowWidth() {
    if (window.innerWidth){
        return (window.innerWidth - (window.scrollbars.visible ? 17 : 0));                     // Mozilla; -17 for scrollbars
    }

    if (document.documentElement.clientWidth)
        return document.documentElement.clientWidth;    // IE6

    if (document.body.clientWidth)
        return document.body.clientWidth;               // IE DHTML-compliant any other
  }

  function getClientWindowHeight() {
    if (window.innerHeight){
        return (window.innerHeight - (window.scrollbars.visible ? 17 : 0));                     // Mozilla; -17 for scrollbars
    }

    if (document.documentElement.clientHeight)
        return document.documentElement.clientHeight;    // IE6

    if (document.body.clientHeight)
        return document.body.clientHeight;               // IE DHTML-compliant any other
  }


  function copyToClipboard(txt) {
    if (navigator.userAgent.indexOf('MSIE') != -1) {
      if (!window.clipboardData.setData('Text', txt)) {
        alert("Error - text was not copied to clipboard!")
        return false;
      }
    } else if (navigator.userAgent.indexOf('Mozilla') != -1) {
      try {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
      } catch(e) {
        alert("Your current Internet Security settings do not allow data copying to clipboard.\r\n" +
          "You can enable it in FireFox by browsing to about:config and then setting\r\n" +
          "signed.applets.codebase_principal_support\r\n" +
          "to the value \"true\"");
        return;
      }
      
      try {
        e=Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard)
      } catch(e) {
        alert("Error - text was not copied to clipboard!");
        }
      
      try {
        b=Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable)
      } catch(e) {
        alert("Error - text was not copied to clipboard!");
      }
      
      b.addDataFlavor("text/unicode");
      o=Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
      o.data=txt;
      b.setTransferData("text/unicode",o,txt.length*2);
      
      try{
      t=Components.interfaces.nsIClipboard
      } catch(e) {
        alert("Error - text was not copied to clipboard!");
      }
      
      e.setData(b,null,t.kGlobalClipboard)
      return true;
    } else {
      alert("Your browser doesn't support the copy to clipboard feature.");
      return false;
    }
  }

  function callFunctionsFromArray(arr) {
    for (var i = 0; i < arr.length; ++i) {
      d = arr[i];
      if (d) { d.fct(d.obj); }
    }
  }
  function callFunctionsFromArrayWithEvt(arr,evt) {
    for (var i = 0; i < arr.length; ++i) {
      d = arr[i];
      if (d) { d.fct(evt,d.obj); }
    }
  }
  // don't use associative array because it does not maintain order
  function setByKey(arr,k,obj) {
    obj.key = k;
    for (var i = 0; i < arr.length; ++i) {
      if (arr[i] && arr[i].key == k) {
        arr[i] = obj;
        return;
      }
    }
    arr.push(obj);
  }

  function getAllChildNodes(node,result) {
    for (var i = 0; i < node.childNodes.length; ++i) {
      result.push(node.childNodes[i]);
      getAllChildNodes(node.childNodes[i],result);
    }
  }

  var mouseX = 0;
  var mouseY = 0;
  var mousemoveHandlers = [];
  var mousedownHandlers = [];
  var mouseupHandlers = [];
  var keypressHandlers = [];
  var keydownHandlers = [];
  var keyupHandlers = [];
  var onloadHandlers = [];
  var mouseIsInitialized = false;
  function mouseinit() {
    if (mouseIsInitialized) {return;}
    mouseIsInitialized = true;
    // Initialisierung der Überwachung der Events
    document.onmousemove = function(evt) {
      mouseX = document.all ? window.event.clientX + document.body.scrollLeft : evt.pageX;
      mouseY = document.all ? window.event.clientY + document.body.scrollTop : evt.pageY;
      return callFunctionsFromArray(mousemoveHandlers);
    };
    document.onmousedown = function() { return callFunctionsFromArray(mousedownHandlers); }
    document.onmouseup = function() { return callFunctionsFromArray(mouseupHandlers); }
    document.onkeypress = function(evt) { return callFunctionsFromArrayWithEvt(keypressHandlers,evt); }
    document.onkeydown = function(evt) { return callFunctionsFromArrayWithEvt(keydownHandlers,evt); }
    document.onkeyup = function(evt) { return callFunctionsFromArrayWithEvt(keyupHandlers,evt); }
    window.onload = function() { return callFunctionsFromArray(onloadHandlers); }
  }
  function registerMouseMoveHandler(k,o,f) {
    mouseinit();
    setByKey(mousemoveHandlers,k,{obj:o,fct:f});
  }
  function unregisterMouseMoveHandler(k) {
    setByKey(mousemoveHandlers,k,null);
  }
  function registerMouseDownHandler(k,o,f) {
    mouseinit();
    setByKey(mousedownHandlers,k,{obj:o,fct:f});
  }
  function unregisterMouseDownHandler(k) {
    setByKey(mousedownHandlers,k,null);
  }
  function registerMouseUpHandler(k,o,f) {
    mouseinit();
    setByKey(mouseupHandlers,k,{obj:o,fct:f});
  }
  function unregisterMouseUpHandler(k) {
    setByKey(mouseupHandlers,k,null);
  }
  function registerKeyPressHandler(k,o,f) {
    mouseinit();
    setByKey(keypressHandlers,k,{obj:o,fct:f});
  }
  function unregisterKeyPressHandler(k) {
    setByKey(keypressHandlers,k,null);
  }
  function registerKeyDownHandler(k,o,f) {
    mouseinit();
    setByKey(keydownHandlers,k,{obj:o,fct:f});
  }
  function unregisterKeyDownHandler(k) {
    setByKey(keydownHandlers,k,null);
  }
  function registerKeyUpHandler(k,o,f) {
    mouseinit();
    setByKey(keyupHandlers,k,{obj:o,fct:f});
  }
  function unregisterKeyUpHandler(k) {
    setByKey(keyupHandlers,k,null);
  }
  function registerOnLoadHandler(k,o,f) {
    mouseinit();
    setByKey(onloadHandlers,k,{obj:o,fct:f});
  }
  function unregisterOnLoadHandler(k) {
    setByKey(onloadHandlers,k,null);
  }

  // tooltip artige Popups. Vorerst nur statischer Modus (HTML fuer Popupinhalt bei Generierung
  // (uebergeben). ToDo: HTLM optional dynamisch mit Callbackfunktion generieren
  var registeredPopups = {};
  var registeredPopup = null;
  var registeredPopupCurrBaseElem = null;
  function showRegisteredPopup(baseElem,registeredId) {
    registerMouseMoveHandler("hideRegisteredPopup",null,hideRegisteredPopup);
    hideRegisteredPopup(true);
    registeredPopupCurrBaseElem = baseElem;
    registeredPopup = document.createElement("div");
    registeredPopup.style.backgroundColor = "#FFFFE0";
    registeredPopup.style.border = "black solid 1px";
    registeredPopup.style.padding = 2;
    registeredPopup.style.paddingLeft = registeredPopup.style.paddingRight = 6;
    registeredPopup.style.position = "absolute";
    registeredPopup.style.display = "block";
    var spanPos = getElemPos(baseElem);
    registeredPopup.style.left = 10;
    registeredPopup.style.top = 10;
    registeredPopup.innerHTML = registeredPopups[registeredId];
    document.body.appendChild(registeredPopup);
  }
  function hideRegisteredPopup(force) {
    if (!registeredPopup) {return;}
    if (force || !ptIsInElem(mouseX,mouseY,getElemPos(registeredPopupCurrBaseElem),2)) {
      registeredPopup.style.display = "none";
      document.body.removeChild(registeredPopup);
      registeredPopup = null;
      registeredPopupCurrBaseElem = null;
    } else {
      registeredPopup.style.left = Math.max(10,Math.min(getClientWindowWidth() - registeredPopup.offsetWidth - 10, mouseX + 10));
      registeredPopup.style.top = Math.max(10,
        Math.min((getClientWindowHeight()+document.body.scrollTop) - registeredPopup.offsetHeight - 10, 
        mouseY + 10));
    }
  }
  var popupBaseIdCnt = 0;
  function registerPopup(baseElem,popupHtml) {
    if (!baseElem.id || baseElem.id.length == 0) { baseElem.id = "popupBase" + (++popupBaseIdCnt); }
    registeredPopups[baseElem.id] = popupHtml;
    //baseElem.onmouseover = 'alert("over"); showRegisteredPopup(this,"' + baseElem.id + '");';
    baseElem.onmouseover = function() {showRegisteredPopup(this,baseElem.id);};
  }

} // document._commonsIncluded_
