返回资讯中心
外部精选
软件工程
#开发者实时流

Defrag the UK Economy

const FLAG_BIG = FLAG.replace('width="12" height="11"', 'width="16" height="15"');

Hacker News 最新rwmj2026/10/31 · 2 天前22 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

'; const ICON_FOLDER = ''; const ICON_LINE = '£'; const LOCK_BADGE = ''; const LOCK_BIG = ''; const TRASH = ''; const ICON_WARN = ''; const FLAG = ''; const FLAG_BIG = FLAG.replace('width="12" height="11"', 'width="16" height="15"'); const CHECK = '';

/* ---------- selection & expansion ---------- */ let sel = ROOT; let exp = new Set(["uk", "uk/social-protection", "uk/health", "uk/general-public-services"]); const kidsOf = n => (n.children || []).filter(c => !gone(c)).sort((a, b) => (a.rem ? 1 : 0) - (b.rem ? 1 : 0) || b.v[YI] - a.v[YI]); function flatten() { const out = []; (function walk(n, lv, dp) { out.push({ n, lv, dp }); if (treeFolder(n) && exp.has(n.key)) for (const c of kidsOf(n)) walk(c, lv + 1, n); })(ROOT, 0, null); return out; } function settle(rows) { if (rows.some(r => r.n === sel)) return; let p = sel.parent; while (p && !rows.some(r => r.n === p)) p = p.parent; sel = p || ROOT; } function reveal(n) { for (let p = n.parent; p; p = p.parent) exp.add(p.key); }

/* ---------- tree view (virtualised) ---------- */ const treeEl = document.getElementById("tree"); const inner = document.createElement("div"); inner.style.position = "relative"; treeEl.appendChild(inner); let ROWS = []; const rowH = () => (window.matchMedia("(max-width: 560px)").matches ? 34 : 28);

