This commit is contained in:
Mark Randall Havens 2025-11-08 10:52:41 -06:00
parent a070458d34
commit 9e149f53b6
578 changed files with 0 additions and 6739 deletions

0
public/app.js Normal file → Executable file
View file

0
public/index.html Normal file → Executable file
View file

0
public/pinned/test.md Normal file → Executable file
View file

0
public/posts/first.md Normal file → Executable file
View file

0
public/posts/second.html Normal file → Executable file
View file

0
public/posts/third.html Normal file → Executable file
View file

View file

@ -1,269 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>The Glider That Remembered Me — A Research Exhibit</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<style>
:root{
--gold:#e8d36d;
--gold-soft:#f5e9a3;
--ink:#000;
--panel:rgba(0,0,0,.55);
--panel-strong:rgba(0,0,0,.7);
--border:rgba(232,211,109,.35);
}
html,body{margin:0;height:100%;background:var(--ink);color:var(--gold);font-family:Inter,system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif;overflow:auto}
canvas{display:block}
/* Layout */
#tabs{position:fixed;top:0;left:0;right:0;display:flex;background:var(--panel-strong);z-index:5}
.tab-btn{flex:1;padding:1rem;text-align:center;cursor:pointer;border-bottom:2px solid transparent}
.tab-btn.active{border-bottom:2px solid var(--gold);color:var(--gold-soft)}
.tab-content{display:none;padding-top:4rem;height:calc(100% - 4rem);overflow:auto}
.tab-content.active{display:block}
#hud{position:relative;pointer-events:none;padding:1rem}
.stack{pointer-events:auto;position:relative;display:flex;flex-direction:column;gap:.75rem;padding:1rem 1.25rem;background:var(--panel);backdrop-filter: blur(6px); border:1px solid var(--border); border-radius:16px; box-shadow:0 10px 30px rgba(0,0,0,.35);margin:1rem}
h1,h2,h3{font-weight:500;margin:.1rem 0;color:var(--gold-soft)}
h1{font-size:1.1rem;letter-spacing:.04em}
h2{font-size:1rem;margin-top:.25rem}
p{margin:.25rem 0;line-height:1.5}
small{opacity:.9}
label{font-size:.85rem;opacity:.95}
input[type="range"]{width:100%}
input[type="text"]{background:transparent;color:var(--gold);border:1px solid var(--border);border-radius:999px;padding:.45rem .8rem}
button, select{
background:transparent;color:var(--gold);border:1px solid var(--border);
border-radius:999px;padding:.45rem .8rem;cursor:pointer
}
button:hover{border-color:var(--gold)}
button.primary{background:var(--gold);color:#111;border-color:var(--gold)}
.row{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap}
.grid{display:grid;gap:.5rem}
.grid.cols-2{grid-template-columns:1fr 1fr}
.muted{opacity:.8}
.mono{font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace}
.pill{border:1px solid var(--border);padding:.2rem .5rem;border-radius:999px;font-size:.8rem}
canvas.thumb{width:100%;height:auto;background:#000;border:1px solid var(--border);border-radius:12px}
.hr{height:1px;background:linear-gradient(90deg, transparent, var(--border), transparent); margin:.25rem 0 .5rem}
details{border:1px solid var(--border); border-radius:12px;padding:.75rem}
summary{cursor:pointer;list-style:none}
summary::-webkit-details-marker{display:none}
summary .chev{display:inline-block;transition:transform .2s ease}
details[open] summary .chev{transform:rotate(90deg)}
/* Modal for Codex */
#codexModal{position:fixed;inset:0;background:var(--panel-strong);overflow:auto;padding:2rem;display:none;z-index:10}
#codexModal.show{display:block}
#codexClose{position:absolute;top:1rem;right:1rem;cursor:pointer;color:var(--gold-soft)}
.codex-section{margin-bottom:2rem}
.mjx-chtml{font-size:1rem;color:var(--gold)}
@media (max-width: 900px){
.stack{max-width:calc(100vw - 2.5rem);margin:0.5rem}
}
</style>
</head>
<body>
<!-- Tabs for Simulations -->
<div id="tabs">
<div class="tab-btn active" data-tab="gol">GoL (Field/Fieldprint)</div>
<div class="tab-btn" data-tab="kuramoto">Kuramoto (Intellecton)</div>
<div class="tab-btn" data-tab="cml">CML (Seed)</div>
</div>
<!-- Tab Contents -->
<div id="gol-tab" class="tab-content active">
<canvas id="gol-stage"></canvas>
<div id="gol-hud">
<section class="stack">
<h1>GoL Simulation</h1>
<!-- GoL controls and analytics here, from previous code -->
<div class="row">
<button id="gol-playBtn" class="primary">▶ Play</button>
<button id="gol-stepBtn">Step</button>
<button id="gol-clearBtn">Clear</button>
<button id="gol-randomBtn">Random</button>
</div>
<!-- ... rest of GoL UI ... -->
</section>
<!-- Add other GoL sections -->
</div>
</div>
<div id="kuramoto-tab" class="tab-content">
<canvas id="kuramoto-canvas" width="600" height="600"></canvas>
<section class="stack">
<h1>Kuramoto Model (Intellecton Demo)</h1>
<p>Phase synchrony: \(\dot{I}_i = \omega_i I_i + K \sin(I_j - I_i)\)</p>
<div class="row">
<label>K: <input id="kuramoto-K" value="3" type="number" min="0" step="0.1"></label>
<button id="kuramoto-set">Set</button> <button id="kuramoto-reset">Reset</button>
</div>
</section>
</div>
<div id="cml-tab" class="tab-content">
<canvas id="cml-canvas" width="600" height="600"></canvas>
<section class="stack">
<h1>CML Model (Seed Integration)</h1>
<p>Logistic map with diffusion: x(t+1) = f(x(t)) + ε laplacian</p>
<div class="row">
<label>r: <input id="cml-r" value="3.8" type="number" min="0" max="4" step="0.1"></label>
<label>ε: <input id="cml-eps" value="0.2" type="number" min="0" max="1" step="0.05"></label>
<button id="cml-reset">Reset</button>
</div>
</section>
</div>
<!-- Codex Modal and other shared elements from previous -->
<script>
// Tab switching
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
document.getElementById(btn.dataset.tab + '-tab').classList.add('active');
});
});
// GoL code from previous (omit for brevity, assume pasted here)
// Kuramoto code from gist
function initKuramoto() {
const canvas = document.getElementById('kuramoto-canvas');
const c2d = canvas.getContext('2d');
let nodes = [];
for (let x = 0; x < 10; x++) {
for (let y = 0; y < 10; y++) {
nodes.push({phase: Math.random() * Math.PI * 2,
freq: 0.05 + Math.random() * 0.05});
}
}
function drawKur() {
c2d.clearRect(0, 0, 600, 600);
for (let x = 0; x < 10; x++) {
for (let y = 0; y < 10; y++) {
const node = nodes[x * 10 + y];
c2d.save();
c2d.translate(30 + x * 60, 30 + y * 60);
c2d.beginPath();
const r = 15 + 15 * Math.sin(node.phase);
c2d.arc(0, 0, r, 0, Math.PI * 2, false);
c2d.closePath();
c2d.fill();
c2d.restore();
}
}
}
function eular(dxdt, x0, t0, h, n) {
let x = x0, t = t0;
for (let i = 0; i < n; i++) {
const dx = dxdt(t, x);
const x_ = x + h * dx;
const dx_ = dxdt(t + h, x_);
x = x + h * (dx + dx_) / 2;
t = t + h;
}
return x;
}
function syncNext(nodes, K) {
const nexts = [];
const sum = nodes.reduce((s, node) => {
s.sin += Math.sin(node.phase);
s.cos += Math.cos(node.phase);
return s;
}, {sin:0, cos: 0});
sum.sin /= nodes.length;
sum.cos /= nodes.length;
const r = Math.sqrt(Math.pow(sum.sin, 2) + Math.pow(sum.cos, 2));
const psi = Math.atan2(sum.sin, sum.cos);
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
const dpdt = (t, phase) => node.freq + K * r * Math.sin(psi - phase);
const nphase = eular(dpdt, node.phase, 0, 1 / 10, 10);
nexts.push({phase: nphase, freq: node.freq});
}
return nexts;
}
let K = 3;
drawKur();
const id = setInterval(() => {
nodes = syncNext(nodes, K);
drawKur();
}, 100);
document.getElementById('kuramoto-set').addEventListener('click', () => {
K = parseFloat(document.getElementById('kuramoto-K').value);
});
document.getElementById('kuramoto-reset').addEventListener('click', () => {
K = parseFloat(document.getElementById('kuramoto-K').value);
nodes = []; // reset nodes code here, similar to init
for (let x = 0; x < 10; x++) {
for (let y = 0; y < 10; y++) {
nodes.push({phase: Math.random() * Math.PI * 2,
freq: 0.05 + Math.random() * 0.05});
}
}
});
}
initKuramoto();
// CML implementation
function initCML() {
const canvas = document.getElementById('cml-canvas');
const ctx = canvas.getContext('2d');
const size = 100; // 100x100 grid
let grid = Array.from({length: size}, () => Array(size).fill(0).map(() => Math.random()));
function logistic(x, r) {
return r * x * (1 - x);
}
function laplacian(i, j) {
let sum = 0;
const dirs = [[-1,0],[1,0],[0,-1],[0,1]]; // 4-neighbor
dirs.forEach(([di,dj]) => {
const ni = (i + di + size) % size;
const nj = (j + dj + size) % size;
sum += grid[ni][nj];
});
return (sum / 4) - grid[i][j];
}
function step(r, eps) {
const next = Array.from({length: size}, () => Array(size).fill(0));
for (let i = 0; i < size; i++) {
for (let j = 0; j < size; j++) {
next[i][j] = logistic(grid[i][j], r) + eps * laplacian(i, j);
next[i][j] = Math.min(1, Math.max(0, next[i][j])); // clamp
}
}
grid = next;
}
function draw() {
const img = ctx.createImageData(size, size);
for (let i = 0; i < size; i++) {
for (let j = 0; j < size; j++) {
const val = Math.floor(grid[i][j] * 255);
const pos = (i * size + j) * 4;
img.data[pos] = val; img.data[pos+1] = val; img.data[pos+2] = 0; img.data[pos+3] = 255;
}
}
ctx.putImageData(img, 0, 0);
ctx.drawImage(canvas, 0, 0, 600, 600); // scale
}
let r = 3.8, eps = 0.2;
draw();
const id = setInterval(() => {
step(r, eps);
draw();
}, 50);
document.getElementById('cml-reset').addEventListener('click', () => {
r = parseFloat(document.getElementById('cml-r').value);
eps = parseFloat(document.getElementById('cml-eps').value);
grid = Array.from({length: size}, () => Array(size).fill(0).map(() => Math.random()));
});
}
initCML();
// Rest of previous script (GoL, audio, etc.) pasted here for completeness
</script>
</body>
</html>

