// Wires the ".alog reference curve" panel: local file upload, and browsing a server-side // library directory (e.g. wherever the roastetta skill already downloaded logs). export function initAlogPanel({ state, recompute }) { const fileInput = document.getElementById("alog-file"); const libraryBtn = document.getElementById("alog-library-refresh"); const libraryList = document.getElementById("alog-library-list"); const resultEl = document.getElementById("alog-result"); fileInput.addEventListener("change", async (e) => { const file = e.target.files?.[0]; if (!file) return; resultEl.innerHTML = "
Parsing…
"; try { const content = await file.text(); const res = await fetch("/api/alog", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ filename: file.name, content }), }); const body = await res.json(); applyResult(body); } catch (err) { resultEl.innerHTML = `${escapeHtml(err.message)}
`; } }); libraryBtn.addEventListener("click", async () => { libraryList.classList.remove("hidden"); libraryList.innerHTML = "Loading…
"; const r = await fetch(`/api/alog/library/${encodeURIComponent(f.filename)}`); applyResult(await r.json()); }); libraryList.appendChild(li); } } catch (err) { libraryList.innerHTML = `${escapeHtml(body.error ?? body.code)}
`; return; } state.plan.reference = body; recompute(); const warnings = (body.warnings ?? []).map((w) => `${escapeHtml(body.roast.title)} — ${body.roast.roastDate || "no date"} · first crack ${fmt(body.derived?.firstCrackS)} · development ${fmt(body.derived?.developmentS)} · drop ${fmt(body.derived?.dropS)} · DTR ${body.derived?.dtrPct ?? "—"}%
${warnings ? `