static/js/app.js:80:const POST = (p, json) => api(p, { method: "POST", json }); } function fmtMoney(n) { if (n == null) return "—"; return "$" + Number(n).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } function plural(n, w) { return `${n} ${w}${n === 1 ? "" : "s"}`; } /* ---------- API client ---------- */ const CSRF = { get() { return getCookie("mailer_csrf"); }, }; function getCookie(name) { return document.cookie.split("; ").find(r => r.startsWith(name + "="))?.split("=").slice(1).join("=") || ""; } async function api(path, opts = {}) { const headers = Object.assign({}, opts.headers || {}); if (opts.json !== undefined) { headers["Content-Type"] = "application/json"; opts.body = JSON.stringify(opts.json); delete opts.json; } if ((opts.method || "GET").toUpperCase() !== "GET") headers["X-CSRF-Token"] = CSRF.get(); const res = await fetch(path, Object.assign({}, opts, { headers, credentials: "same-origin" })); let data = null; try { data = await res.json(); } catch { /* no body */ } if (res.status === 401 && !location.pathname.startsWith("/login")) { location.href = "/login?next=" + encodeURIComponent(location.pathname); throw new Error("Not authenticated"); } if (!res.ok) {