var FunctionMonitor={version:"2.1",can_trace:1,functions:[],function_index:[],stack_len:20,hold_max:1,clearMetrics:function(){for(var c=FunctionMonitor.function_index.length,b=0,a;b<c;){a=FunctionMonitor.functions[FunctionMonitor.function_index[b++]];a.metrics.length=0;a.stackCount=0}},getAllMetrics:function(){for(var c=FunctionMonitor.function_index.length,a=0,b=[];a<c;)b.push(FunctionMonitor.getMetrics(FunctionMonitor.function_index[a++]));return b.join("\n")},getMetrics:function(e){var i=FunctionMonitor.functions[e],b=[],d=0,a,g,f,h,c;if(typeof i=="object"){b.push(e+":");f=i.metrics;h=f.length;for(var c="   ";d<h;d++){a=f[d];g=-1;if(a&&a.stop&&a.start)g=a.stop-a.start;b.push(c+"#"+d+" time="+g);a.valOffset>0&&b.push(c+c+"process: "+a.valOffset);a.route!=null&&a.route!="null"&&b.push(c+c+"trace = "+a.route)}}else b.push(e+" is not a registered function.");return b.join("\n")},getWindowName:function(b){var a="window",c;if(b&&b!=window){c=b;if(c.name)a=c.name;else a="frame"}return a},getIsRegistered:function(e,f,d){var g=window,b=FunctionMonitor.getWindowName(f),a="",c;if(b!="window")a=b+"-";if(d)a+=d+"--";c="dispatch-"+a+e;return typeof FunctionMonitor.functions[c]=="object"?1:0},unregisterAll:function(){for(var c=FunctionMonitor.function_index.length,a,b=c-1;b>=0;b--){a=FunctionMonitor.functions[FunctionMonitor.function_index[b]];if(!a)continue;if(a.proto)FunctionMonitor.unregister(a.name,a.window,a.proto);else FunctionMonitor.unregister(a.name,a.window)}return c},unregister:function(a,g,b){var c=window,j=FunctionMonitor.getWindowName(g),h="",e,d,k,l,f,i=0;if(g&&g!=window)c=g;if(j!="window")h=j+"-";if(b)h+=b+"--";e="dispatch-"+h+a;d=FunctionMonitor.functions[e];if(!d){alert(e+" is not a monitored function");return}k=d.index;FunctionMonitor.function_index[k]=null;if(!b&&a.indexOf(".")>-1){f=FunctionMonitor.getObject(a.substring(0,a.lastIndexOf(".")),c);if(f){i=1;f[a.substring(a.lastIndexOf(".")+1,a.length)]=d.fp}}else if(b&&b.indexOf(".")>-1){f=FunctionMonitor.getObject(b,c);if(f&&f.prototype){i=1;f.prototype[a]=d.fp}}if(!i)if(!b)if(c[a])c[a]=d.fp;else alert(a+" does not exist");else if(c[b].prototype[a])c[b].prototype[a]=d.fp;else alert(b+"."+a+" does not exist.");if(!FunctionMonitor[e]){alert(e+" does not have a monitor definition.");return}l=FunctionMonitor[e];if(c.onload==l)c.onload=d.fp;FunctionMonitor[e]=null;FunctionMonitor._pack()},_pack:function(){var f=FunctionMonitor.functions,b=FunctionMonitor.function_index,e,a=0,c,d;FunctionMonitor.functions=[];FunctionMonitor.function_index=[];e=b.length;for(;a<e;a++)if(b[a]!=null){c=FunctionMonitor.function_index.length;FunctionMonitor.function_index[c]=b[a];d=f[b[a]];d.index=c;FunctionMonitor.functions[b[a]]=d}},register:function(a,g,b){var c=window,i=FunctionMonitor.getWindowName(g),d,j="",e,h=-1,f;if(g&&g!=window)c=g;if(!b&&a.indexOf(".")>-1)d=FunctionMonitor.getObject(a,c);else if(b&&b.indexOf(".")>-1){f=FunctionMonitor.getObject(b,c);if(f&&f.prototype)d=f.prototype[a]}if(!d)if(!b)d=c[a];else{d=c[b];if(d)if(d.prototype)d=d.prototype[a];else d=d[a]}if(typeof d=="function"){if(i!="window")j=i+"-";if(b)j+=b+"--";e="dispatch-"+j+a;if(!FunctionMonitor.functions[e]){h=FunctionMonitor.function_index.length;FunctionMonitor.function_index[h]=e}else h=FunctionMonitor.functions[e].index;FunctionMonitor.functions[e]={name:a,classRef:b,refName:i,ref:c,fp:d,index:h,metrics:[],stackCount:0};eval('FunctionMonitor["'+e+'"]=function(){return FunctionMonitor.dispatch("'+e+'",this,arguments);}');var k=0;if(!b&&a.indexOf(".")>-1){f=FunctionMonitor.getObject(a.substring(0,a.lastIndexOf(".")),c);if(f){k=1;f[a.substring(a.lastIndexOf(".")+1,a.length)]=FunctionMonitor[e]}}else if(b&&b.indexOf(".")>-1){f=FunctionMonitor.getObject(b,c);if(f&&f.prototype){k=1;f.prototype[a]=FunctionMonitor[e]}}if(!k)if(!b)c[a]=FunctionMonitor[e];else if(c[b].prototype)c[b].prototype[a]=FunctionMonitor[e];else c[b][a]=FunctionMonitor[e];if(c.onload==d)c.onload=FunctionMonitor[e]}else alert(a+" is not a function")},makeMetric:function(){return{start:null,stop:null,valOffset:-1,route:null,monStatus:-1,duration:-1,caller:null,parentName:null}},dispatch:function(j,o,i){var h,b=FunctionMonitor.functions[j],g,a,e,n,p,f,m,c,d,k,l;if(!b){if(!FunctionMonitor.alert_error){FunctionMonitor.alert_error=1;alert("Error: invalid function reference: "+j)}return}g=new Date;a=FunctionMonitor.makeMetric();e=null;n=null;if(FunctionMonitor.dispatch.caller&&FunctionMonitor.dispatch.caller.caller)e=FunctionMonitor.dispatch.caller.caller;if(FunctionMonitor.can_trace){a.route=FunctionMonitor.traceRoute(e);if(a.route)a.route+="->";a.route+=b.name+FunctionMonitor.printArguments(i)}p=b.ref;f=new Date;a.start=f.getTime();if(!b.classRef)h=b.fp.apply(e,i);else h=b.fp.apply(o,i);a.monStatus=1;f=new Date;a.stop=f.getTime();m=g.getTime();g=new Date;a.valOffset=g.getTime()-m-(a.stop-a.start);c;if(FunctionMonitor.stack_len>0){if(b.stackCount>=FunctionMonitor.stack_len)b.stackCount=0;c=b.stackCount;d=b.metrics[c];if(d){k=d.stop-d.start;l=a.stop-a.start;if(k>l)a=d}b.stackCount++}else c=b.metrics.length;b.metrics[c]=a;return h},printArguments:function(f){for(var c=0,d="(",e,a,b;c<f.length;c++){if(c>0)d+=", ";e="";a=f[c];t=typeof a;b=0;switch(t){case"string":e='"';a=a.replace(/\r/gi,"\\r");a=a.replace(/\n/gi,"\\n");a=a.replace(/\t/gi,"\\t");a=a.replace(/\s+/gi," ");if(a.length>25)a=a.substring(0,17)+"... ("+a.length+")";break;case"object":if(a instanceof Array)a="{array("+a.length+")}";else if(a instanceof Date)a="{date("+a.toString()+")}";else a="{obj}";b=0;break;case"function":a="{function}";b=0}d+=e+a+e+(b?" {as "+b+"}":"")}d+=")";return d},traceRoute:function(a){var c="",d=[],f=0,b,g,e,h;if(a!=null){while(a&&a!=null){b=FunctionMonitor.getFunctionName(a.toString());if(b==null){a=null;break}d.push(b+FunctionMonitor.printArguments(a.arguments));a=a.caller}c=d.reverse().join("->")}else c="null";return c},getFunctionName:function(a){var b=a.match(/function\s([A-Za-z0-9_]*)\(/gi);if(a==null)return a;if(b!=null&&b.length){a=b[0];a=a.replace(/^function\s+/,"");a=a.replace(/^\s*/,"");a=a.replace(/\s*$/,"");a=a.replace(/\($/,"");return a}else return null},getObject:function(f,e){var c,g=0,b,h=e?e:window,a,d;a=h;if(typeof f=="string"){c=f.split(".");d=c.length;if(d==0)return 0;for(;g<d;){b=c[g++];if(typeof a[b]!="object"&&typeof a[b]!="function")return 0;a=a[b]}}else return 0;return typeof a!="function"&&typeof a!="object"?0:a}}