function rowHTML(r, i) { const { n, lv, dp } = r, root = !dp; const share = dp ? Math.max(0, Math.min(1, n.e / dp.v[YI])) : 1; const folder = treeFolder(n), open = folder && exp.has(n.key); const major = root || share >= 0.15; const cut = n.v[YI] - n.e; const acts = !root && !n.lock; const name = root ? UK:\\${n.name}\\ : n.name; const title = root ? ${n.name}: ${money(n.e)} : n.lock ? ${n.name}: locked : ${n.name}: ${money(n.e)}${cut >= 0.05 ? , cut ${money(cut)} : ""}; return ``

  • ${folder ? CHEV : ""}
  • ${folder ? ICON_FOLDER : ICON_LINE}${n.lock ? LOCK_BADGE : ""}
  • ${money(n.e)}${esc(name)}${n.warn ? ${FLAG}${WARN_SHORT}: ""}${!root && cut >= 0.05 ?−${money(cut)} : ""}
  • (acts ? −10%${TRASH} : "")
  • `

`; } let painting = false; function paint() { painting = false; const h = rowH(), st = treeEl.scrollTop, vh = treeEl.clientHeight || 600; const a = Math.max(0, Math.floor(st / h) - 12), b = Math.min(ROWS.length, Math.ceil((st + vh) / h) + 12); const hadFocus = treeEl.contains(document.activeElement); // Keep row elements that haven't changed, so a scroll never swaps out the row under the pointer mid-drag. const old = new Map(); for (const el of inner.children) old.set(el.dataset.key, el); const want = [], tmp = document.createElement("div"); for (let i = a; i { if (inner.children[i] !== el) inner.insertBefore(el, inner.children[i] || null); }); if (hadFocus && !treeEl.contains(document.activeElement)) inner.querySelector('.row[tabindex="0"]')?.focus({ preventScroll: true }); } treeEl.addEventListener("scroll", () => { if (!painting) { painting = true; requestAnimationFrame(paint); } updateMore(); }, { passive: true }); // "More files" cue: shown while there are rows below the visible part of the list const treeMore = document.getElementById("treeMore"); function updateMore() { treeMore.hidden = !(treeEl.scrollTop + treeEl.clientHeight treeEl.scrollBy({ top: Math.round(treeEl.clientHeight * 0.7), behavior: window.matchMedia("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth" })); function renderTree(scrollToSel) { ROWS = flatten(); settle(ROWS); const h = rowH(); inner.style.height = ROWS.length * h + "px"; if (scrollToSel) { const i = ROWS.findIndex(r => r.n === sel), top = i * h; if (top treeEl.scrollTop + treeEl.clientHeight) treeEl.scrollTop = top + 2 * h - treeEl.clientHeight; } paint(); updateMore(); }

/* ---------- drive meter ---------- */ let lastGap = null; function renderMeter() { const u = used(), g = u - CAP, scale = Math.max(u, CAP); const fill = Math.min(u, CAP) / scale, capAt = CAP / scale; document.getElementById("mFill").style.width = (fill * 100).toFixed(3) + "%"; const ov = document.getElementById("mOver"); ov.style.left = (capAt * 100).toFixed(3) + "%"; ov.style.width = g > 0 ? ((g / scale) * 100).toFixed(3) + "%" : "0%"; document.getElementById("mCap").style.left = (capAt * 100).toFixed(3) + "%"; // Receipts sits on the spending row, right-aligned under its tick; on the narrowest phones it moves to the row's end rather than wrap. const lg = document.getElementById("legend"); lg.style.setProperty("--cap-right", ((1 - capAt) * 100).toFixed(3) + "%"); if (lg.querySelector(".cap-label").offsetTop > lg.querySelector(".k-used").offsetTop + 2) lg.style.setProperty("--cap-right", "0%"); document.getElementById("meter").setAttribute("aria-label", Spending ${money(u)} against receipts ${money(CAP)}); const st = document.getElementById("state"); st.className = "state " + (g > 0.05 ? "over" : "ok"); if (touched && g 0.05 ? ${ICON_WARN}Over capacity by ${money(g)} : ${CHECK}Fits, with ${money(-g)} free; document.getElementById("lgUsed").textContent = money(u); document.getElementById("lgCap").textContent = money(CAP); document.getElementById("lgOver").textContent = money(Math.max(0, g)); document.getElementById("lgOverK").hidden = !(g > 0.05); document.getElementById("lgCut").textContent = money(totalCut()); document.getElementById("compare").textContent = compareText(g); renderEgg(u); const s1 = document.getElementById("st1"); s1.innerHTML = Free Space: 0.05 ? "neg" : "pos"}">${money(-g)} (of ${money(CAP)}); document.getElementById("st2").textContent = ${YEAR} outturn; const ch = changes(); const nd = ch.filter(deleted).length, ns = ch.length - nd; document.getElementById("st3").textContent = ${nf0.format(ALL.filter(n => !n.children && !gone(n)).length)} Lines · ${nd} deleted · ${ns} shrunk; } function eggInfo(u) { const p = (u / GDP) * 100, base = (TME / GDP) * 100; if (p >= base - 0.005) return null; let since = null; for (let i = HIST.length - 1; i >= 0; i--) if (HIST[i][1] ${since} (your plan: ${nf1.format(p)}% of GDP) :Smallest state since records began in ${HIST[0][0]} (your plan: ${nf1.format(p)}% of GDP); el.hidden = false; } const lcFirst = s => (/^[A-Z][a-z]/.test(s) ? s[0].toLowerCase() + s.slice(1) : s); function compareText(g) { if (g 0 && !n.lock && !n.rem && !gone(n) && n.e >= 0.5 && (!best || Math.abs(n.e - g) saving(b) - saving(a)); } function renderBin() { const ch = changes(); const nd = ch.filter(deleted).length, ns = ch.length - nd; const parts = []; if (nd) parts.push(${nd} deleted); if (ns) parts.push(${ns} shrunk); document.getElementById("binSum").innerHTML = ch.length ? ${parts.join(", ")} · ${money(totalCut())} freed: (window.matchMedia("(hover: none)").matches ? "Empty. Tap a line, then use its bin button." : "Empty. Drag a line here, or select one and press Delete."); document.getElementById("binPaper").setAttribute("opacity", ch.length ? "1" : "0"); document.getElementById("restoreAll").disabled = !ch.length; document.getElementById("copyPlan").hidden = !ch.length; document.getElementById("eggRow").hidden = !ch.length && document.getElementById("egg").hidden; document.getElementById("binList").innerHTML = ch.map(n => { const d = deleted(n); return${d ? TRASH : "✂"}`

  • ${esc(n.name)}${n.warn ? ${FLAG}${WARN_SHORT}: ""} ${d ? "deleted" :shrunk ${Math.round((1 - fOf(n)) * 100)}%} · in ${esc(n.parent.depth ? n.parent.name : "Public spending")}
  • `${money(saving(n))}Restore

`; }).join(""); }

/* ---------- Properties ---------- */ function sparkSVG(n) { const W = 340, H = 70, top = 6, base = 50, gap = 9; const vals = [...n.v, n.e]; const max = Math.max(...vals, 1); const slots = vals.length, bw = (W - gap * (slots - 1)) / slots; const labels = [...RAW.years.map(yshort), "Plan"]; let s = ${y} ${money(n.v[i])}).join(", ")}; your plan ${money(n.e)}">; vals.forEach((v, i) => { const x = i * (bw + gap), hgt = Math.max(1, (Math.max(0, v) / max) * (base - top)), y = base - hgt; if (i ${RAW.years[i]}: ${money(v)}; else s += Your plan: ${money(v)}; s += ${labels[i]}; }); return s + ``; } function wasHTML(n) { const cut = n.v[YI] - n.e; return cut >= 0.05 ? ${money(n.v[YI])} · cut ${money(cut)} (${pct(cut / n.v[YI])}): n.depth ? "Untouched" : ""; } function outHTML(n) { const k = Math.round(fOf(n) * 100); returnKeep ${k}% · ${money(n.e)}; } function renderDetail() { const n = sel; document.getElementById("propName").textContent = "— " + n.name; const about = aboutOf(n); let memo = ""; if (n.memo) for (const m of n.memo) memo += ${money(m.v[YI])} of this is ${m.name.toLowerCase()} (social care arranged by councils), counted across the lines below.

${g > 0.05 ? To balance the budget, you need to cut ${money(g)}, or ${pct(g / TME)} of all spending. : The budget balances, with ${money(-g)} to spare.} Click on files in the folders ${where} to delete or shrink line items. Debt interest and accounting adjustments are fixed.

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →