molecule
Alex — Adom Molecule LED Nameplate
Public Made by Adomby adom
Alex's name etched out of the soldermask over the top-layer ground plane, lit by side-view LEDs firing inward across the board. A real Adom molecule: large machine pins on the 32 mm base-scaffold grid, USB-C powered. Every LED returns its current through the letters, so there is no second ground path.
← Commit history
Alex nameplate: self-hosted 3D viewer, Z-up model, README.html
1 file changed
+31−10
viewer/index.html+31−10@@ -1296,18 +1296,39 @@ function loadAlphabet() { } function loadAdom3D() {- // Hosted as a release asset rather than a page file: page files are capped at- // ~4 MB and this bundle is 13 MB. Release assets have no cap, and the CSP- // (`script-src 'unsafe-inline' https:`) allows any https: source, so this can- // be an ordinary streaming script tag instead of a chunked fetch reassembled- // into one 13 MB string.- return new Promise((resolve, reject) => {+ // Two wiki constraints shape this.+ //+ // 1. The render endpoint 413s on files over ~4 MB and this bundle is 13 MB,+ // so it ships as 4 byte-exact parts, reassembled as bytes (never as+ // text) because a multi-byte character can straddle a split boundary.+ //+ // 2. The page CSP is `script-src 'unsafe-inline' https:`. That permits an+ // INLINE script but blocks `blob:`, so handing the reassembled bundle to+ // URL.createObjectURL and setting script.src fails with+ // "Loading the script 'blob:null/...' violates ... Content Security+ // Policy". Setting textContent runs it under 'unsafe-inline' instead.+ // An inline script executes synchronously on append, so there is nothing+ // to await once it is in the DOM.+ return (async () => {+ const N = 4;+ const bufs = [];+ for (let i = 0; i < N; i++) {+ const r = await fetch('js/adom-3d-viewer.min.js.part' + i);+ if (!r.ok) throw new Error('viewer bundle part ' + i + ' -> HTTP ' + r.status);+ bufs.push(new Uint8Array(await r.arrayBuffer()));+ }+ let total = 0;+ for (const b of bufs) total += b.length;+ const all = new Uint8Array(total);+ let o = 0;+ for (const b of bufs) { all.set(b, o); o += b.length; }+ const s = document.createElement('script');- s.src = 'https://wiki.adom.inc/download/adom/alex-nameplate/viewer-1/adom-3d-viewer.min.js';- s.onload = () => resolve();- s.onerror = () => reject(new Error('Failed to load the viewer bundle from https://wiki.adom.inc/download/adom/alex-nameplate/viewer-1/adom-3d-viewer.min.js'));+ s.textContent = new TextDecoder('utf-8').decode(all); document.head.appendChild(s);- });++ if (!window.Adom3DViewer) throw new Error('viewer bundle ran but exposed no Adom3DViewer');+ })(); } async function initViewer() {