// sky.mjs — day/night lighting, sun marker, URL state, play const bright = `const a = window.mapViewer, gl = a.renderer.getContext(); a.view.render(); const w = gl.drawingBufferWidth, h = gl.drawingBufferHeight, p = new Uint8Array(4 * 400); gl.readPixels((w >> 1) - 10, (h >> 1) - 10, 20, 20, gl.RGBA, gl.UNSIGNED_BYTE, p); let s = 0; for (let i = 0; i < p.length; i += 4) s += p[i] + p[i + 1] + p[i + 2]; return s / 400;`; const at = lon => `window.mapViewer.view.setState({ lat: 20, lon: ${lon}, alt: 1.5 }); await new Promise(r => setTimeout(r, 400));`; export const steps = [ { name: 'sky off at 0°E and 180°', wait: 4000, js: at(0) + `window.__off0 = (() => { ${bright} })();` + at(180) + `window.__off180 = (() => { ${bright} })(); return [window.__off0, window.__off180];` }, { name: 'sky on: bar, label, sun marker', expect: ([h, n, t]) => h === false && n === 1 && t === 'day 54 of 216 · northern midsummer', js: `document.getElementById('sky-toggle').click(); const d = document.getElementById('sky-day'), m = document.getElementById('sky-mo'); d.value = 54; d.dispatchEvent(new Event('input')); m.value = 23328; m.dispatchEvent(new Event('input')); await new Promise(r => setTimeout(r, 300)); return [document.getElementById('skybar').hidden, document.querySelectorAll('.marker.sun').length, document.getElementById('sky-day-label').textContent];` }, { name: 'noon at 0°E stays lit', js: at(0) + `return [(() => { ${bright} })(), window.__off0];`, expect: ([on, off]) => on > off * 0.8 }, { name: 'midnight at 180° goes dark', js: at(180) + `return [(() => { ${bright} })(), window.__off180];`, expect: ([on, off]) => on < off * 0.5 }, { name: 'URL carries the sky', js: `await new Promise(r => setTimeout(r, 400)); return location.hash;`, expect: v => v.includes('sky=1') && v.includes('day=54') && v.includes('mo=23328') }, { name: 'flat view is lit too', js: `const a = window.mapViewer; a.setView('equal_earth'); return a.view.shade.sky.value;`, expect: v => v === 1 }, { name: 'playing rebuilds no sky lines', expect: v => v.n === 0 && v.moved, js: `const a = window.mapViewer, o = a.overlays, f = o.setExtra.bind(o); let n = 0; o.setExtra = (...x) => { n++; return f(...x); }; const m0 = a.state.mo, b = document.getElementById('sky-play'); b.click(); await new Promise(r => setTimeout(r, 600)); b.click(); o.setExtra = f; return { n, moved: a.state.mo !== m0 };` }, { name: 'play advances time', expect: v => v === true, js: `const b = document.getElementById('sky-play'); const m0 = window.mapViewer.state.mo; b.click(); await new Promise(r => setTimeout(r, 600)); b.click(); return window.mapViewer.state.mo !== m0;` }, { name: 'sky off restores', js: `document.getElementById('sky-toggle').click(); return [window.mapViewer.view.shade.sky.value, document.querySelectorAll('.marker.sun').length];`, expect: ([s, n]) => s === 0 && n === 0 }, ];