Buckets:

glennmatlin's picture
download
raw
11.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SocialIQA Classification Audit Viewer</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace; background: #0d1117; color: #c9d1d9; padding: 16px; }
h1 { font-size: 18px; margin-bottom: 12px; color: #e6edf3; }
.controls { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center; }
.controls select, .controls input { background: #161b22; border: 1px solid #30363d; color: #c9d1d9; padding: 6px 10px; border-radius: 4px; font-size: 13px; }
.controls input[type="text"] { width: 220px; }
.controls select { min-width: 140px; }
.drop-zone { border: 2px dashed #30363d; border-radius: 8px; padding: 32px; text-align: center; margin-bottom: 16px; cursor: pointer; transition: border-color 0.2s; }
.drop-zone:hover, .drop-zone.over { border-color: #58a6ff; }
.drop-zone input { display: none; }
.stats { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
.stat { background: #161b22; border: 1px solid #30363d; border-radius: 6px; padding: 10px 14px; }
.stat .n { font-size: 22px; font-weight: 600; color: #e6edf3; }
.stat .lbl { font-size: 11px; color: #8b949e; text-transform: uppercase; letter-spacing: 0.5px; }
table { width: 100%; border-collapse: collapse; font-size: 12px; table-layout: fixed; }
thead th { background: #161b22; position: sticky; top: 0; padding: 8px 6px; text-align: left; border-bottom: 1px solid #30363d; cursor: pointer; white-space: nowrap; }
thead th:hover { color: #58a6ff; }
tbody td { padding: 6px; border-bottom: 1px solid #21262d; vertical-align: top; word-wrap: break-word; overflow-wrap: break-word; }
tbody tr:hover { background: #161b22; }
tr.agree-yes td:first-child { border-left: 3px solid #3fb950; }
tr.agree-no td:first-child { border-left: 3px solid #f85149; }
tr.agree-nr td:first-child { border-left: 3px solid #30363d; }
.page-controls { margin-top: 12px; display: flex; gap: 8px; align-items: center; justify-content: center; }
.page-controls button { background: #21262d; border: 1px solid #30363d; color: #c9d1d9; padding: 6px 14px; border-radius: 4px; cursor: pointer; }
.page-controls button:hover { background: #30363d; }
.page-controls button:disabled { opacity: 0.4; cursor: default; }
.method-badge { display: inline-block; padding: 2px 6px; border-radius: 3px; font-size: 11px; font-weight: 500; }
.method-badge.o_pattern { background: #1f6feb33; color: #58a6ff; }
.method-badge.x_pattern { background: #23863633; color: #3fb950; }
.method-badge.x_to_o_disambiguation { background: #a371f733; color: #bc8cff; }
.method-badge.manual_override { background: #d2992233; color: #d29922; }
.method-badge.verified_correction { background: #f8514933; color: #f85149; }
.method-badge.verified_correction_by_text { background: #f8514933; color: #f85149; }
.hidden { display: none; }
col.c-id { width: 110px; } col.c-ctx { width: 22%; } col.c-q { width: 20%; }
col.c-label { width: 70px; } col.c-method { width: 150px; } col.c-pattern { width: 14%; }
col.c-actor { width: 60px; } col.c-subj { width: 60px; } col.c-xo { width: 40px; }
col.c-sonnet { width: 70px; } col.c-agree { width: 65px; }
</style>
</head>
<body>
<h1>SocialIQA ATOMIC Reasoning Type — Classification Audit</h1>
<div id="dropZone" class="drop-zone">
Drop <code>socialiqa_classification_audit.csv</code> here or <label style="color:#58a6ff;cursor:pointer">browse<input type="file" id="fileInput" accept=".csv"></label>
</div>
<div id="app" class="hidden">
<div class="stats" id="stats"></div>
<div class="controls">
<select id="fLabel"><option value="">All labels</option></select>
<select id="fMethod"><option value="">All methods</option></select>
<select id="fAgree"><option value="">All agreement</option></select>
<input type="text" id="fSearch" placeholder="Search question text...">
<span id="countDisplay" style="color:#8b949e;font-size:13px"></span>
</div>
<div style="overflow-x:auto">
<table>
<colgroup>
<col class="c-id"><col class="c-ctx"><col class="c-q"><col class="c-label">
<col class="c-method"><col class="c-pattern"><col class="c-actor"><col class="c-subj">
<col class="c-xo"><col class="c-sonnet"><col class="c-agree">
</colgroup>
<thead><tr>
<th data-col="query_id">query_id</th>
<th data-col="context">context</th>
<th data-col="question_sentence">question</th>
<th data-col="final_label">label</th>
<th data-col="classification_method">method</th>
<th data-col="pattern_matched">pattern</th>
<th data-col="context_actor">actor</th>
<th data-col="question_subject">subject</th>
<th data-col="x_to_o_applied">x→o</th>
<th data-col="sonnet_label">sonnet</th>
<th data-col="sonnet_agrees">agrees</th>
</tr></thead>
<tbody id="tbody"></tbody>
</table>
</div>
<div class="page-controls">
<button id="prevBtn" onclick="changePage(-1)">Prev</button>
<span id="pageInfo"></span>
<button id="nextBtn" onclick="changePage(1)">Next</button>
</div>
</div>
<script>
let allRows = [], filtered = [], page = 0;
const PER_PAGE = 100;
function parseCSV(text) {
const lines = text.split('\n').filter(l => l.trim());
const headers = parseCSVLine(lines[0]);
return lines.slice(1).map(line => {
const vals = parseCSVLine(line);
const obj = {};
headers.forEach((h, i) => obj[h] = vals[i] || '');
return obj;
});
}
function parseCSVLine(line) {
const result = []; let current = '', inQuotes = false;
for (let i = 0; i < line.length; i++) {
const ch = line[i];
if (inQuotes) {
if (ch === '"' && line[i+1] === '"') { current += '"'; i++; }
else if (ch === '"') { inQuotes = false; }
else { current += ch; }
} else {
if (ch === '"') { inQuotes = true; }
else if (ch === ',') { result.push(current); current = ''; }
else { current += ch; }
}
}
result.push(current);
return result;
}
function loadData(rows) {
allRows = rows;
const labels = [...new Set(rows.map(r => r.final_label))].sort();
const methods = [...new Set(rows.map(r => r.classification_method))].sort();
const agrees = [...new Set(rows.map(r => r.sonnet_agrees))].sort();
populateSelect('fLabel', labels);
populateSelect('fMethod', methods);
populateSelect('fAgree', agrees);
updateStats();
applyFilters();
document.getElementById('dropZone').classList.add('hidden');
document.getElementById('app').classList.remove('hidden');
}
function populateSelect(id, values) {
const sel = document.getElementById(id);
values.forEach(v => { const o = document.createElement('option'); o.value = v; o.textContent = v || '(empty)'; sel.appendChild(o); });
}
function updateStats() {
const s = document.getElementById('stats');
const methodCounts = {};
allRows.forEach(r => { methodCounts[r.classification_method] = (methodCounts[r.classification_method] || 0) + 1; });
const agreeCounts = {};
allRows.forEach(r => { agreeCounts[r.sonnet_agrees] = (agreeCounts[r.sonnet_agrees] || 0) + 1; });
s.innerHTML = `
<div class="stat"><div class="n">${allRows.length.toLocaleString()}</div><div class="lbl">Total</div></div>
<div class="stat"><div class="n">${methodCounts['x_pattern'] || 0}</div><div class="lbl">x_pattern</div></div>
<div class="stat"><div class="n">${methodCounts['x_to_o_disambiguation'] || 0}</div><div class="lbl">x→o disambig</div></div>
<div class="stat"><div class="n">${methodCounts['o_pattern'] || 0}</div><div class="lbl">o_pattern</div></div>
<div class="stat"><div class="n">${(methodCounts['verified_correction'] || 0) + (methodCounts['verified_correction_by_text'] || 0) + (methodCounts['manual_override'] || 0)}</div><div class="lbl">Overrides</div></div>
<div class="stat"><div class="n">${agreeCounts['yes'] || 0}</div><div class="lbl">Sonnet agrees</div></div>
<div class="stat"><div class="n">${agreeCounts['no'] || 0}</div><div class="lbl">Sonnet disagrees</div></div>
`;
}
function applyFilters() {
const label = document.getElementById('fLabel').value;
const method = document.getElementById('fMethod').value;
const agree = document.getElementById('fAgree').value;
const search = document.getElementById('fSearch').value.toLowerCase();
filtered = allRows.filter(r =>
(!label || r.final_label === label) &&
(!method || r.classification_method === method) &&
(!agree || r.sonnet_agrees === agree) &&
(!search || r.context.toLowerCase().includes(search) || r.question_sentence.toLowerCase().includes(search))
);
page = 0;
document.getElementById('countDisplay').textContent = `${filtered.length.toLocaleString()} rows`;
render();
}
function render() {
const tbody = document.getElementById('tbody');
const start = page * PER_PAGE;
const slice = filtered.slice(start, start + PER_PAGE);
tbody.innerHTML = slice.map(r => {
const cls = r.sonnet_agrees === 'yes' ? 'agree-yes' : r.sonnet_agrees === 'no' ? 'agree-no' : 'agree-nr';
const mCls = r.classification_method.replace(/ /g, '_');
return `<tr class="${cls}">
<td>${esc(r.query_id)}</td>
<td>${esc(r.context)}</td>
<td>${esc(r.question_sentence)}</td>
<td><strong>${esc(r.final_label)}</strong></td>
<td><span class="method-badge ${mCls}">${esc(r.classification_method)}</span></td>
<td>${esc(r.pattern_matched)}</td>
<td>${esc(r.context_actor)}</td>
<td>${esc(r.question_subject)}</td>
<td>${r.x_to_o_applied === 'True' ? 'yes' : ''}</td>
<td>${esc(r.sonnet_label)}</td>
<td>${esc(r.sonnet_agrees)}</td>
</tr>`;
}).join('');
const totalPages = Math.ceil(filtered.length / PER_PAGE);
document.getElementById('pageInfo').textContent = `Page ${page + 1} of ${totalPages}`;
document.getElementById('prevBtn').disabled = page === 0;
document.getElementById('nextBtn').disabled = page >= totalPages - 1;
}
function changePage(delta) { page += delta; render(); }
function esc(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
['fLabel', 'fMethod', 'fAgree'].forEach(id => document.getElementById(id).addEventListener('change', applyFilters));
document.getElementById('fSearch').addEventListener('input', applyFilters);
const dropZone = document.getElementById('dropZone');
dropZone.addEventListener('dragover', e => { e.preventDefault(); dropZone.classList.add('over'); });
dropZone.addEventListener('dragleave', () => dropZone.classList.remove('over'));
dropZone.addEventListener('drop', e => { e.preventDefault(); dropZone.classList.remove('over'); handleFile(e.dataTransfer.files[0]); });
document.getElementById('fileInput').addEventListener('change', e => handleFile(e.target.files[0]));
function handleFile(file) {
if (!file) return;
const reader = new FileReader();
reader.onload = e => loadData(parseCSV(e.target.result));
reader.readAsText(file);
}
document.querySelectorAll('thead th').forEach(th => {
th.addEventListener('click', () => {
const col = th.dataset.col;
filtered.sort((a, b) => a[col].localeCompare(b[col]));
page = 0; render();
});
});
</script>
</body>
</html>

Xet Storage Details

Size:
11.2 kB
·
Xet hash:
cca0c1b0dcd0f84fd1b7fe4beb5f42fb011e4b15b8007dbce2928707d87d8124

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.