function dump(o, level) {
   level = level || 0;
   if(level>dump.maxLevel) return "Too deep";
   if(level || (dbg = document.getElementById('dbg_win'))) {
      var ret = '';

      if(typeof(o) != 'function')
         ret = typeof(o) + ': ';

      if(typeof(o) == 'object') {
         ret+= '\r\n';
         try {
            for(i in o) {
               try {
                  ret += "\t".repeat(level) + i + ' => ' + dump(o[i], level+1) + '\r\n';
               } catch(e) {}
            }
         } catch(e) {
            ret = 'can\'t iterate over object';
         }
      } else {
         try {
            ret += o.toString().indent(level, 1);
         } catch(e) {
            ret += 'can\'t convert to string';
         }
      }
      if(level) {
         return ret;
      } else {
         dbg.appendChild(document.createTextNode(ret));
//         dbg.appendChild(document.createElement('hr'));
      }
   }
}

dump.maxLevel = 4;
if(!String.prototype.repeat) {
   String.prototype.repeat = function(n) {
      var s=this.toString(), ret='';
      while( (n--) > 0) ret+=s;
      return ret;
   }
}
if(!String.prototype.indent) {
   String.prototype.indent = function(level, dontIndentFirst, indentChar) {
      indentChar = indentChar || "\t";
      dontIndentFirst = Number(dontIndentFirst)||0;
      var s = this.toString();
      s = s.split(/^/m);
      for(var i=dontIndentFirst, l=s.length; i<l; i++)
         s[i] = indentChar.repeat(level) + s[i];
      return s.join("");
   }
} 

