/*
 * JavaScript probing framework by Sam Saffron
 * MIT license
 *
 *
 * Examples:
 *
 *  someFunction = window.probes.measure(someFunction, {
 *    name: "somename" // or function(args) { return "name"; },
 *    before: function(data, owner, args) {
 *      // if owner is true, we are not in a recursive function call.
 *      //
 *      // data contains the bucker of data already measuer
 *      // data.count >= 0
 *      // data.time is the total time measured till now
 *      //
 *      // arguments contains the original arguments sent to the function
 *    },
 *    after: function(data, owner, args) {
 *      // same format as before
 *    }
 *  });
 *
 *
 *  // minimal
 *  someFunction = window.probes.measure(someFunction, "someFunction");
 *
 * */
(function(){
  var measure, clear;

  clear = function() {
    window.probes = {
      clear: clear,
      measure: measure,
      displayProbes: displayProbes
    };
  };

  measure = function(fn,options) {
    // start is outside so we measure time around recursive calls properly
    var start = null, nameParam, before, after;
    if (!options) {
      options = {};
    }

    if (typeof options === "string") {
      nameParam = options;
    }
    else
    {
      nameParam = options.name;

      if (nameParam === "measure" || nameParam === "clear") {
        throw new Error("can not be called measure or clear");
      }

      if (!nameParam)
      {
        throw new Error("you must specify the name option measure(fn, {name: 'some name'})");
      }

      before = options.before;
      after = options.after;
    }

    var now = (function(){
      var perf = window.performance || {};
      var time = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
      return time ? time.bind(perf) : function() { return new Date().getTime(); };
    })();

    return function() {
      var name = nameParam;
      if (typeof name === "function"){
        name = nameParam(arguments);
      }
      var p = window.probes[name];
      var owner = (!start);

      if (before) {
        // would like to avoid try catch so its optimised properly by chrome
        before(p, owner, arguments);
      }

      if (p === undefined) {
        window.probes[name] = {count: 0, time: 0, currentTime: 0};
        p = window.probes[name];
      }

      var callStart;
      if (owner) {
        start = now();
        callStart = start;
      }
      else if(after) {
        callStart = now();
      }

      var r = fn.apply(this, arguments);
      if (owner && start) {
        p.time += now() - start;
        start = null;
      }
      p.count += 1;

      if (after) {
        p.currentTime = now() - callStart;
        // would like to avoid try catch so its optimised properly by chrome
        after(p, owner, arguments);
      }

      return r;
    };
  };

  var displayProbes = function(){
     var pre;
     var text = "";
     var body = document.getElementsByTagName("body")[0];

     for(var prop in window.probes){
       var probe = window.probes[prop];
       if(probe && probe.count){
          text += prop + ": " + probe.time + " ( " + probe.count + " )\n";
       }
     }

     pre = document.getElementById("__probes");

     if(!body){
       return;
     }

     if(pre){
       pre.textContent = text;
       pre.innerText = text;
       return;
     }

     pre = document.createElement("pre");

     pre.textContent = text;
     pre.innerText = text;
     pre.setAttribute("style", "position: fixed; bottom: 25px; left: 50px; z-index: 99999; border: 1px solid #777; padding: 10px; background-color: rgba(255,255,255, 0.8);");
     pre.id = "__probes";
     body.appendChild(pre);
  };


  // setInterval(displayProbes, 1000);
  clear();

})();

@@ -3356,35 +3356,39 @@
 n;%0A     %7D%0A%0A     
-pre
+var div
  = document.crea
@@ -3402,80 +3402,57 @@
 nt(%22
-pre
+div
 %22);%0A
-%0A
      
-pre.textContent = text;%0A     pre.innerText = text
+div.id = %22__probes_wrapper%22
 ;%0A     
-pre
+div
 .set
@@ -3613,16 +3613,166 @@
 0.8);%22);
+%0A%0A     pre = document.createElement(%22pre%22);%0A     pre.setAttribute(%22style%22, %22margin:0 0 5px;%22);%0A     pre.textContent = text;%0A     pre.innerText = text;
 %0A     pr
@@ -3794,33 +3794,466 @@
 s%22;%0A
+%0A
      
-body.appendChild(pre
+div.appendChild(pre);%0A%0A     var a = document.createElement('a');%0A     a.href = %22%22;%0A     a.innerText = %22clear%22;%0A     a.addEventListener(%22click%22, function(e)%7B%0A        for(var prop in window.probes)%7B%0A          var probe = window.probes%5Bprop%5D;%0A          if(probe && probe.count)%7B%0A            delete window.probes%5Bprop%5D;%0A          %7D%0A        %7D%0A        displayProbes();%0A        e.preventDefault();%0A     %7D);%0A%0A     div.appendChild(a);%0A%0A     body.appendChild(div
 );%0A 

improve probing diag tool, add a clear button