File size: 4,389 Bytes
1208309
 
 
 
 
 
 
6aab158
1208309
 
 
 
 
 
 
 
 
 
 
 
 
6aab158
1208309
6aab158
1208309
 
 
 
 
 
 
 
 
 
 
 
6aab158
1208309
 
 
 
 
 
 
6aab158
 
1208309
 
 
 
 
6aab158
 
 
 
 
1208309
 
 
 
 
6aab158
1208309
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
const HF = "https://huggingface.co/";
const AUDIO_SPACE = HF + "spaces/danielrosehill/Audio-Dataset-Navigator";
const SENTENCE_SPACE = HF + "spaces/danielrosehill/Sentence-Dataset-Navigator";
const esc = (s) => String(s ?? "").replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c]));
const ds = (id) => HF + "datasets/" + id;
const link = (url, text) => `<a href="${esc(url)}" target="_blank" rel="noopener">${esc(text)}</a>`;
const size = (b) => (b >= 1e9 ? (b / 1e9).toFixed(1) + " GB" : b >= 1e6 ? Math.round(b / 1e6) + " MB" : Math.max(1, Math.round(b / 1e3)) + " KB");
const hours = (h) => (h >= 1 ? h.toFixed(1) + " hours" : Math.max(1, Math.round(h * 60)) + " min");
const short = (id) => id.split("/")[1].replace(/-/g, " ");

function who(d, kind) {
  const org = d.owner === "Hebrish";
  const text = org
    ? `Hebrish org 路 Daniel's own ${kind}`
    : `danielrosehill 路 Daniel's own ${kind}`;
  return `<div class="who"><img src="${org ? "hebrish.webp" : "daniel.webp"}" alt=""><span>${text}</span></div>`;
}

function card(d, kind, unit) {
  const meta = [];
  if (d.rows != null) meta.push(`${d.rows.toLocaleString("en-US")} ${unit}`);
  if (d.hours != null) meta.push(hours(d.hours));
  meta.push(size(d.bytes));
  if ("hours" in d) meta.push("Updated " + d.modified.slice(0, 10));
  if (d.gated) meta.push('<span class="badge">Access request</span>');
  const pairs = (d.banks || []).map((b) => link(ds(b), "Text: " + short(b)));
  if (d.pairs_with) pairs.push(link(ds(d.pairs_with), "Audio: " + short(d.pairs_with)));
  return `<article class="card${d.group === "Master" ? " master" : ""}">${who(d, kind)}
    <h3>${link(ds(d.id), d.name)}</h3><p>${esc(d.summary)}</p>
    <div class="meta">${meta.join("<span>路</span>")}</div>
    ${pairs.length ? `<div class="meta">${pairs.join("")}</div>` : ""}</article>`;
}

async function navigator({ kind, unit }) {
  const data = await (await fetch("data.json")).json();
  const list = data.datasets;
  const q = document.getElementById("q"), owner = document.getElementById("owner"), sort = document.getElementById("sort"), out = document.getElementById("list");
  document.getElementById("built").textContent = data.built;
  const total = list.reduce((n, d) => n + (d.rows || 0), 0);
  const master = list.find((d) => d.group === "Master");
  const stat = (v, l) => `<span><b>${v}</b> ${l}</span>`;
  document.getElementById("stats").innerHTML =
    stat(list.length, "datasets") +
    ["danielrosehill", "Hebrish"].map((o) => [o, list.filter((d) => d.owner === o).length]).filter(([, n]) => n).map(([o, n]) => stat(n, "on " + o)).join("") +
    stat((master ? master.rows : total).toLocaleString("en-US"), master ? "takes in the master" : "sentences") +
    (master && master.hours != null ? stat(master.hours.toFixed(1), "hours in the master") : "");
  if (new Set(list.map((d) => d.owner)).size < 2) owner.hidden = true;
  const draw = () => {
    const term = q.value.trim().toLowerCase();
    const hit = list.filter((d) => (!owner.value || d.owner === owner.value) && (d.id + " " + d.summary + " " + d.group).toLowerCase().includes(term));
    const groups = [...new Set(hit.map((d) => d.group))];
    const order = sort && { takes: (a, b) => (b.rows ?? -1) - (a.rows ?? -1), updated: (a, b) => b.modified.localeCompare(a.modified) }[sort.value];
    if (order && hit.length) {
      out.innerHTML = `<div class="grid">${[...hit].sort(order).map((d) => card(d, kind, unit)).join("")}</div>`;
      return;
    }
    out.innerHTML = groups.map((g) => `<h2>${esc(g)}</h2><div class="grid">${hit.filter((d) => d.group === g).map((d) => card(d, kind, unit)).join("")}</div>`).join("")
      || '<p class="empty">No datasets match.</p>';
  };
  q.addEventListener("input", draw);
  owner.addEventListener("change", draw);
  if (sort) sort.addEventListener("change", draw);
  draw();
}

async function thirdParty() {
  const data = await (await fetch("data.json")).json();
  document.getElementById("built").textContent = data.built;
  document.getElementById("collection").href = HF + "collections/" + data.collections.sentences_third_party;
  document.getElementById("list").innerHTML = data.third_party.map((d) => `<article class="card">
    <div class="who"><span>${esc(d.id.split("/")[0])}</span></div><h3>${link(ds(d.id), short(d.id))}</h3><p>${esc(d.note)}</p></article>`).join("");
}