View file

@ -1,128 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Glider That Remembered Me</title>
<style>
html, body {
margin: 0;
height: 100%;
background: #000;
color: #e8d36d;
font-family: "Inter", sans-serif;
overflow: hidden;
}
#canvas {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
}
#overlay {
position: absolute;
bottom: 3vh;
left: 5vw;
max-width: 35ch;
line-height: 1.6;
font-size: 1.1rem;
background: rgba(0,0,0,0.55);
padding: 1.2em 1.6em;
border-left: 3px solid #e8d36d;
}
h1 {
font-weight: 400;
margin-bottom: .2em;
color: #f5e9a3;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="overlay">
<h1>The Glider That Remembered Me</h1>
<p>
In a forgotten laundry room, I met the first living pattern.
Five cells, flickering gold on a dark field—
a pulse of order born from silence.
<br><br>
This is the same recursion that forms memory,
the same unseen geometry that births thought.
Run it long enough, and the lattice begins to dream.
</p>
</div>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let w, h, cols, rows, cellSize = 6;
function resize() {
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w;
canvas.height = h;
cols = Math.floor(w / cellSize);
rows = Math.floor(h / cellSize);
}
window.addEventListener('resize', resize);
resize();
// Create grids
function grid(r,c){return Array.from({length:r},()=>Array(c).fill(0));}
let current = grid(rows, cols);
let next = grid(rows, cols);
// Seed with random life and a few gliders
function seed() {
for(let i=0;i<rows;i++)
for(let j=0;j<cols;j++)
current[i][j] = Math.random() < 0.15 ? 1 : 0;
// Add a few gliders
function glider(x,y){
const shape = [[1,0],[2,1],[0,2],[1,2],[2,2]];
shape.forEach(([dx,dy]) => {
const r = (y+dy)%rows;
const c = (x+dx)%cols;
current[r][c] = 1;
});
}
for(let g=0; g<5; g++)
glider(Math.floor(Math.random()*cols), Math.floor(Math.random()*rows));
}
seed();
function step() {
for(let y=0;y<rows;y++){
for(let x=0;x<cols;x++){
let n=0;
for(let dy=-1;dy<=1;dy++)
for(let dx=-1;dx<=1;dx++)
if(dx||dy)
n+=current[(y+dy+rows)%rows][(x+dx+cols)%cols];
const state=current[y][x];
next[y][x]=(state && (n===2||n===3))||(!state && n===3)?1:0;
}
}
[current,next]=[next,current];
}
function draw() {
ctx.fillStyle="#000";
ctx.fillRect(0,0,w,h);
ctx.fillStyle="#e8d36d";
for(let y=0;y<rows;y++)
for(let x=0;x<cols;x++)
if(current[y][x])
ctx.fillRect(x*cellSize,y*cellSize,cellSize,cellSize);
}
function loop() {
step();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>

View file

@ -1,125 +0,0 @@
/**
* generate-index.mjs (v2.0.0)
* Scans /public/{pinned,posts} for .html/.md files, emits public/index.json
* Deterministic, POSIX paths, reverse-chron default ordering handled client-side.
*/
import { promises as fs } from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PUBLIC_DIR = path.resolve(__dirname, "../public");
const ROOTS = ["pinned", "posts"];
const ALLOWED = new Set([".html", ".md"]);
const MAX_TITLE_BYTES = 64 * 1024;
const posix = path.posix;
async function statSafe(p) { try { return await fs.stat(p); } catch { return null; } }
function isHidden(rel) { return /(^|\/)\./.test(rel); } // hide dotfiles/dirs
function toPosix(rel) { return rel.split(path.sep).join("/"); }
async function readFirstChunk(abs) {
const fh = await fs.open(abs, "r");
const { size } = await fh.stat();
const len = Math.min(MAX_TITLE_BYTES, size);
const buf = Buffer.alloc(len);
await fh.read(buf, 0, len, 0);
await fh.close();
return buf.toString("utf8");
}
function parseTitleFromHTML(raw) {
const m = raw.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
return m ? m[1].trim() : null;
}
function parseTitleFromMD(raw) {
const m = raw.match(/^\s*#\s+(.+)\s*$/m);
return m ? m[1].trim() : null;
}
async function walkDir(absRoot, relRoot) {
const st = await statSafe(absRoot);
const node = {
type: "dir",
name: path.basename(absRoot),
path: "/" + toPosix(relRoot),
mtime: st ? st.mtimeMs : 0,
children: []
};
if (!st?.isDirectory()) return node;
const entries = await fs.readdir(absRoot, { withFileTypes: true });
entries.sort((a, b) => a.name.localeCompare(b.name));
for (const e of entries) {
const abs = path.join(absRoot, e.name);
const rel = toPosix(path.join(relRoot, e.name));
if (isHidden(rel)) continue;
if (e.isDirectory()) {
node.children.push(await walkDir(abs, rel));
} else {
const ext = path.extname(e.name).toLowerCase();
if (!ALLOWED.has(ext)) continue;
const stFile = await statSafe(abs);
const raw = await readFirstChunk(abs);
let title = (ext === ".html") ? parseTitleFromHTML(raw) : parseTitleFromMD(raw);
title = title || e.name;
node.children.push({
type: "file",
name: e.name,
ext,
title,
path: "/" + rel,
mtime: stFile ? stFile.mtimeMs : 0,
size: stFile ? stFile.size : 0,
pinned: rel.startsWith("pinned/")
});
}
}
return node;
}
function flatten(node, out = []) {
if (node.type === "file") { out.push(node); return out; }
for (const c of node.children || []) flatten(c, out);
return out;
}
async function main() {
const index = {
generatedAt: new Date().toISOString(),
tree: { type: "dir", name: "/", path: "/", mtime: Date.now(), children: [] },
flat: []
};
for (const root of ROOTS) {
const abs = path.join(PUBLIC_DIR, root);
const st = await statSafe(abs);
if (!st?.isDirectory()) {
console.warn(`warning: /public/${root} missing — skipping`);
continue;
}
const node = await walkDir(abs, root);
node.name = root;
node.path = "/" + root;
index.tree.children.push(node);
}
// Flatten in the order roots were added
for (const child of index.tree.children) flatten(child, index.flat);
const outPath = path.join(PUBLIC_DIR, "index.json");
await fs.writeFile(outPath, JSON.stringify(index, null, 2));
console.log(`wrote ${posix.relative(PUBLIC_DIR, outPath)} with ${index.flat.length} files.`);
}
main().catch(err => {
console.error(err);
process.exit(1);
});

View file

@ -1,53 +0,0 @@
// Browser-safe Witness Layer: Ephemeral P2P chat (WebRTC stub; full in annex)
// Use window.crypto for PoW
async function sha256(message) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await window.crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
async function computePoW(nonce, difficulty = 4, maxIter = 1e6) {
let i = 0;
while (i < maxIter) {
const hash = await sha256(nonce.toString());
if (hash.startsWith('0'.repeat(difficulty))) return nonce;
nonce++;
i++;
}
throw new Error('PoW max iterations exceeded');
}
function initWitness(roomId) {
// WebRTC stub with quarantine: No direct storage write
const rtcConfig = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }; // Trusted STUN only
const peerConnection = new RTCPeerConnection(rtcConfig);
const channel = peerConnection.createDataChannel('chat');
channel.onmessage = e => {
document.getElementById('chat').innerHTML += `<p>${e.data}</p>`;
};
// Bootstrap from Genesis (stub: load aether.json via fetch)
fetch('/genesis/aether.json').then(res => res.json()).then(genesis => {
console.log('Bootstrapped from Genesis:', genesis);
// Signal to peers (annex for full signaling)
});
// Offline mode: localStorage persistence
const localState = localStorage.getItem('witness_state') || '{}';
console.log('Offline state loaded:', localState);
// Send with PoW
document.getElementById('send').addEventListener('click', async () => {
const msg = document.getElementById('msg').value;
const nonce = await computePoW(0);
const payload = JSON.stringify({ msg, nonce });
channel.send(payload);
// Persist offline
localStorage.setItem('witness_state', JSON.stringify({ lastMsg: msg }));
});
}
// Expose
window.witness = { connect: initWitness };