<commit_before><!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fishybox Log Analyzer/Viewer</title>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<style>
tr.undo_row {
  display: none;  /* default, will be overridden to display */
  color: #999999;
  background: #eeeeee;
}
td.actionbuttons {
  white-space: nowrap;  /* keep all buttons on one line */
}
input#rowfilter {
  font-weight: normal;
  margin-left: 2em;
  padding: 0 0.5em;
  border-radius: 10em;
  border: solid 1px #ccc;
  box-shadow: 1px 1px 2px 1px #ccc;
}
span#filterclear {
  position: relative;
  left: -1.2em;
  top: -0.1em;
  color: #999;
  cursor: pointer;
}
th.points_cell, td.points_cell {
  text-align: right;
}
body {
  overflow-y: scroll;  /* Scroll bar always present -- avoids bouncing on hide/show of rows */
}
svg.aml_chart {
  height: 1em;
  width: 4em;
}
</style>
<script type="text/javascript">
function do_post(url, query, check) {
  if (check) {
    var go = confirm("Are you sure?  (" + check + ")");
    if (! go) return;
  }
  var form = document.createElement('form');
  form.setAttribute('method', 'post');
  form.setAttribute('action', url + "?" + query);
  form.style.display = 'hidden';
  document.body.appendChild(form)
    form.submit();
}
function async_post(url, query) {
  $.post(url + "?" + query);
}

function filter_rows(value) {
  var re = new RegExp(value);
  $("tr.log_row").each(function() {
    logfile = $(this).find(".logfile_cell").text();
    if (re.test(logfile)) {
      $(this).show();
    }
    else {
      $(this).hide();
    }
  });
  update_selection();
}

// setup handlers / onload stuff
$(function() {
  $("#filterclear").click(function(e) {
    $("#rowfilter").val('');
    $("#rowfilter").trigger('input');
  });
  $("#rowfilter").on('input', function(e) {
    filter_rows(this.value);
  });
  $("#selectallbutton").click(toggle_select_all);
  $("tr.log_row .selectbutton").click(function(e) {
    var row = $(this).closest("tr");
    togglesel(row);
  });
  makeCharts();
});

function makeCharts() {
  $("svg.aml_chart").each(function() {
    var s = Snap(this);
    var data = $(this).data("values").split('|');
    var acquired = parseFloat(data[0]);
    var missing = parseFloat(data[1]);
    var lost = parseFloat(data[2]);
    var a = acquired*100;
    var b = missing*100;
    var c = lost*100;
    s.rect(0,0,a,20).attr({fill: '#0d0'});
    s.rect(a,0,b,20).attr({fill: '#fc0'});
    s.rect(a+b,0,c,20).attr({fill: '#d00'});
  });
}

// keep track of selected tracks
var selection = Object.create(null);  // an empty object to be used as a set
function sel_count() {
  return Object.keys(selection).length;
}
function togglesel(row) {
  var sel_button = $(row).find(".selectbutton");
  sel_button.toggleClass('btn-primary');
  update_selection();
}
function toggle_select_all() {
  var log_rows = $("tr.log_row").filter(":visible");
  var row_count = log_rows.length;
  var notall = (sel_count() < row_count);
  log_rows.each(function() {
    var sel_button = $(this).find(".selectbutton");
    if (notall != sel_button.hasClass('btn-primary')) {
      togglesel(this);
    }
  });
}
function update_selection() {<commit_msg>Fix tooltip over SVG in Chrome.<commit_after><!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fishybox Log Analyzer/Viewer</title>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<style>
tr.undo_row {
  display: none;  /* default, will be overridden to display */
  color: #999999;
  background: #eeeeee;
}
td.actionbuttons {
  white-space: nowrap;  /* keep all buttons on one line */
}
input#rowfilter {
  font-weight: normal;
  margin-left: 2em;
  padding: 0 0.5em;
  border-radius: 10em;
  border: solid 1px #ccc;
  box-shadow: 1px 1px 2px 1px #ccc;
}
span#filterclear {
  position: relative;
  left: -1.2em;
  top: -0.1em;
  color: #999;
  cursor: pointer;
}
th.points_cell, td.points_cell {
  text-align: right;
}
body {
  overflow-y: scroll;  /* Scroll bar always present -- avoids bouncing on hide/show of rows */
}
svg.aml_chart {
  height: 1em;
  width: 4em;
}
</style>
<script type="text/javascript">
function do_post(url, query, check) {
  if (check) {
    var go = confirm("Are you sure?  (" + check + ")");
    if (! go) return;
  }
  var form = document.createElement('form');
  form.setAttribute('method', 'post');
  form.setAttribute('action', url + "?" + query);
  form.style.display = 'hidden';
  document.body.appendChild(form)
    form.submit();
}
function async_post(url, query) {
  $.post(url + "?" + query);
}

function filter_rows(value) {
  var re = new RegExp(value);
  $("tr.log_row").each(function() {
    logfile = $(this).find(".logfile_cell").text();
    if (re.test(logfile)) {
      $(this).show();
    }
    else {
      $(this).hide();
    }
  });
  update_selection();
}

// setup handlers / onload stuff
$(function() {
  $("#filterclear").click(function(e) {
    $("#rowfilter").val('');
    $("#rowfilter").trigger('input');
  });
  $("#rowfilter").on('input', function(e) {
    filter_rows(this.value);
  });
  $("#selectallbutton").click(toggle_select_all);
  $("tr.log_row .selectbutton").click(function(e) {
    var row = $(this).closest("tr");
    togglesel(row);
  });
  makeCharts();
});

function makeCharts() {
  $("svg.aml_chart").each(function() {
    var data = $(this).data("values").split('|');
    var acquired = parseFloat(data[0]);
    var missing = parseFloat(data[1]);
    var lost = parseFloat(data[2]);
    var a = acquired*100;
    var b = missing*100;
    var c = lost*100;

    var s = Snap(this);
    s.group(
      // Chrome requires the title tag to be in a group with the graphics
      // elements (not just part of the <svg> itself) to display it as a tooltip.
      Snap.parse("<title>" + this.getAttribute('title') + "</title>"),
      s.rect(0,0,a,20).attr({fill: '#0d0'}),
      s.rect(a,0,b,20).attr({fill: '#fc0'}),
      s.rect(a+b,0,c,20).attr({fill: '#d00'})
    );
  });
}

// keep track of selected tracks
var selection = Object.create(null);  // an empty object to be used as a set
function sel_count() {
  return Object.keys(selection).length;
}
function togglesel(row) {
  var sel_button = $(row).find(".selectbutton");
  sel_button.toggleClass('btn-primary');
  update_selection();
}
function toggle_select_all() {
  var log_rows = $("tr.log_row").filter(":visible");
  var row_count = log_rows.length;
  var notall = (sel_count() < row_count);
  log_rows.each(function() {
    var sel_button = $(this).find(".selectbutton");
    if (notall != sel_button.hasClass('btn-primary')) {
      togglesel(this);
    }
  });
}
function update_selection() {
{'fraction_non_alphanumeric': 0.19428491385348087, 'fraction_numerical': 0.017929682028295278, 'mean_word_length': 3.7695390781563125, 'pattern_counts': {'":': 2, '<': 36, '<?xml version=': 0, '>': 34, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '4463408', 'n_tokens_mistral': 2634, 'n_tokens_neox': 2561, 'n_words': 528}