/* shared.js -- common runtime for all module pages: top navigation, Pyodide bootstrap, editable-code runner, plot helpers. */ const NAV_ITEMS = [ ["index.html", "导航 Home"], ["m00_overview.html", "0 水量平衡"], ["m01_forcing.html", "1 Forcing"], ["m02_pet.html", "2 PET"], ["m05_runoff.html", "5 产流"], ["m06_response.html", "6 Response"], ["m07_routing.html", "7 Routing·方法"], ["m08_channel.html", "8a Routing·空间"], ]; function renderNav(here) { const nav = document.createElement("div"); nav.className = "topnav"; const inner = document.createElement("div"); inner.className = "wrap"; const brand = document.createElement("span"); brand.className = "brand"; brand.textContent = "💧 HydroModel Builder"; inner.appendChild(brand); for (const [href, label] of NAV_ITEMS) { // skip links to pages that don't exist yet (marked with data-disabled below) const a = document.createElement("a"); a.href = href; a.textContent = label; if (here === href) a.className = "here"; inner.appendChild(a); } nav.appendChild(inner); document.body.prepend(nav); } /* ---------- Pyodide bootstrap (one shared promise) ---------- */ let _pyodidePromise = null; function getPyodide(statusEl) { if (!_pyodidePromise) { if (statusEl) statusEl.textContent = "正在加载 Python 运行时 (~10s 首次) …"; _pyodidePromise = loadPyodide().then(async (py) => { await py.loadPackage("numpy"); if (statusEl) statusEl.textContent = "Python (numpy) 就绪 — 可改代码后重跑"; return py; }); } return _pyodidePromise; } /* ---------- Editable-code runner ---------- makeRunner({codeEl, runBtn, resetBtn, statusEl, errEl, buildScript, onResult}) - codeEl: