<commit_before><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>webgrind</title>
	<link rel="stylesheet" type="text/css" href="styles/style.css" />
	<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.blockUI.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.tablesorter.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.selectboxes.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/sprintf.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript" charset="utf-8">
		var fileUrlFormat = '<?php echo Webgrind_Config::$fileUrlFormat?>';
		var currentDataFile = null;
		var callInfoLoaded = new Array();
		function getOptions(){
			options = new Object();
			options.dataFile = $("#dataFile").val();
			options.costFormat = $('#costFormat').val();
			options.showFraction = $("#showFraction").val();
			options.hideInternals = $('#hideInternals').attr('checked') ? 1 : 0;
			return options;
		}
		
		function update(){
			vars = getOptions();
			vars.op = 'function_list';
			$.getJSON("index.php",
				vars,
				function(data){
					callInfoLoaded = new Array();
					$("#function_table tbody").empty();
					for(i=0;i<data.functions.length;i++){
						callInfoLoaded[data.functions[i].nr] = false;
						$("#function_table tbody").append(functionTableRow(data.functions[i]));
					}
					currentDataFile = data.dataFile;
					$("#data_file").html(data.dataFile);
					$("#invoke_url").html(data.invokeUrl);
					$("#mtime").html(data.mtime);
					$("#shown_sum").html(data.functions.length);
					$("#invocation_sum").html(data.summedInvocationCount);
					$("#runtime_sum").html(data.summedRunTime);
					
					var breakdown_sum = data.breakdown['internal']+data.breakdown['user']+data.breakdown['class']+data.breakdown['include'];
                    $("#breakdown").html(
                        '<img src="img/gradient_left.png" height="20" width="10">'+
                        '<img src="img/gradient_blue.png" height="20" width="'+Math.floor(data.breakdown['internal']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_grey.png" height="20" width="'+Math.floor(data.breakdown['include']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_green.png" height="20" width="'+Math.floor(data.breakdown['class']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_orange.png" height="20" width="'+Math.floor(data.breakdown['user']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_right.png" height="20" width="10">'+
                        '<div title="blue: internal functions\ngrey: include/require\ngreen: class methods\norange: procedural functions" style="background:url(img/gradient_markers.png);position:relative;top:-20px;left:10px;width:301px;height:19px"></div>'
                    );
					
					$("#hello_message").hide();
					$("#trace_view").show();
					
					$("#function_table").trigger('update');
					$("#function_table").trigger("sorton",[[[3,1]]]); 
				}
			);
		}
		
		function reloadFilelist(){
			$.getJSON("index.php",
				{'op':'file_list'},
				function(data){
					options = new Object();
					for(i=0;i<data.length;i++){
						options[data[i]['filename']] = data[i]['invokeUrl']+' ('+data[i]['filename']+')';
					}
					$("#dataFile").removeOption(/[^0]/);
					$("#dataFile").addOption(options, false);

				}
			);
		}
		
		function loadCallInfo(functionNr){			
			$.getJSON("index.php",
				{'op':'callinfo_list', 'file':currentDataFile, 'functionNr':functionNr, 'costFormat':$("#costFormat").val()},
				function(data){
					
					if(data.calledByHost)
						$("#callinfo_area_"+functionNr).append('<b>Called from script host</b>');
					
					insertCallInfo(functionNr, 'sub_calls_table_', 'Calls', data.subCalls);
					insertCallInfo(functionNr, 'called_from_table_', 'Called From', data.calledFrom);

					
					callInfoLoaded[functionNr] = true;
				}
			);				
		
		}
		
		function insertCallInfo(functionNr, idPrefix, title, data){
			if(data.length==0)
				return;
				
			$("#callinfo_area_"+functionNr).append(callTable(functionNr,idPrefix, title));
			
			for(i=0;i<data.length;i++){
				$("#"+idPrefix+functionNr+" tbody").append(callTableRow(i, data[i]));
			}
			
			$("#"+idPrefix+functionNr).tablesorter({
				widgets: ['zebra'],
				headers: { 
		            3: { 
		                sorter: false 
		            }
		        }							
			});
			$("#"+idPrefix+functionNr).bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
			$("#"+idPrefix+functionNr).trigger("sorton",[[[2,1]]]); 				
				
			
		}
		
		function callTable(functionNr, idPrefix, title){
			return '<table class="tablesorter" id="'+idPrefix+functionNr+'" cellspacing="0"> \
						<thead><tr><th><span>'+title+'</span></th><th><span>Count</span></th><th><span>Total Call Cost</span></th><th> </th></tr></thead> \
						<tbody> \
						</tbody> \
					</table> \
			';
		}
		
		function callTableRow(nr,data){
			return '<tr> \
						<td>'+data.callerFunctionName+' @ '+data.line+'</td> \
						<td class="nr">'+data.callCount+'</td> \
						<td class="nr">'+data.summedCallCost+'</td> \
						<td><a title="Open file and show line" href="'+sprintf(fileUrlFormat,data.callerFile,data.line)+'" target="_blank"><img src="img/file_line.png" alt="O"/></a></td> \
					</tr>';
			
		}
				
		function toggleCallInfo(functionNr){
			if(!callInfoLoaded[functionNr]){
				loadCallInfo(functionNr);
			}					
			
			$("#callinfo_area_"+functionNr).toggle();
			current = $("#fold_marker_"+functionNr).get(0).src;
			if(current.substr(current.lastIndexOf('/')+1) == 'right.gif')
				$("#fold_marker_"+functionNr).get(0).src = 'img/down.gif';
			else
				$("#fold_marker_"+functionNr).get(0).src = 'img/right.gif';
		}
		
		function functionTableRow(data){
			openLink = (data.file=='php:internal')?'':'<a title="Open file" href="'+sprintf(fileUrlFormat,data.file,-1)+'" target="_blank"><img src="img/file.png" alt="O"/></a>';
			return '<tr> \
						<td> \
						    <img src="img/call_'+data.kind+'.png" /> \
							<a href="javascript:toggleCallInfo('+data.nr+')"> \
								<img id="fold_marker_'+data.nr+'" src="img/right.gif" />&nbsp;&nbsp;'+data.functionName+' \
							</a> \
							<div class="callinfo_area" id="callinfo_area_'+data.nr+'"></div> \
						</td> \
						<td>'+openLink+'</td> \
						<td class="nr">'+data.invocationCount+'</td> \
						<td class="nr">'+data.summedSelfCost+'</td> \
						<td class="nr">'+data.summedInclusiveCost+'</td> \
					</tr> \
			';
		}
		
		function sortBlock(){
			$.blockUI('<div class="block_box"><h1>Sorting...</h1></div>');
		}
		
		
		$(document).ready(function() { 
			$.blockUI.defaults.pageMessage = '<div class="block_box"><h1>Loading...</h1><p>Loading information from server. If the callgrind file is large this may take some time.</p></div>';
			$.blockUI.defaults.overlayCSS =  { backgroundColor: '#fff', opacity: '0' }; 
			$.blockUI.defaults.fadeIn = 0;
			$.blockUI.defaults.fadeOut = 0;
			$().ajaxStart($.blockUI).ajaxStop($.unblockUI);
			$("#function_table").tablesorter({
				widgets: ['zebra'],
				sortInitialOrder: 'desc',
				headers: { 
		            1: { 
		                sorter: false 
		            }
		        }
			});
			$("#function_table").bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
			
			if(document.location.hash) {
				update(document.location.hash.substr(1));
			}
		});
		
	</script>
</head>
<body>
<div id="head">
    <h1>webgrind<sup style="font-size:10px">v0.6</sup></h1>
    <p>profiling in the browser</p>
</div>
<div id="options">
    <form method="get" onsubmit="update();return false">
    	<div style="float:right;margin-left:10px">
    	    <input type="submit" value="update" />
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">in</label>
    		<select id="costFormat" name="costFormat">
    		    <option value="percent" <?php echo (Webgrind_Config::$defaultCostformat=='percent') ? 'selected' : ''?>>percent</option>
    		    <option value="msec" <?php echo (Webgrind_Config::$defaultCostformat=='msec') ? 'selected' : ''?>>milliseconds</option>
    		    <option value="usec" <?php echo (Webgrind_Config::$defaultCostformat=='usec') ? 'selected' : ''?>>microseconds</option>
    		</select>
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">of</label>
    		<select id="dataFile" name="dataFile" style="width:200px">
    			<option value="0">Auto (newest)</option>
    			<?php foreach(Webgrind_FileHandler::getInstance()->getTraceList() as $trace):?>
    				<option value="<?php echo $trace['filename']?>"><?php echo $trace['invokeUrl']?> (<?php echo $trace['filename']?>)</option>
    			<?php endforeach;?>
    		</select>
			<img class="list_reload" src="img/reload.gif" onclick="reloadFilelist()"/>
    	</div>
    	<div style="float:right">
    		<label style="margin:0 5px">Show</label>
    		<select id="showFraction" name="showFraction">
    			<?php for($i=100; $i>0; $i-=10):?>
    			<option value="<?php echo $i/100?>" <?php if ($i==Webgrind_Config::$defaultFunctionPercentage):?>selected="selected"<?php endif;?>><?php echo $i?>%</option>
    			<?php endfor;?>
    		</select>
    	</div>
    	<div style="clear:both;"></div>    	
    	<div style="margin:0 45px">
    	    <input type="checkbox" name="hideInternals" value="1" <?php echo (Webgrind_Config::$defaultHideInternalFunctions==1) ? 'checked' : ''?> id="hideInternals">
    	    <label for="hideInternals">Hide PHP functions</label>
    	</div>
    </form>
</div>
<div style="clear:both;"></div>
<div class="hr"></div>
<div id="trace_view">
	<div style="float:left;">
	    <h2 id="invoke_url"></h2>
	    <span id="data_file"></span> @ <span id="mtime"></span>
	</div>
	<div style="float:right;">
	    <div id="breakdown" style="margin-bottom:5px;width:320px;height:20px">
	    </div><commit_msg>- Version bump and minor corrections<commit_after><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
	<title>webgrind</title>
	<link rel="stylesheet" type="text/css" href="styles/style.css" />
	<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.blockUI.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.tablesorter.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/jquery.selectboxes.js" type="text/javascript" charset="utf-8"></script>
	<script src="js/sprintf.js" type="text/javascript" charset="utf-8"></script>
	<script type="text/javascript" charset="utf-8">
		var fileUrlFormat = '<?php echo Webgrind_Config::$fileUrlFormat?>';
		var currentDataFile = null;
		var callInfoLoaded = new Array();
		function getOptions(){
			options = new Object();
			options.dataFile = $("#dataFile").val();
			options.costFormat = $('#costFormat').val();
			options.showFraction = $("#showFraction").val();
			options.hideInternals = $('#hideInternals').attr('checked') ? 1 : 0;
			return options;
		}
		
		function update(){
			vars = getOptions();
			vars.op = 'function_list';
			$.getJSON("index.php",
				vars,
				function(data){
					callInfoLoaded = new Array();
					$("#function_table tbody").empty();
					for(i=0;i<data.functions.length;i++){
						callInfoLoaded[data.functions[i].nr] = false;
						$("#function_table tbody").append(functionTableRow(data.functions[i]));
					}
					currentDataFile = data.dataFile;
					$("#data_file").html(data.dataFile);
					$("#invoke_url").html(data.invokeUrl);
					$("#mtime").html(data.mtime);
					$("#shown_sum").html(data.functions.length);
					$("#invocation_sum").html(data.summedInvocationCount);
					$("#runtime_sum").html(data.summedRunTime);
					
					var breakdown_sum = data.breakdown['internal']+data.breakdown['user']+data.breakdown['class']+data.breakdown['include'];
                    $("#breakdown").html(
                        '<img src="img/gradient_left.png" height="20" width="10">'+
                        '<img src="img/gradient_blue.png" height="20" width="'+Math.floor(data.breakdown['internal']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_grey.png" height="20" width="'+Math.floor(data.breakdown['include']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_green.png" height="20" width="'+Math.floor(data.breakdown['class']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_orange.png" height="20" width="'+Math.floor(data.breakdown['user']/breakdown_sum*300)+'">'+
                        '<img src="img/gradient_right.png" height="20" width="10">'+
                        '<div title="blue: internal functions\ngrey: include/require\ngreen: class methods\norange: procedural functions" style="background:url(img/gradient_markers.png);position:relative;top:-20px;left:10px;width:301px;height:19px"></div>'
                    );
					
					$("#hello_message").hide();
					$("#trace_view").show();
					
					$("#function_table").trigger('update');
					$("#function_table").trigger("sorton",[[[3,1]]]); 
				}
			);
		}
		
		function reloadFilelist(){
			$.getJSON("index.php",
				{'op':'file_list'},
				function(data){
					options = new Object();
					for(i=0;i<data.length;i++){
						options[data[i]['filename']] = data[i]['invokeUrl']+' ('+data[i]['filename']+')';
					}
					$("#dataFile").removeOption(/[^0]/);
					$("#dataFile").addOption(options, false);

				}
			);
		}
		
		function loadCallInfo(functionNr){			
			$.getJSON("index.php",
				{'op':'callinfo_list', 'file':currentDataFile, 'functionNr':functionNr, 'costFormat':$("#costFormat").val()},
				function(data){
					
					if(data.calledByHost)
						$("#callinfo_area_"+functionNr).append('<b>Called from script host</b>');
					
					insertCallInfo(functionNr, 'sub_calls_table_', 'Calls', data.subCalls);
					insertCallInfo(functionNr, 'called_from_table_', 'Called From', data.calledFrom);

					
					callInfoLoaded[functionNr] = true;
				}
			);				
		
		}
		
		function insertCallInfo(functionNr, idPrefix, title, data){
			if(data.length==0)
				return;
				
			$("#callinfo_area_"+functionNr).append(callTable(functionNr,idPrefix, title));
			
			for(i=0;i<data.length;i++){
				$("#"+idPrefix+functionNr+" tbody").append(callTableRow(i, data[i]));
			}
			
			$("#"+idPrefix+functionNr).tablesorter({
				widgets: ['zebra'],
				headers: { 
		            3: { 
		                sorter: false 
		            }
		        }							
			});
			$("#"+idPrefix+functionNr).bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
			$("#"+idPrefix+functionNr).trigger("sorton",[[[2,1]]]); 				
				
			
		}
		
		function callTable(functionNr, idPrefix, title){
			return '<table class="tablesorter" id="'+idPrefix+functionNr+'" cellspacing="0"> \
						<thead><tr><th><span>'+title+'</span></th><th><span>Count</span></th><th><span>Total Call Cost</span></th><th> </th></tr></thead> \
						<tbody> \
						</tbody> \
					</table> \
			';
		}
		
		function callTableRow(nr,data){
			return '<tr> \
						<td>'+data.callerFunctionName+' @ '+data.line+'</td> \
						<td class="nr">'+data.callCount+'</td> \
						<td class="nr">'+data.summedCallCost+'</td> \
						<td><a title="Open file and show line" href="'+sprintf(fileUrlFormat,data.callerFile,data.line)+'" target="_blank"><img src="img/file_line.png" alt="O"/></a></td> \
					</tr>';
			
		}
				
		function toggleCallInfo(functionNr){
			if(!callInfoLoaded[functionNr]){
				loadCallInfo(functionNr);
			}					
			
			$("#callinfo_area_"+functionNr).toggle();
			current = $("#fold_marker_"+functionNr).get(0).src;
			if(current.substr(current.lastIndexOf('/')+1) == 'right.gif')
				$("#fold_marker_"+functionNr).get(0).src = 'img/down.gif';
			else
				$("#fold_marker_"+functionNr).get(0).src = 'img/right.gif';
		}
		
		function functionTableRow(data){
			openLink = (data.file=='php:internal')?'':'<a title="Open file" href="'+sprintf(fileUrlFormat,data.file,-1)+'" target="_blank"><img src="img/file.png" alt="O"/></a>';
			return '<tr> \
						<td> \
						    <img src="img/call_'+data.kind+'.png" /> \
							<a href="javascript:toggleCallInfo('+data.nr+')"> \
								<img id="fold_marker_'+data.nr+'" src="img/right.gif" />&nbsp;&nbsp;'+data.functionName+' \
							</a> \
							<div class="callinfo_area" id="callinfo_area_'+data.nr+'"></div> \
						</td> \
						<td>'+openLink+'</td> \
						<td class="nr">'+data.invocationCount+'</td> \
						<td class="nr">'+data.summedSelfCost+'</td> \
						<td class="nr">'+data.summedInclusiveCost+'</td> \
					</tr> \
			';
		}
		
		function sortBlock(){
			$.blockUI('<div class="block_box"><h1>Sorting...</h1></div>');
		}
		
		
		$(document).ready(function() { 
			$.blockUI.defaults.pageMessage = '<div class="block_box"><h1>Loading...</h1><p>Loading information from server. If the callgrind file is large this may take some time.</p></div>';
			$.blockUI.defaults.overlayCSS =  { backgroundColor: '#fff', opacity: '0' }; 
			$.blockUI.defaults.fadeIn = 0;
			$.blockUI.defaults.fadeOut = 0;
			$().ajaxStart($.blockUI).ajaxStop($.unblockUI);
			$("#function_table").tablesorter({
				widgets: ['zebra'],
				sortInitialOrder: 'desc',
				headers: { 
		            1: { 
		                sorter: false 
		            }
		        }
			});
			$("#function_table").bind("sortStart",sortBlock).bind("sortEnd",$.unblockUI);
			
			if(document.location.hash) {
				update(document.location.hash.substr(1));
			}
		});
		
	</script>
</head>
<body>
<div id="head">
    <h1>webgrind<sup style="font-size:10px">v0.7</sup></h1>
    <p>profiling in the browser</p>
</div>
<div id="options">
    <form method="get" onsubmit="update();return false">
    	<div style="float:right;margin-left:10px">
    	    <input type="submit" value="update" />
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">in</label>
    		<select id="costFormat" name="costFormat">
    		    <option value="percent" <?php echo (Webgrind_Config::$defaultCostformat=='percent') ? 'selected' : ''?>>percent</option>
    		    <option value="msec" <?php echo (Webgrind_Config::$defaultCostformat=='msec') ? 'selected' : ''?>>milliseconds</option>
    		    <option value="usec" <?php echo (Webgrind_Config::$defaultCostformat=='usec') ? 'selected' : ''?>>microseconds</option>
    		</select>
    	</div>
    	<div style="float:right;">
    		<label style="margin:0 5px">of</label>
    		<select id="dataFile" name="dataFile" style="width:200px">
    			<option value="0">Auto (newest)</option>
    			<?php foreach(Webgrind_FileHandler::getInstance()->getTraceList() as $trace):?>
    				<option value="<?php echo $trace['filename']?>"><?php echo $trace['invokeUrl']?> (<?php echo $trace['filename']?>)</option>
    			<?php endforeach;?>
    		</select>
			<img class="list_reload" src="img/reload.gif" onclick="reloadFilelist()"/>
    	</div>
    	<div style="float:right">
    		<label style="margin:0 5px">Show</label>
    		<select id="showFraction" name="showFraction">
    			<?php for($i=100; $i>0; $i-=10):?>
    			<option value="<?php echo $i/100?>" <?php if ($i==Webgrind_Config::$defaultFunctionPercentage):?>selected="selected"<?php endif;?>><?php echo $i?>%</option>
    			<?php endfor;?>
    		</select>
    	</div>
    	<div style="clear:both;"></div>    	
    	<div style="margin:0 70px">
    	    <input type="checkbox" name="hideInternals" value="1" <?php echo (Webgrind_Config::$defaultHideInternalFunctions==1) ? 'checked' : ''?> id="hideInternals">
    	    <label for="hideInternals">Hide PHP functions</label>
    	</div>
    </form>
</div>
<div style="clear:both;"></div>
<div class="hr"></div>
<div id="trace_view">
	<div style="float:left;">
	    <h2 id="invoke_url"></h2>
	    <span id="data_file"></span> @ <span id="mtime"></span>
	</div>
	<div style="float:right;">
	    <div id="breakdown" style="margin-bottom:5px;width:320px;height:20px"></div>
{'fraction_non_alphanumeric': 0.21467404613802224, 'fraction_numerical': 0.011950825292648284, 'mean_word_length': 3.6079891672308735, 'pattern_counts': {'":': 0, '<': 373, '<?xml version=': 0, '>': 371, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3268566', 'n_tokens_mistral': 8155, 'n_tokens_neox': 6954, 'n_words': 977}