diff --git a/assets/mirror/20.jpg b/assets/mirror/20.jpg new file mode 100644 index 0000000..0194ec1 Binary files /dev/null and b/assets/mirror/20.jpg differ diff --git a/assets/mirror/21.jpg b/assets/mirror/21.jpg new file mode 100644 index 0000000..9ec53b5 Binary files /dev/null and b/assets/mirror/21.jpg differ diff --git a/assets/mirror/22.jpg b/assets/mirror/22.jpg new file mode 100644 index 0000000..d567d73 Binary files /dev/null and b/assets/mirror/22.jpg differ diff --git a/assets/mirror/23.jpg b/assets/mirror/23.jpg new file mode 100644 index 0000000..7d4e09c Binary files /dev/null and b/assets/mirror/23.jpg differ diff --git a/assets/mirror/24.jpg b/assets/mirror/24.jpg new file mode 100644 index 0000000..83057c3 Binary files /dev/null and b/assets/mirror/24.jpg differ diff --git a/assets/mirror/25.jpg b/assets/mirror/25.jpg new file mode 100644 index 0000000..749a0bd Binary files /dev/null and b/assets/mirror/25.jpg differ diff --git a/build.sh b/build.sh index 2c92ab3..286c9e1 100755 --- a/build.sh +++ b/build.sh @@ -21,7 +21,10 @@ for f in pilot/arc.tpl.html pilot/manifest-docker.json pilot/manifest-cluster.js assets/dist/course-II-cluster.webp assets/dist/course-00-surround.webp \ assets/dist/course-III-node.webp assets/dist/course-III-pod.webp \ assets/dist/course-IV-traffic.webp assets/dist/course-V-orbit.webp \ - assets/dist/intro-establishing.webp; do + assets/dist/intro-establishing.webp \ + pilot/mirror.tpl.html pilot/mirror.js pilot/index.tpl.html \ + assets/mirror/20.jpg assets/mirror/21.jpg assets/mirror/22.jpg \ + assets/mirror/23.jpg assets/mirror/24.jpg assets/mirror/25.jpg; do [[ -f "$f" ]] || { printf 'missing source: %s\n' "$f" >&2; exit 1; } done @@ -29,11 +32,13 @@ dist="$here/dist" rm -rf -- "$dist" node pilot/assemble-arc.mjs "$dist" -# No inline JS may survive into the served HTML, or the CSP silently kills the page. -if grep -oiE ']*>' -- "$dist/index.html" | grep -qivE 'src='; then - printf 'index.html contains an inline - - +${scripts.map(s => ``).join("\n")} `; -writeFileSync(join(DIST, "index.html"), html); -writeFileSync(join(DIST, "build.json"), JSON.stringify({ revision: BUILD_REV, app: appName }) + "\n"); +const html = shell({ + title: "The Exploded Cluster", desc: DESC, path: "/cluster", ogImg: OG_IMG, + scripts: [gsapRef, stRef, appRef], bodyHtml: body, +}); + +// ---- The Mirror (chapter 02): fingerprint its plates + its app script ------- +const MIRROR_DESC = "A pull-through container registry taken apart: why a lab runs its own mirror, the chicken-and-egg loops inside it, and the scars that taught each rule."; +let mirror = readFileSync(join(ROOT, "pilot/mirror.tpl.html"), "utf8"); +const mirrorPlates = {}; +for (const n of ["20", "21", "22", "23", "24", "25"]) { + const { url } = emit(join(ROOT, "assets/mirror", `${n}.jpg`), `mirror-${n}`, "jpg"); + mirrorPlates[n] = url; + mirror = mirror.replace(`__M${n}__`, url); +} +const mirrorJs = readFileSync(join(ROOT, "pilot/mirror.js")); +const mirrorJsName = `mirror.${fp(mirrorJs)}.js`; +writeFileSync(join(DIST, "assets", mirrorJsName), mirrorJs); +mirror = mirror.replace("__MIRROR_JS__", "/assets/" + mirrorJsName); +if (mirror.includes("__M")) throw new Error("unfilled mirror placeholder"); +const mirrorHtml = shell({ + title: "The Mirror", desc: MIRROR_DESC, path: "/mirror", + ogImg: SITE + mirrorPlates["20"], scripts: [], bodyHtml: mirror, +}); + +// ---- the directory (index): the chapters of what this place teaches --------- +const DIR_DESC = "The Teaching Lab: scroll-driven teardowns of real infrastructure - container platforms, registries and the machinery of delivery, one exploded system per chapter."; +let dir = readFileSync(join(ROOT, "pilot/index.tpl.html"), "utf8") + .replace("__THUMB_CLUSTER__", heroUrls["__HERO_GITOPS__"]) + .replace("__THUMB_MIRROR__", mirrorPlates["20"]); +if (dir.includes("__THUMB")) throw new Error("unfilled directory placeholder"); +const dirHtml = shell({ + title: "The Teaching Lab", desc: DIR_DESC, path: "/", + ogImg: SITE + mirrorPlates["20"], scripts: [], bodyHtml: dir, +}); + +writeFileSync(join(DIST, "index.html"), dirHtml); +writeFileSync(join(DIST, "cluster.html"), html); +writeFileSync(join(DIST, "mirror.html"), mirrorHtml); +writeFileSync(join(DIST, "build.json"), JSON.stringify({ revision: BUILD_REV, app: appName, mirror: mirrorJsName }) + "\n"); // --------------------------------------------------------------------------- // Preflight gates: fail the build loudly rather than ship a known defect. @@ -157,20 +193,18 @@ writeFileSync(join(DIST, "build.json"), JSON.stringify({ revision: BUILD_REV, ap const fail = []; const must = (cond, msg) => { if (!cond) fail.push(msg); }; -// no inline