Download embed.js from embedl/Edge-Inference-Benchmarks: direct link, hf CLI and curl.
- Browser
- Download file 13.6 kB
-
https://huggingface.co/spaces/embedl/Edge-Inference-Benchmarks/resolve/main/embed.js
- Command line
-
hf download hf://spaces/embedl/Edge-Inference-Benchmarks/embed.js
-
curl -L -o embed.js https://huggingface.co/spaces/embedl/Edge-Inference-Benchmarks/resolve/main/embed.js
13.6 kB
| // ─── Embed SVG Generator ───────────────────────────────────────────────────── | |
| // | |
| // Extracted module. Call initEmbed(deps) from the main app once globals are | |
| // ready. Returns { showEmbedModal }. | |
| // eslint-disable-next-line no-unused-vars | |
| function initEmbed(deps) { | |
| const { | |
| config, filters, activeFamilyKey, getActiveModelSet, | |
| getData, MODEL_COL, FAMILY_COL, GROUP_BY, CHART_CFG, | |
| MODEL_COLORS, MODEL_SHORT, isOOMRow, isExternalModel, | |
| sortModels, parseModelSize, shareHash, | |
| } = deps; | |
| let embedModal = null; | |
| let cachedCommitHash = null; | |
| const HF_DOCS_REPO = "embedl/documentation-images"; | |
| const HF_SVG_FOLDER = "Edge-Inference-Benchmarks"; | |
| const HF_SPACES_REPO = "embedl/Edge-Inference-Benchmarks"; | |
| const HF_SPACES_URL = "https://huggingface.co/spaces/" + HF_SPACES_REPO; | |
| async function loadCommitHash() { | |
| if (cachedCommitHash) return cachedCommitHash; | |
| try { | |
| const resp = await fetch("https://huggingface.co/api/spaces/" + HF_SPACES_REPO); | |
| if (resp.ok) { | |
| const data = await resp.json(); | |
| cachedCommitHash = data.sha ? data.sha.substring(0, 7) : null; | |
| } | |
| } catch {} | |
| return cachedCommitHash; | |
| } | |
| function embedFamilyKey() { | |
| return filters.variant || activeFamilyKey(); | |
| } | |
| function embedFileName() { | |
| return embedFamilyKey() + "__" + filters[GROUP_BY] + ".svg"; | |
| } | |
| function getEmbedChartData() { | |
| const familyCfg = config.model_families?.[activeFamilyKey()] || {}; | |
| const chartCfg = familyCfg.chart || CHART_CFG; | |
| const scenarios = chartCfg.scenarios || []; | |
| const metricCol = filters.metric; | |
| const metricCfg = config.metrics.find(m => m.column === metricCol) || {}; | |
| const groupFilterCfg = config.filters.find(f => f.column === GROUP_BY); | |
| const groupVal = filters[GROUP_BY]; | |
| if (groupVal === "all") return null; | |
| const groupLabel = groupFilterCfg?.value_labels?.[groupVal] || String(groupVal); | |
| const familyModels = getActiveModelSet(); | |
| const filtered = getData().filter(r => { | |
| if (!familyModels.has(r[MODEL_COL])) return false; | |
| for (const f of config.filters) { | |
| const fv = filters[f.column]; | |
| if (fv === "all" || fv === "" || fv === undefined) continue; | |
| if (String(r[f.column]) !== String(fv)) return false; | |
| } | |
| return true; | |
| }); | |
| const gRows = filtered.filter(r => String(r[GROUP_BY]) === String(groupVal)); | |
| if (!gRows.length) return null; | |
| const uniqueModels = new Set(gRows.map(r => r[MODEL_COL])); | |
| if (uniqueModels.size <= 1) return null; | |
| const scenarioList = scenarios.length ? scenarios : [{ label: "", match: {} }]; | |
| // Find first scenario that produces data (mirrors buildChart logic) | |
| let scenario = null; | |
| let picked = []; | |
| for (const sc of scenarioList) { | |
| const matchRows = gRows.filter(r => | |
| Object.entries(sc.match || {}).every(([col, val]) => | |
| String(r[col]) === String(val) | |
| ) | |
| ); | |
| const matchedModels = new Set(matchRows.map(r => r[MODEL_COL])); | |
| const oomRows = gRows.filter(r => !matchedModels.has(r[MODEL_COL]) && isOOMRow(r) | |
| && Object.entries(sc.match || {}).every(([col, val]) => | |
| r[col] === null || r[col] === "" || r[col] === "OOM" || String(r[col]) === String(val) | |
| ) | |
| ); | |
| const allRows = matchRows.concat(oomRows); | |
| const models = sortModels([...new Set(allRows.map(r => r[MODEL_COL]))]); | |
| const candidates = models.map(m => allRows.find(r => r[MODEL_COL] === m)).filter(Boolean); | |
| if (candidates.length) { | |
| scenario = sc; | |
| picked = candidates; | |
| break; | |
| } | |
| } | |
| if (!picked.length) return null; | |
| const hib = metricCfg.higher_is_better !== false; | |
| picked.sort((a, b) => { | |
| const sizeA = parseModelSize(a[FAMILY_COL] || a[MODEL_COL]); | |
| const sizeB = parseModelSize(b[FAMILY_COL] || b[MODEL_COL]); | |
| if (sizeA !== sizeB) return sizeA - sizeB; | |
| const extA = isExternalModel(a[MODEL_COL]) ? 0 : 1; | |
| const extB = isExternalModel(b[MODEL_COL]) ? 0 : 1; | |
| if (extA !== extB) return extA - extB; | |
| const va = a[metricCol] ?? 0; | |
| const vb = b[metricCol] ?? 0; | |
| return hib ? va - vb : vb - va; | |
| }); | |
| const rawLabels = picked.map(r => MODEL_SHORT[r[MODEL_COL]]); | |
| const families = new Set(picked.map(r => r[FAMILY_COL])); | |
| const needPrefix = families.size > 1; | |
| const labels = rawLabels.map((lbl, i) => { | |
| if (needPrefix) { | |
| const fk = picked[i][FAMILY_COL] || ""; | |
| return lbl ? `${fk} ${lbl}` : fk; | |
| } | |
| return lbl; | |
| }); | |
| return { | |
| familyKey: embedFamilyKey(), | |
| groupLabel, | |
| scenarioLabel: scenario.label || "", | |
| metricCol, | |
| metricLabel: metricCfg.short || metricCol, | |
| higherIsBetter: hib, | |
| picked, | |
| labels, | |
| }; | |
| } | |
| function generateEmbedSVG(version) { | |
| const data = getEmbedChartData(); | |
| if (!data) return null; | |
| const { familyKey, groupLabel, scenarioLabel, metricCol, metricLabel, higherIsBetter, picked, labels } = data; | |
| const width = 800; | |
| const barHeight = 32; | |
| const barGap = 10; | |
| const topPad = 76; | |
| const bottomPad = 44; | |
| const leftPad = 260; | |
| const rightPad = 90; | |
| const barAreaWidth = width - leftPad - rightPad; | |
| const contentHeight = picked.length * (barHeight + barGap) - barGap; | |
| const height = topPad + contentHeight + bottomPad; | |
| const maxVal = Math.max(...picked.map(r => r[metricCol] ?? 0), 1); | |
| function esc(s) { | |
| return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); | |
| } | |
| let bars = ""; | |
| picked.forEach((r, i) => { | |
| const val = r[metricCol] ?? 0; | |
| const barW = maxVal > 0 ? Math.max((val / maxVal) * barAreaWidth, 0) : 0; | |
| const y = topPad + i * (barHeight + barGap); | |
| const cy = y + barHeight / 2 + 5; | |
| const color = MODEL_COLORS[r[MODEL_COL]]?.border || "#58b1c3"; | |
| const label = labels[i]; | |
| const oom = val === 0 && isOOMRow(r); | |
| const valText = oom ? "OOM" : val.toFixed(1); | |
| const valColor = oom ? "#ff4d6d" : "#e8e8e8"; | |
| bars += ` <text x="${leftPad - 14}" y="${cy}" text-anchor="end" fill="${color}" font-size="13" font-weight="500" font-family="system-ui,-apple-system,sans-serif">${esc(label)}</text>\n`; | |
| if (!oom && barW > 0) { | |
| bars += ` <rect x="${leftPad}" y="${y}" width="${barW.toFixed(1)}" height="${barHeight}" rx="4" fill="${color}" opacity="0.7"/>\n`; | |
| } | |
| bars += ` <text x="${leftPad + (oom ? 0 : barW) + 10}" y="${cy}" fill="${valColor}" font-size="13" font-weight="${oom ? "600" : "400"}" font-family="system-ui,-apple-system,sans-serif">${valText}</text>\n`; | |
| }); | |
| const hint = higherIsBetter ? "(higher is better)" : "(lower is better)"; | |
| const subtitle = [familyKey, groupLabel, scenarioLabel, metricLabel + " " + hint].filter(Boolean).join(" \u00b7 "); | |
| const commitAttr = version ? ` data-commit="${esc(version)}"` : ""; | |
| return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}"${commitAttr}> | |
| <defs> | |
| <linearGradient id="topGlow" x1="0" y1="0" x2="1" y2="0"> | |
| <stop offset="0%" stop-color="#58b1c3" stop-opacity="0"/> | |
| <stop offset="50%" stop-color="#58b1c3" stop-opacity="0.5"/> | |
| <stop offset="100%" stop-color="#58b1c3" stop-opacity="0"/> | |
| </linearGradient> | |
| </defs> | |
| <rect width="${width}" height="${height}" rx="12" fill="#0B1527"/> | |
| <rect x="0" y="0" width="${width}" height="${height}" rx="12" fill="none" stroke="#58b1c3" stroke-opacity="0.15"/> | |
| <rect x="80" y="1" width="${width - 160}" height="2" rx="1" fill="url(#topGlow)"/> | |
| <text x="28" y="32" fill="#e8e8e8" font-size="17" font-weight="700" font-family="system-ui,-apple-system,sans-serif">Edge Inference Benchmarks</text> | |
| <text x="28" y="54" fill="#8899aa" font-size="12" font-family="system-ui,-apple-system,sans-serif">${esc(subtitle)}</text> | |
| ${bars} <line x1="28" y1="${height - 36}" x2="${width - 28}" y2="${height - 36}" stroke="#58b1c3" stroke-opacity="0.15"/> | |
| <text x="28" y="${height - 14}" fill="#5a6a7a" font-size="11" font-family="system-ui,-apple-system,sans-serif">embedl.com</text> | |
| <text x="${width - 28}" y="${height - 14}" text-anchor="end" fill="#58b1c3" font-size="11" font-family="system-ui,-apple-system,sans-serif">View Benchmarks \u2192</text> | |
| </svg>`; | |
| } | |
| function createEmbedModal() { | |
| const overlay = document.createElement("div"); | |
| overlay.className = "embed-overlay"; | |
| overlay.innerHTML = ` | |
| <div class="embed-modal"> | |
| <div class="embed-modal-header"> | |
| <h3>Embed in Model Card</h3> | |
| <button class="embed-close" aria-label="Close">×</button> | |
| </div> | |
| <div class="embed-preview" id="embed-preview"></div> | |
| <div class="embed-status-bar"> | |
| <span class="embed-status" id="embed-status"></span> | |
| </div> | |
| <div class="embed-actions"> | |
| <button class="btn embed-action-btn" id="embed-copy">Copy Embed Code</button> | |
| <button class="btn embed-action-btn embed-secondary" id="embed-upload-manual">Download SVG & Open HF</button> | |
| </div> | |
| <div class="embed-code-section"> | |
| <label>Paste this into your HuggingFace model card README.md:</label> | |
| <textarea class="embed-code" id="embed-code" readonly rows="6"></textarea> | |
| </div> | |
| </div> | |
| `; | |
| overlay.querySelector(".embed-close").addEventListener("click", () => overlay.classList.remove("visible")); | |
| overlay.addEventListener("click", e => { if (e.target === overlay) overlay.classList.remove("visible"); }); | |
| overlay.querySelector("#embed-upload-manual").addEventListener("click", () => { | |
| const svg = generateEmbedSVG(cachedCommitHash); | |
| if (!svg) return; | |
| const fileName = embedFileName(); | |
| const blob = new Blob([svg], { type: "image/svg+xml" }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement("a"); | |
| a.href = url; | |
| a.download = fileName; | |
| a.click(); | |
| URL.revokeObjectURL(url); | |
| const commitMsg = "Update " + fileName + " (" + (cachedCommitHash || "latest") + ")"; | |
| window.open("https://huggingface.co/datasets/" + HF_DOCS_REPO + "/upload/main/" + HF_SVG_FOLDER + "?commit_message=" + encodeURIComponent(commitMsg), "_blank"); | |
| }); | |
| overlay.querySelector("#embed-copy").addEventListener("click", () => { | |
| const textarea = overlay.querySelector("#embed-code"); | |
| navigator.clipboard.writeText(textarea.value); | |
| const btn = overlay.querySelector("#embed-copy"); | |
| const orig = btn.textContent; | |
| btn.textContent = "Copied!"; | |
| setTimeout(() => { btn.textContent = orig; }, 2000); | |
| }); | |
| document.body.appendChild(overlay); | |
| return overlay; | |
| } | |
| function setEmbedStatus(cls, html) { | |
| const el = embedModal.querySelector("#embed-status"); | |
| el.className = "embed-status " + cls; | |
| el.innerHTML = html; | |
| } | |
| function showUploadUI(show) { | |
| embedModal.querySelector("#embed-upload-manual").style.display = show ? "" : "none"; | |
| } | |
| async function runEmbedUpload() { | |
| const version = cachedCommitHash; | |
| const fileName = embedFileName(); | |
| const svgPath = HF_SVG_FOLDER + "/" + fileName; | |
| const svgUrl = "https://huggingface.co/datasets/" + HF_DOCS_REPO + "/resolve/main/" + svgPath; | |
| setEmbedStatus("checking", "Checking\u2026"); | |
| showUploadUI(false); | |
| let remoteCommit = null; | |
| let exists = false; | |
| try { | |
| const resp = await fetch(svgUrl, { cache: "no-store" }); | |
| if (resp.ok) { | |
| exists = true; | |
| const text = await resp.text(); | |
| const m = text.match(/data-commit="([^"]+)"/); | |
| if (m) remoteCommit = m[1]; | |
| } | |
| } catch {} | |
| if (exists && version && remoteCommit === version) { | |
| setEmbedStatus("up-to-date", ""); | |
| return; | |
| } | |
| if (exists) { | |
| setEmbedStatus("needs-token", "SVG outdated \u2014 use Download SVG & Open HF below to update"); | |
| } else { | |
| setEmbedStatus("needs-token", "SVG not yet uploaded \u2014 use Download SVG & Open HF below to upload manually"); | |
| } | |
| showUploadUI(true); | |
| } | |
| async function showEmbedModal() { | |
| if (!embedModal) embedModal = createEmbedModal(); | |
| const version = await loadCommitHash(); | |
| const svg = generateEmbedSVG(version); | |
| if (!svg) return; | |
| embedModal.querySelector("#embed-preview").innerHTML = svg; | |
| const famKey = embedFamilyKey(); | |
| const fileName = embedFileName(); | |
| const svgUrl = "https://huggingface.co/datasets/" + HF_DOCS_REPO + "/resolve/main/" + HF_SVG_FOLDER + "/" + fileName; | |
| // Deep-link the embed back to the exact view it was generated from. | |
| const spacesUrl = HF_SPACES_URL + (typeof shareHash === "function" ? shareHash() : ""); | |
| const embedCode = '<a href="' + spacesUrl + '" target="_blank" rel="noopener">\n <img\n src="' + svgUrl + '"\n alt="Edge Inference Benchmarks for ' + famKey + '"\n width="100%"\n />\n</a>'; | |
| embedModal.querySelector("#embed-code").value = embedCode; | |
| embedModal.classList.add("visible"); | |
| runEmbedUpload(); | |
| } | |
| return { showEmbedModal }; | |
| } // end initEmbed | |