code wiki / _hdl_build / nx_video_appv2_emit.nx

nx_video_appv2_emit.nx

buildroot/runtime/_hdl_build/nx_video_appv2_emit.nx

74595 B145 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind orphan librarytopic video
docsdependenciesstructsconstsfunctions

about

nx_video_appv2_emit.nx -- GENERATED EMITTER (nx_asset_emit_gen). THIS ORGAN IS THE SSOT for sites/nishifamily/video/app.v2.js -- edit HERE (or regenerate), NEVER the emitted artifact. argv[1] overrides the target (the drift-kill seam: emit to a compare path + byte-diff). license_tier: ORIGINAL

dependencies 1 imports · 0 importers

nx_syscalls.nx nx_video_appv2_emit.nx

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

structs

none

consts

7const P0: *u8 = "// app.v2.js -- Nishi Family Video TIER-2 client (STAGED): striped shard-lanes + core FEC + 0x43 chat.\n// Lane = shard-lane ROOM (room, room#1, room#2): video frames are FEC-packed BY THE CORE into 10\n// shards striped across lanes -- one lane's TCP stall = a recoverable erasure (any 8-of-10 rebuild,\n// gate nx_vc_fecwire_gate 6/6). Lane 0 carries control+audio+chat. Chat rides binary kind 0x43\n// packed/parsed BY THE CORE (no JSON on the chat wire). Flip = point index.html at this file.\n// LAST-MILE SHIM ONLY (the doctrine header below still governs).\n//\n// Operator 2026-06-10: \"we dont want to use javascript or anything except\n// as a last mile translation for 3rd party browsers.\"\n//\n// ALL format, protocol, and sample logic lives in nx_video_client.wasm --\n// NishiLang (runtime/nx_video_client_wasm.nx), compiled by the team's own\n// toolchain, cross-gated natively against nx_nv1.nx (nx_vc_gate 8/8) and\n// smoked as the shipped artifact. What remains HERE is the named last-mile\n// bridge to the 3rd-party browser runtime:\n// - mount the wasm core + move bytes in/out of its linear memory\n// - platform primitives the browser gates behind JS APIs: getUserMedia,\n// canvas pix"
8const P1: *u8 = "els (JPEG encode/decode), AudioContext buffers, WebSocket\n// - DOM glue (tiles, buttons, toasts)\n// Named residual JS-logic debts (replacement = more core exports):\n// - rate-mismatch linear-interp playback fallback (sinc-in-core rung named)\n// - jitter-buffer playhead arithmetic against actx.currentTime\n//\n// Every media byte still flows browser --wss:443--> nx_sites_daemon_v2\n// --pump--> nx_signaling_v2 --broadcast--> peers. NO WebRTC.\n// Circles = NV1 NishiLossless (PCM at native rate, packed by the core);\n// legacy .webm circles remain playable read-only.\n\n(() => {\n \"use strict\";\n\n // ---------- tunables ----------\n const VID_W = 320, VID_H = 240;\n const BUILD = 761; // client build -- rides every hello + ver.txt; a stale client SELF-heals (reload), never the user's job (operator 2026-07-05)\n // fps/q ladder TABLE lives in the core\n const RTT_DEGRADE_MS = 400;\n const RTT_RECOVER_MS = 180;\n const BACKPRESSURE_MAX = 65536; // ~0.3s at room load; video skips, audio never queues deep\n const AUDIO_CHUNK = 1024; // 21ms frames (was 85ms) -- latency cut\n const PING_PERIOD_MS = 5000;\n const PEER_TIMEOUT_MS = 12000;\n const MAX_CIRCLE_MS = 60000;\n\n // ---"
9const P2: *u8 = "------- the sovereign core (wasm) ----------\n let NX = null; // exports of nx_video_client.wasm\n const B = BigInt;\n const U8 = () => new Uint8Array(NX.memory.buffer);\n const DV = () => new DataView(NX.memory.buffer);\n const I64 = (off) => Number(DV().getBigInt64(off, true));\n // linear-memory regions (core's statics live in its first 16 pages;\n // everything below is in the +64MB the shim grows at mount)\n const R_ID = 0x200000, R_PAY = 0x200100, R_WOUT = 0x220000, R_WIN = 0x240000,\n R_INFO = 0x260000, R_F32 = 0x270000, R_FOUT = 0x280000,\n R_PCM = 0x290000, R_SCR = 0x2A0000,\n R_STAGE = 0x300000, R_STAGE2 = 0x400000,\n R_NV1 = 0x1000000, R_NV1IN = 0x2000000,\n R_FTBL = 0x3000000, R_FSD = 0x3010000, R_FSS = 0x3020000, R_FOUT2 = 0x3030000,\n R_FSCRA = 0x3040000, R_FSCRSH = 0x3050000, R_FDEC = 0x3060000,\n R_CHAT = 0x3080000, R_FST = 0x3100000, // FEC tables/scratch, chat pack, per-peer collectors\n R_PLAN = 0x2B0000, // mb_plan output (9 i64) -- the resource-intelligence API region\n R_UIC = 0x2B1000, // nx_video_ui_core UiState (6 i64) -- SOVEREIGN call-UI state machine (task #36)\n // S"
10const P3: *u8 = "OVEREIGN CODEC regions (task #27, kind 0x57): TX rgba/yuv ping-pong + wire stream, RX staging +\n // per-sender prev/recon slots. 320x240 YUV420 = 115200B; rgba = 307200B. All inside the +64MB grow.\n R_VVTX = 0x3400000, // +0 rgba, +0x50000 cur, +0x70000 yuvA, +0x90000 yuvB, +0xB0000 wire out, +0xF0000 blk, +0xF0100 mv\n R_VVIN = 0x3500000, // RX wire staging (256KB)\n R_VVRX = 0x3600000; // per-sender slots x8, stride 0x90000: +0 yuvA, +0x20000 yuvB, +0x40000 rgba\n // sovereign call-UI INTENTS (nx_video_ui_core) -- the adapter maps a click to ONE of these; the core\n // owns the resulting state (mic/cam/swap). Same intents drive the NishiOS adapter.\n const UI_TOGGLE_MIC = 1, UI_TOGGLE_CAM = 2, UI_PEER_JOIN = 3, UI_PEER_LEAVE = 4, UI_SWAP_VIEW = 5;\n async function mountCore() {\n const r = await fetch(\"/video/nx_video_client.wasm?v=\" + BUILD); // cache-bust with the script (stale wasm = no vv_ = no codec)\n if (!r.ok) throw new Error(\"core fetch \" + r.status);\n const { instance } = await WebAssembly.instantiate(await r.arrayBuffer(),\n { env: { nx_syscall: () => 0n } });\n instance.exports.memory.grow(1024); // room"
11const P4: *u8 = " for NV1 circle packing + FEC regions\n NX = instance.exports;\n NX.vc_fec_init(B(R_FTBL)); // GF(256) tables + [I;Cauchy] generator, once\n if (NX.uic_init) NX.uic_init(B(R_UIC)); // init the SOVEREIGN call-UI state machine (task #36)\n // MEASURED cpu class (field call 2026-07-05: cores+memory GUESSED phones into tier 0-2 -> 5/12fps caps\n // while bp=0 showed the pipe was fine). Benchmark the REAL encoder 3x on a synthetic frame, take the\n // median ms, derive cls from measured capability. Measurement beats heuristics -- self-calibrating.\n try {\n if (NX.vv_enc) {\n const u = U8(); // realistic content (an all-flat frame is all-DC = unrealistically fast to encode)\n for (let i = 0; i < 115200; i++) u[R_VVTX + 0x50000 + i] = (i * 31 + ((i >> 7) * 17)) & 255;\n const t = [];\n for (let i = 0; i < 3; i++) {\n const t0 = performance.now();\n NX.vv_enc(B(R_VVTX + 0x50000), B(R_VVTX + 0x70000), B(R_VVTX + 0x90000), B(VID_W), B(VID_H),\n B(32), B(1), B(6016), B(R_VVTX + 0xB0000 + 6), B(0x40000 - 6), B(R_VVTX + 0xF0000), B(R_VVTX + 0xF0100));\n t.push(performance.now() - t0);\n }"
12const P5: *u8 = "\n t.sort((a, b) => a - b); encMs = Math.max(1, Math.round(t[1]));\n // key-frame encode ms -> cls: 60fps headroom needs ~<8ms; each step roughly doubles the budget\n clsMeasured = encMs <= 8 ? 9 : encMs <= 12 ? 8 : encMs <= 18 ? 7 : encMs <= 26 ? 6 : encMs <= 40 ? 5 : encMs <= 60 ? 4 : encMs <= 90 ? 3 : 2;\n }\n } catch (e) { /* benchmark is a nice-to-have; heuristics remain the fallback */ }\n replan(); // first resource-intelligence plan (sensors -> core)\n }\n const coreReady = mountCore().catch(e => { console.error(e); say(\"core failed to load: \" + e.message); });\n startWorker(); // codec worker (gap #1): its own wasm instance; falls back to sync paths until ready\n\n // ---------- DOM ----------\n const $ = (id) => document.getElementById(id);\n const lobby = $(\"lobby\"), stage = $(\"stage\"), circlesView = $(\"circles\");\n const roomIn = $(\"room\"), nameIn = $(\"name\");\n const peersDiv = $(\"peers\"), roomLabel = $(\"roomLabel\"), netLabel = $(\"netLabel\");\n const toast = $(\"toast\");\n\n // room/name/join come from ?query (the iframe-embed URL) OR #hash (invite links); query wins.\n const qs = new URLSearchParams(location"
13const P6: *u8 = ".search);\n const hashParams = new URLSearchParams(location.hash.slice(1));\n const qp = (k) => qs.get(k) || hashParams.get(k);\n if (qp(\"room\")) roomIn.value = qp(\"room\").slice(0, 24);\n nameIn.value = qp(\"name\") ? qp(\"name\").slice(0, 16) : (localStorage.getItem(\"nishi_name\") || \"\");\n const myId = (Math.random().toString(36).slice(2) + \"00000000\").slice(0, 8);\n\n let ws = null, localStream = null;\n let room = \"\", me = \"\";\n // ---------- SELF-UPGRADE (never rely on the user to refresh): a stale client detects a newer build --\n // via a peer's hello (v) or the ver.txt poll -- announces, saves auto-rejoin state, reloads itself. ----\n // WAKE LOCK (759): rivals hold one; without it a phone screen dims/locks mid-call -> the browser clamps\n // timers to ~1/s -> that participant collapses to ~1fps TX (the exact worstTx=1 signature measured live).\n let wakeLk = null;\n async function wlAcquire() {\n try {\n if (navigator.wakeLock && !wakeLk && joined) {\n wakeLk = await navigator.wakeLock.request(\"screen\");\n wakeLk.addEventListener(\"release\", () => { wakeLk = null; });\n }\n } catch (e) { /* not supported / denied -> bg flag in the beacon tells the story */"
14const P7: *u8 = " }\n }\n document.addEventListener(\"visibilitychange\", () => { if (!document.hidden) wlAcquire(); });\n // FIELD ERROR SURFACE (760): any uncaught error is SHOWN to the user AND rides the next QoE beacon --\n // the next field bug names itself in room_telemetry.log instead of being \"the buttons are broken\".\n let lastErr = \"\";\n window.addEventListener(\"error\", (e) => {\n lastErr = String((e && e.message) || \"err\").slice(0, 48);\n try { say(\"\xe2\x9a\xa0 \" + lastErr); } catch {}\n });\n let upPending = false;\n function staleSelf(target) {\n if (upPending) return;\n try {\n if (sessionStorage.getItem(\"nx_up\") === String(target)) return; // loop guard: one reload per target build\n sessionStorage.setItem(\"nx_up\", String(target));\n if (joined && room) sessionStorage.setItem(\"nx_rejoin\", room); // land back IN the call after the reload\n } catch {}\n upPending = true;\n say(\"updating video engine\xe2\x80\xa6\");\n setTimeout(() => location.reload(), 2500);\n }\n function pollVer() {\n fetch(\"/video/ver.txt?_=\" + Date.now(), { cache: \"no-store\" })\n .then(r => r.ok ? r.text() : \"\")\n .then(t => { const v = parseInt(t) || 0; if (v > BUILD) staleSelf(v); })\n "
15const P8: *u8 = " .catch(() => {});\n }\n let joined = false;\n let micOn = true, camOn = true;\n const peers = new Map();\n let nvr = null, recTimer = null, recStartT = 0;\n let circPriv = false;\n\n function say(msg) {\n toast.textContent = msg;\n toast.style.opacity = 1;\n clearTimeout(say._t);\n say._t = setTimeout(() => { toast.style.opacity = 0; }, 2600);\n }\n const cleanName = (s, fallback) =>\n (s || fallback).toLowerCase().replace(/[^a-z0-9-]/g, \"\").slice(0, 24) || fallback;\n\n // ---------- wire frames: PACKED AND PARSED BY THE CORE ----------\n function wirePackPtr(kind, seq, payPtr, payLen) {\n const n = Number(NX.vc_wire_pack(B(R_WOUT), B(kind), B(R_ID), B(seq), B(payPtr), B(payLen)));\n return U8().slice(R_WOUT, R_WOUT + n);\n }\n function wirePack(kind, seq, payloadU8) {\n U8().set(payloadU8, R_PAY);\n return wirePackPtr(kind, seq, R_PAY, payloadU8.length);\n }\n function wireParse(buf) {\n const b = new Uint8Array(buf);\n if (b.length > 65536) return null;\n U8().set(b, R_WIN);\n if (Number(NX.vc_wire_parse(B(R_WIN), B(b.length), B(R_INFO))) !== 0) return null;\n let id = \"\";\n for (let i = 1; i < 9; i++) id += String.fromCharCode(b[i]);\n return { ki"
16const P9: *u8 = "nd: I64(R_INFO), id, seq: I64(R_INFO + 8), payload: b.subarray(13) };\n }\n\n // ---------- signaling + media: striped shard-lanes ----------\n // lane 0 = the plain room (control JSON + audio + 0x43 chat + its shard share);\n // lanes 1..2 = shard-lane rooms room#1/room#2 (video FEC shards only). A lane that is\n // down at send time rebalances its shards onto lane 0 (skilled degradation, tier 3).\n const LANES = 3;\n let lanes = [null, null, null];\n const laneUp = (l) => lanes[l] && lanes[l].readyState === 1;\n // FIELD-HARDENING 2026-07-05 (real 3-person call: peer invisible until 3rd join + 4fps chop): EVERYTHING\n // rode lane 0 -- hello/ping/audio/chat died with it, and media DEAD-DROPPED to lane 0 instead of failing\n // over. Root of both symptoms. Now every send scans for a LIVE lane (lowest buffered = least congested);\n // lane 0 is a preference, never a single point of failure.\n function bestLane(pref) {\n if (pref !== undefined && laneUp(pref) && lanes[pref].bufferedAmount <= BACKPRESSURE_MAX) return lanes[pref];\n let bw = null;\n for (let l = 0; l < LANES; l++) {\n const w = lanes[l];\n if (!w || w.readyState !== 1) continue;\n if (!bw || w.buffere"
17const P10: *u8 = "dAmount < bw.bufferedAmount) bw = w;\n }\n return bw;\n }\n let bpSkips = 0, txSent = 0, lastRtt = -1; // QoE window counters (beaconed + drive the bp ladder step)\n function wsSendJson(obj) {\n const w = (ws && ws.readyState === 1) ? ws : bestLane();\n if (w) w.send(JSON.stringify(obj));\n }\n function sendLane(i, bytes) {\n const w = bestLane(i % LANES);\n if (!w) return;\n if (w.bufferedAmount > BACKPRESSURE_MAX) { bpSkips++; return; }\n w.send(bytes);\n }\n function sendCtl(bytes) { // audio/chat: any live lane, buffer-aware (never lane-0-only)\n const w = bestLane();\n if (w && w.bufferedAmount <= BACKPRESSURE_MAX) w.send(bytes); else bpSkips++;\n }\n function tierNow() { return (laneUp(1) || laneUp(2)) ? 2 : 3; }\n\n function connectLane(l) {\n const w = new WebSocket(`wss://${location.host}/signal/${encodeURIComponent(room + (l ? \"#\" + l : \"\"))}`);\n w.binaryType = \"arraybuffer\";\n w._rxAt = performance.now(); // lane-watchdog baseline (half-open-socket killer)\n if (l === 0) {\n w.onopen = () => {\n netLabel.textContent = \"relay: connected\";\n wsSendJson({ from: myId, type: \"hello\", name: me, vc"
18const P11: *u8 = ": 2, v: BUILD, ts: performance.now() }); // vc:2 codec+geo-flex; v self-upgrade; ts ack-RTT\n };\n }\n w.onclose = () => {\n if (l === 0) { netLabel.textContent = \"relay: reconnecting\xe2\x80\xa6\"; }\n lanes[l] = null;\n if (l === 0) ws = null;\n if (joined) setTimeout(() => {\n if (joined && !lanes[l]) { lanes[l] = connectLane(l); if (l === 0) ws = lanes[l]; }\n }, 1200);\n };\n w.onmessage = (ev) => { w._rxAt = performance.now(); onWsMessage(ev); };\n return w;\n }\n function connectRoom() {\n for (let l = 0; l < LANES; l++) lanes[l] = connectLane(l);\n ws = lanes[0];\n }\n // ONE join-scoped CONTROL LOOP on ANY live lane (was lane-0's private interval -> it DIED with lane 0,\n // taking RTT feedback + peer-timeout with it): ping(RTT) + PRESENCE re-announce (a lost hello self-heals\n // <=5s -- the invisible-peer fix) + peer sweep + half-open lane watchdog + backpressure ladder step +\n // the QoE BEACON (active performance telemetry -- the field call had NONE, so nothing showed the 4fps).\n let ctlTimer = null, ctlTick = 0;\n function startCtl() {\n clearInterval(ctlTimer);\n ctlTick = 0;\n ctlTimer = setInterval(() => {\n if (!join"
19const P12: *u8 = "ed) return;\n ctlTick++;\n const now = performance.now();\n wsSendJson({ from: myId, type: \"ping\", t: now });\n wsSendJson({ from: myId, type: \"hello\", name: me, vc: 2, v: BUILD, ts: now,\n mi: micOn ? 1 : 0, ca: camOn ? 1 : 0 }); // idempotent presence (+ts ack-RTT, +mi/ca live state)\n if (ctlTick % 6 === 0) pollVer(); // self-upgrade check every ~30s (server-side healing, not the user's job)\n for (const [id, p] of peers) if (now - p.lastSeen > PEER_TIMEOUT_MS) dropPeer(id);\n for (let l = 0; l < LANES; l++) { // a lane \"open\" but silent >2 pings = zombie -> close -> reconnect path\n const w = lanes[l];\n if (w && w.readyState === 1 && peers.size > 0 && now - w._rxAt > 2.2 * PING_PERIOD_MS) { try { w.close(); } catch {} }\n }\n if (bpSkips > 8) ladderIdx = Math.min(NRUNGS() - 1, effLadderIdx() + 1); // pipe too small -> step DOWN (smooth 8fps beats choppy 4)\n if (ctlTick % 2 === 0) { // QoE beacon every 2nd tick (~10s)\n let fpsRxMin = -1;\n for (const [, p] of peers) if (p.fpsLast >= 0) fpsRxMin = fpsRxM"
20const P13: *u8 = "in < 0 ? p.fpsLast : Math.min(fpsRxMin, p.fpsLast);\n const tiles = peersDiv.querySelectorAll(\".tile:not(.self)\").length;\n wsSendJson({ from: myId, type: \"qoe\", name: me, fpsTx: Math.round(txSent / 10), fpsRxMin: Math.round(fpsRxMin),\n rtt: Math.round(lastRtt), bp: bpSkips, lanes: [laneUp(0) ? 1 : 0, laneUp(1) ? 1 : 0, laneUp(2) ? 1 : 0],\n peers: peers.size, tiles, mm: tiles !== peers.size ? 1 : 0, tier: planTier, fpsCap: rungFps(),\n vc57: vcAll() ? 1 : 0, cls: clsMeasured, encMs, vo: planVideoOn ? 1 : 0,\n bg: document.hidden ? 1 : 0, wl: wakeLk ? 1 : 0, wk: wkReady ? 1 : 0, err: lastErr }); // + bg/wake-lock/worker/last-error -> failures NAME themselves\n txSent = 0; bpSkips = 0;\n }\n }, PING_PERIOD_MS);\n }\n const onWsMessage = (ev) => {\n if (typeof ev.data === \"string\") {\n let m;\n try { m = JSON.parse(ev.data); } catch { return; }\n if (!m || m.from === myId) return;\n if (m.to && m.to !== myId) return;\n if (m.type === \"hello\") {\n const hp = ensurePeer(m.from, m.name); hp.lastSeen = performance.now(); hp.vcv = m.vc | 0; hp.vc"
21const P14: *u8 = " = hp.vcv >= 1;\n if (m.mi !== undefined) { hp.mi = m.mi; hp.ca = m.ca; applyPeerState(hp); } // live mute/cam state -> tile badges (not a frozen frame)\n if ((m.v | 0) > BUILD) staleSelf(m.v | 0); // a newer peer = I'm stale -> self-heal\n wsSendJson({ from: myId, to: m.from, type: \"hello-ack\", name: me, vc: 2, v: BUILD, hts: m.ts }); // echo ts -> ack-RTT (2nd RTT source)\n } else if (m.type === \"hello-ack\") {\n const ap = ensurePeer(m.from, m.name); ap.lastSeen = performance.now(); ap.vcv = m.vc | 0; ap.vc = ap.vcv >= 1;\n if ((m.v | 0) > BUILD) staleSelf(m.v | 0);\n if (m.hts) onRtt(performance.now() - m.hts); // redundant RTT path (pong path measured -1 in the field -> two eyes)\n } else if (m.type === \"ping\") {\n wsSendJson({ from: myId, to: m.from, type: \"pong\", t: m.t });\n const p = peers.get(m.from); if (p) p.lastSeen = performance.now();\n } else if (m.type === \"pong\") {\n onRtt(performance.now() - m.t);\n } else if (m.type === \"kreq\") {\n vvForceKey = true; // a receiver lost the chain -> key NOW (our P"
22const P15: *u8 = "LI)\n } else if (m.type === \"bye\") {\n dropPeer(m.from);\n }\n return;\n }\n const f = wireParse(ev.data);\n if (!f || f.id === myId) return;\n const p = ensurePeer(f.id, null);\n p.lastSeen = performance.now();\n if (f.kind === 0x56) drawVideoFrame(p, f); // plain-frame back-compat\n else if (f.kind === 0x57) rxVv(p, f); // SOVEREIGN codec frame (task #27)\n else if (f.kind === 0x46) rxShard(p, f); // FEC shard -> core collector\n else if (f.kind === 0x41) queueAudio(f.payload); // raw PCM (back-compat)\n else if (f.kind === 0x4C) queueAudioL(f.payload); // LPC lossless (core decodes)\n else if (f.kind === 0x43) rxChat(f); // chat, core-parsed (no JSON)\n };\n\n // ---------- FEC shard RX: the CORE collects + rebuilds (any 8-of-10, out of order) ----------\n const fecSlots = new Map(); // sender id -> collector slot\n function rxShard(p, f) {\n if (!NX) return;\n let slot = fecSlots.get(f.id);\n if (slot === undefined) {\n if (fecSlots.size >= 8) return;\n slot = fecSlots.size;\n fecSlo"
23const P16: *u8 = "ts.set(f.id, slot);\n NX.vc_fecrx_reset(B(R_FST + slot * 0x10000));\n }\n U8().set(f.payload, R_FSS);\n const rc = Number(NX.vc_fecrx_add(B(R_FST + slot * 0x10000), B(R_FTBL), B(R_FSS),\n B(f.payload.length), B(R_FSCRA), B(R_FSCRSH), B(R_FDEC), B(0xFF00))); // outcap=65280: n*S bound (safe-by-construction), all 4 regions are 64KB >= this\n if (rc > 0) drawVideoFrame(p, { seq: f.seq, payload: U8().slice(R_FDEC, R_FDEC + rc) });\n }\n // ---------- SOVEREIGN codec RX (kind 0x57): per-sender prev/recon slots, decode chain guarded ----------\n const vvSlots = new Map(); // sender id -> slot index (cap 8)\n function kreq(p, id) { // request a keyframe from `id` (our PLI)\n const t = performance.now();\n if (t - (p.vvKreqAt || 0) < 1000) return;\n p.vvKreqAt = t;\n wsSendJson({ from: myId, to: id, type: \"kreq\" });\n }\n const vvScratch = document.createElement(\"canvas\"); // scaled-draw staging (geometry-flex RX)\n vvScratch.width = VID_W; vvScratch.height = VID_H;\n const vvScratchCtx = vvScratch.getContext(\"2d\");\n function rxVv(p, f) {\n if (!NX || !NX.vv_dec || f.payload.length "
24const P17: *u8 = "< 18) return;\n const key = (f.payload[0] & 1) === 1;\n const qp = f.payload[1];\n const w = f.payload[2] | (f.payload[3] << 8);\n const h = f.payload[4] | (f.payload[5] << 8);\n // GEOMETRY-FLEX (vc:2): accept any even geometry up to 320x240 -- the resource plan may send 160x120\n // from a weak phone (1/4 the encode cost + bits). Bounds = slot region safety (wire boundary, rule 12).\n if (w < 64 || h < 48 || w > VID_W || h > VID_H || (w & 1) || (h & 1)) return;\n let slot = vvSlots.get(f.id);\n if (slot === undefined) {\n if (vvSlots.size >= 8) return;\n slot = vvSlots.size; vvSlots.set(f.id, slot);\n p.vvWaitKey = true;\n }\n // CHAIN INTEGRITY: P-frames only decode against the exact previous recon. Any gap/reorder -> wait for\n // a key -- and REQUEST one instantly (kreq = our PLI, 759): recovery ~1 RTT instead of up-to-3.2s of\n // frozen video waiting for the scheduled key. Rate-limited 1/s per sender; old clients ignore kreq.\n if (f.seq <= p.vvSeq) return;\n if (!key && (w !== p.vvW || h !== p.vvH)) { p.vvWaitKey = true; kreq(p, f.id); return; }\n if (!key && f.seq !== p.vvSeq + 1) { p.vvWaitKey = true; kreq(p, f.id); return; }\n "
25const P18: *u8 = " if (!key && p.vvWaitKey) { kreq(p, f.id); return; }\n if (wkReady) { // WORKER PATH: decode OFF the main thread\n if (wkDecPend > 8) { p.vvWaitKey = true; kreq(p, f.id); return; } // decode overloaded -> honest drop + resync\n wkDecPend++;\n p.vvSeq = f.seq; p.vvWaitKey = false; // optimistic chain advance; decfail rolls back via waitKey+kreq\n const pay = f.payload.slice().buffer;\n wk.postMessage({ op: \"dec\", id: f.id, slot, pay, w, h, qp }, [pay]);\n return;\n }\n const base = R_VVRX + slot * 0x90000;\n const prev = base + (p.vvFlip === 0 ? 0 : 0x20000);\n const recon = base + (p.vvFlip === 0 ? 0x20000 : 0);\n U8().set(f.payload.subarray(6), R_VVIN);\n const rc = Number(NX.vv_dec(B(prev), B(recon), B(w), B(h), B(qp), B(R_VVIN), B(f.payload.length - 6),\n B(R_VVTX + 0xF0000), B(R_VVTX + 0xF0100)));\n if (rc !== 0) { p.vvWaitKey = true; return; } // refused (truncated/hostile) -> resync on key\n p.vvSeq = f.seq; p.vvWaitKey = false; p.vvFlip = 1 - p.vvFlip; p.vvW = w; p.vvH = h;\n NX.vv_yuv420_to_rgba(B(recon), B(w), B(h), B(base + 0x40000));\n const rgba = new Uint8C"
26const P19: *u8 = "lampedArray(U8().subarray(base + 0x40000, base + 0x40000 + w * h * 4));\n if (w === VID_W && h === VID_H) { p.ctx.putImageData(new ImageData(rgba, w, h), 0, 0); }\n else { // upscale small geometry to the tile canvas\n vvScratchCtx.putImageData(new ImageData(rgba, w, h), 0, 0);\n p.ctx.drawImage(vvScratch, 0, 0, w, h, 0, 0, VID_W, VID_H);\n }\n p.fpsCount++;\n const now = performance.now();\n if (now - p.fpsT > 2000) {\n p.fpsLast = p.fpsCount * 1000 / (now - p.fpsT);\n p.stats.textContent = `${p.fpsLast.toFixed(1)}fps`;\n p.stats.classList.toggle(\"bad\", p.fpsLast < 8);\n p.fpsCount = 0; p.fpsT = now;\n }\n }\n function rxChat(f) {\n if (!NX || f.payload.length < 2) return;\n U8().set(f.payload, R_CHAT + 4096);\n if (Number(NX.vc_chat_parse(B(R_CHAT + 4096), B(f.payload.length), B(R_INFO))) !== 0) return;\n const base = R_CHAT + 4096;\n const name = new TextDecoder().decode(U8().subarray(base + I64(R_INFO), base + I64(R_INFO) + I64(R_INFO + 8)));\n const text = new TextDecoder().decode(U8().subarray(base + I64(R_INFO + 16), base + I64(R_INFO + 16) + I64(R_INFO + 24)));\n if (!tex"
27const P20: *u8 = "t) return;\n ensurePeer(f.id, name).lastSeen = performance.now();\n addChat(name.slice(0, 24), text.slice(0, 500), false);\n }\n\n // ---------- roster / tiles (DOM glue) ----------\n function ensurePeer(id, name) {\n let p = peers.get(id);\n if (p) { if (name) { p.name = name; p.tile.querySelector(\".label\").textContent = name; } return p; }\n const tile = document.createElement(\"div\");\n tile.className = \"tile\";\n tile.innerHTML = `<canvas width=\"${VID_W}\" height=\"${VID_H}\"></canvas>\n <span class=\"label\">${name || id}</span><span class=\"stats\"></span>`;\n peersDiv.appendChild(tile);\n tile.addEventListener(\"dblclick\", () => { tile.classList.toggle(\"flipx\"); say(\"mirror \" + (tile.classList.contains(\"flipx\") ? \"on\" : \"off\")); }); // per-tile mirror fix (pre-mirroring cams)\n const canvas = tile.querySelector(\"canvas\");\n p = { tile, canvas, ctx: canvas.getContext(\"2d\"), stats: tile.querySelector(\".stats\"),\n name: name || id, lastSeen: performance.now(), vseq: -1, fpsCount: 0, fpsT: performance.now(), fpsLast: -1,\n vc: false, vcv: 0, vvSeq: -1, vvWaitKey: true, vvSlot: -1, vvFlip: 0, vvW: 0, vvH: 0 };\n peers.set(id, p);"
28const P21: *u8 = "\n vvForceKey = true; // a newcomer needs an intra frame to start decoding us -> key on next TX\n replan(); // room size is a budget input (fan-out envelope)\n callLayout(); // 1=solo, 2=duo (remote full + self PiP), 3+=grid\n return p;\n }\n // render a peer's mute/cam state on their tile (Discord/Zoom-style: badge + dimmed \"camera off\" card)\n function applyPeerState(p) {\n const lab = p.tile.querySelector(\".label\");\n if (lab) lab.textContent = p.name + (p.mi === 0 ? \" \xf0\x9f\x94\x87\" : \"\");\n p.tile.classList.toggle(\"camoff\", p.ca === 0);\n }\n function dropPeer(id) {\n const p = peers.get(id);\n if (!p) return;\n p.tile.remove();\n peers.delete(id);\n replan();\n callLayout();\n }\n // callLayout: the SOTA call framing. total = remote peers + self.\n // 1 -> solo (self fills) 2 -> duo (remote FULL-SCREEN, self a PiP corner) 3+ -> grid.\n // Fixes the operator's #1 complaint: in a 2-person call you now see THEM full with YOU in the corner.\n function callLayout() {\n // The LAYOUT LAW (1=SOLO, 2=DUO=remote-full+self-PiP, 3+=GRID) lives in the SOVEREIGN core\n // (nx_video_ui_core.uic_layout), NOT here. This shim is a thin ADAP"
29const P22: *u8 = "TER: report the peer count, ask\n // the core which layout, render it. The SAME core runs native on NishiOS -- no browser logic to rework.\n let mode;\n if (NX && NX.uic_set_peers) {\n NX.uic_set_peers(B(R_UIC), B(peers.size)); // adapter reports roster -> core derives + owns swap state\n mode = Number(NX.uic_layout(B(R_UIC))); // 1 SOLO / 2 DUO / 3 GRID (sovereign SSOT)\n } else {\n const total = peers.size + 1; mode = total <= 1 ? 1 : (total === 2 ? 2 : 3); // fallback if core not mounted yet\n }\n peersDiv.classList.toggle(\"solo\", mode === 1);\n peersDiv.classList.toggle(\"duo\", mode === 2);\n if (mode !== 2) peersDiv.classList.remove(\"swapped\");\n }\n\n // ---------- video RX: JPEG -> canvas (platform decode) ----------\n function drawVideoFrame(p, f) {\n if (f.seq <= p.vseq) return;\n p.vseq = f.seq;\n const blob = new Blob([f.payload], { type: \"image/jpeg\" });\n createImageBitmap(blob).then(bmp => {\n if (p.canvas.width !== bmp.width) { p.canvas.width = bmp.width; p.canvas.height = bmp.height; }\n p.ctx.drawImage(bmp, 0, 0);\n bmp.close();\n p.fpsCount++;\n const now = performance.now();\n if (now - p.fpsT > "
30const P23: *u8 = "2000) {\n p.fpsLast = p.fpsCount * 1000 / (now - p.fpsT);\n p.stats.textContent = `${p.fpsLast.toFixed(1)}fps`;\n p.stats.classList.toggle(\"bad\", p.fpsLast < 8); // per-tile quality indicator (a measured CALLUI gap)\n p.fpsCount = 0; p.fpsT = now;\n }\n }).catch(() => {});\n }\n\n // ---------- video TX: camera -> canvas JPEG (platform encode) ----------\n let ladderIdx = 0, vseq = 0, txTimer = null;\n const txCanvas = document.createElement(\"canvas\");\n txCanvas.width = VID_W; txCanvas.height = VID_H;\n const txCtx = txCanvas.getContext(\"2d\");\n let selfVideo = null;\n\n // effective rung = RTT ladder clamped by the CORE's N-aware room floor\n // (bigger rooms cost more fan-out; the perf gate measured the ceiling)\n const NRUNGS = () => NX ? Number(NX.vc_ladder_rungs()) : 1;\n const rungFps = () => NX ? Number(NX.vc_ladder_fps(B(effLadderIdx()))) : 8;\n const rungQ = () => NX ? Number(NX.vc_ladder_q_permille(B(effLadderIdx()))) / 1000 : 0.4;\n // ---------- RESOURCE INTELLIGENCE (mobile-first, API-first) ----------\n // The DECISION lives in the sovereign core (NX.mb_plan); this shim only reads device sensors.\n // A phone lands a lower tier (fps/heig"
31const P24: *u8 = "ht cap), a laptop lands 60fps -- same API, same core.\n let planTier = -1, planFpsCap = 0, planVideoOn = 1;\n let encMs = -1, clsMeasured = -1; // MEASURED encode capability (set by the mount-time vv_enc benchmark)\n function deviceBudget() {\n // MEASUREMENT FIRST (field call 2026-07-05): the mount benchmark timed the real encoder; that IS the\n // cpu class. The cores+memory heuristic (which guessed phones into tier 0-2 -> 5/12fps caps while the\n // pipe sat idle, bp=0) is only the fallback when the codec isn't mounted yet.\n let cls;\n if (clsMeasured >= 0) { cls = clsMeasured; }\n else {\n const cores = navigator.hardwareConcurrency || 4;\n const mem = navigator.deviceMemory || 4; // GB (Chrome/Edge; absent elsewhere)\n const mobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);\n cls = Math.min(9, Math.round(cores + Math.min(4, mem) - (mobile ? 3 : 0)));\n if (cls < 1) cls = 1;\n }\n const con = navigator.connection || {};\n // browsers expose DOWNLINK only, and phones report it junk-low (0.35 seen on LTE -> 175kbps est ->\n // tier 0 -> the 5fps cap of the 2026-07-05 call). Floor the estimate at 1000kbps: any "
32const P25: *u8 = "live cellular/\n // wifi uplink carries >=1Mbps of the SOVEREIGN codec (tier 4 = 700kbps), and the MEASURED backpressure\n // loop (bpSkips -> ladder step-down) catches the genuinely-bad pipes -- measurement over proxy.\n const uplinkKbps = con.downlink ? Math.max(1000, Math.round(con.downlink * 500)) : 5000;\n return { cls, uplinkKbps };\n }\n let batteryPct = 101; // 101 = plugged/unknown => no cap\n // DEFENSIVE: resource-intelligence is a NICE-TO-HAVE. It must NEVER break the call. getBattery() can\n // throw SYNCHRONOUSLY on some browsers/contexts (a sync throw the async .catch would miss) -> that\n // would kill every button wired AFTER this line. Wrapped so a failure here is a silent no-op.\n try {\n if (navigator.getBattery) navigator.getBattery().then(b => {\n const upd = () => { batteryPct = b.charging ? 101 : Math.round(b.level * 100); replan(); };\n b.addEventListener(\"levelchange\", upd); b.addEventListener(\"chargingchange\", upd); upd();\n }).catch(() => {});\n } catch (e) { /* battery API unavailable -> stay at 101 (no cap) */ }\n function replan() {\n try {\n if (!NX || !NX.mb_plan) return;\n const { "
33const P26: *u8 = "cls, uplinkKbps } = deviceBudget();\n NX.mb_plan(B(cls), B(uplinkKbps), B(batteryPct), B(peers.size + 1), B(R_PLAN));\n planFpsCap = I64(R_PLAN); // plan[0] = fps\n planVideoOn = I64(R_PLAN + 64); // plan[8] = video_on\n planTier = I64(R_PLAN + 56); // plan[7] = tier\n } catch (e) { planVideoOn = 1; } // any failure -> video ON, no cap (never block the call)\n }\n // budget fps cap -> the lowest ladder idx whose fps fits the plan (idx grows = quality drops)\n function planIdxFloor() {\n if (!NX || planFpsCap <= 0) return 0;\n const n = NRUNGS();\n for (let i = 0; i < n; i++) if (Number(NX.vc_ladder_fps(B(i))) <= planFpsCap) return i;\n return n - 1;\n }\n function effLadderIdx() {\n const floor = NX ? Number(NX.vc_ladder_floor(B(peers.size + 1))) : 0;\n return Math.min(NRUNGS() - 1, Math.max(ladderIdx, floor, planIdxFloor()));\n }\n function scheduleTx() {\n clearTimeout(txTimer);\n if (!joined) return;\n txTimer = setTimeout(txOneFrame, 1000 / rungFps());\n }\n // ---------- SOVEREIGN CODEC TX (task #27, kind 0x57): our vcodec replaces JPEG when the WHOLE room is\n // capable (vc:1 handshake -- one stale client "
34const P27: *u8 = "and everyone stays on JPEG: mixed-version family-safe).\n // Wire: [flags:1 bit0=key][qp:1][w:2 LE][h:2 LE][3-plane vv stream]. P-frames chain off the last recon,\n // so ORDER matters: all 0x57 ride ONE sticky lane (per-lane WSS is ordered); the lane may only change AT\n // a keyframe. Keys every VV_KEY_EVERY frames + on peer join (vvForceKey). Gate-measured at 320x240:\n // key ~7KB, P ~0.2-2KB vs JPEG ~10KB EVERY frame -> the ~8x uplink cut the field call demanded.\n const VV_KEY_EVERY = 48;\n let vvSeq = 0, vvForceKey = true, vvLane = 0, vvFlip = 0, vvTxW = VID_W, vvTxH = VID_H;\n const vcAll = () => { if (!(NX && NX.vv_enc) || peers.size === 0) return false; for (const [, p] of peers) if (!p.vc) return false; return true; };\n const geoFlexAll = () => { for (const [, p] of peers) if (p.vcv < 2) return false; return peers.size > 0; };\n const vvQp = () => Math.max(24, Math.min(48, Math.round(48 - rungQ() * 30))); // ladder q (0..1) -> codec qp\n // ---------- CODEC WORKER (760): gap #1 vs WebRTC -- encode/decode OFF the main thread. The worker owns\n // its OWN wasm instance + the recon chains (txFlip + per-slot flips); the MAIN thread keeps every\n // decision (gates, geomet"
35const P28: *u8 = "ry, keyframes, sticky lane, seq, chain integrity, kreq). Zero-copy transfers.\n // Fallback BY CONSTRUCTION: until \"ready\", the synchronous paths below run unchanged.\n let wk = null, wkReady = false, wkEncBusy = false, wkEncKey = false, wkEncLane = 0, wkDecPend = 0;\n function startWorker() {\n try {\n if (!window.Worker) return;\n const src = `\n let NX=null, U8=null; const B=BigInt;\n const RT=${R_VVTX}, RI=${R_VVIN}, RR=${R_VVRX};\n let txFlip=0; const flips=[0,0,0,0,0,0,0,0];\n onmessage = async (ev) => {\n const m = ev.data;\n if (m.op === \"init\") {\n try {\n const r = await fetch(m.url);\n const inst = (await WebAssembly.instantiate(await r.arrayBuffer(), { env: { nx_syscall: () => 0n } })).instance;\n inst.exports.memory.grow(1024);\n NX = inst.exports; U8 = () => new Uint8Array(NX.memory.buffer);\n postMessage({ op: \"ready\", ok: NX.vv_enc ? 1 : 0 });\n } catch (e) { postMessage({ op: \"ready\", ok: 0 }); }\n return;\n }\n if (!NX) return;\n if (m.op === \"enc\") {\n const t0 = performance.now();\n "
36const P29: *u8 = " U8().set(new Uint8Array(m.rgba), RT);\n NX.vv_rgba_to_yuv420(B(RT), B(m.w), B(m.h), B(RT + 0x50000));\n const prev = RT + (txFlip === 0 ? 0x70000 : 0x90000);\n const recon = RT + (txFlip === 0 ? 0x90000 : 0x70000);\n const n = Number(NX.vv_enc(B(RT + 0x50000), B(prev), B(recon), B(m.w), B(m.h), B(m.qp), B(m.key ? 1 : 0), B(m.qp * 188), B(RT + 0xB0000 + 6), B(0x40000 - 6), B(RT + 0xF0000), B(RT + 0xF0100)));\n if (n <= 0) { postMessage({ op: \"encfail\" }); return; }\n const u = U8();\n u[RT + 0xB0000] = m.key ? 1 : 0; u[RT + 0xB0000 + 1] = m.qp;\n u[RT + 0xB0000 + 2] = m.w & 255; u[RT + 0xB0000 + 3] = m.w >> 8;\n u[RT + 0xB0000 + 4] = m.h & 255; u[RT + 0xB0000 + 5] = m.h >> 8;\n txFlip = 1 - txFlip;\n const wire = u.slice(RT + 0xB0000, RT + 0xB0000 + 6 + n);\n postMessage({ op: \"enc\", wire: wire.buffer, ms: Math.round(performance.now() - t0) }, [wire.buffer]);\n return;\n }\n if (m.op === \"dec\") {\n const pay = new Uint8Array(m.pay);\n const base = RR + m.slot * 0x90000;\n const prev = base + (flips[m.slot] ="
37const P30: *u8 = "== 0 ? 0 : 0x20000);\n const recon = base + (flips[m.slot] === 0 ? 0x20000 : 0);\n U8().set(pay.subarray(6), RI);\n const rc = Number(NX.vv_dec(B(prev), B(recon), B(m.w), B(m.h), B(m.qp), B(RI), B(pay.length - 6), B(RT + 0xF0000), B(RT + 0xF0100)));\n if (rc !== 0) { postMessage({ op: \"decfail\", id: m.id }); return; }\n flips[m.slot] = 1 - flips[m.slot];\n NX.vv_yuv420_to_rgba(B(recon), B(m.w), B(m.h), B(base + 0x40000));\n const rgba = U8().slice(base + 0x40000, base + 0x40000 + m.w * m.h * 4);\n postMessage({ op: \"dec\", id: m.id, rgba: rgba.buffer, w: m.w, h: m.h }, [rgba.buffer]);\n return;\n }\n };`;\n wk = new Worker(URL.createObjectURL(new Blob([src], { type: \"text/javascript\" })));\n wk.onmessage = onWk;\n wk.postMessage({ op: \"init\", url: \"/video/nx_video_client.wasm?v=\" + BUILD });\n } catch (e) { wk = null; }\n }\n function onWk(ev) {\n const m = ev.data;\n if (m.op === \"ready\") { wkReady = m.ok === 1; return; }\n if (m.op === \"enc\") {\n wkEncBusy = false;\n const w = lanes[wkEncLane];\n const wire = new Uint8Array(m.wire);\n if (!w |"
38const P31: *u8 = "| w.readyState !== 1 || w.bufferedAmount > BACKPRESSURE_MAX) { bpSkips++; vvForceKey = true; return; }\n U8().set(wire, R_VVTX + 0xB0000);\n w.send(wirePackPtr(0x57, vvSeq, R_VVTX + 0xB0000, wire.length));\n vvSeq++; vvForceKey = false; txSent++;\n return;\n }\n if (m.op === \"encfail\") { wkEncBusy = false; vvForceKey = true; return; }\n if (m.op === \"dec\") {\n wkDecPend--;\n const p = peers.get(m.id);\n if (!p) return;\n const rgba = new Uint8ClampedArray(m.rgba);\n if (m.w === VID_W && m.h === VID_H) { p.ctx.putImageData(new ImageData(rgba, m.w, m.h), 0, 0); }\n else { vvScratchCtx.putImageData(new ImageData(rgba, m.w, m.h), 0, 0); p.ctx.drawImage(vvScratch, 0, 0, m.w, m.h, 0, 0, VID_W, VID_H); }\n p.fpsCount++;\n const now = performance.now();\n if (now - p.fpsT > 2000) {\n p.fpsLast = p.fpsCount * 1000 / (now - p.fpsT);\n p.stats.textContent = `${p.fpsLast.toFixed(1)}fps`;\n p.stats.classList.toggle(\"bad\", p.fpsLast < 8);\n p.fpsCount = 0; p.fpsT = now;\n }\n return;\n }\n if (m.op === \"decfail\") { wkDecPend--; const p = peers.get(m.id); if (p) { p.vvWaitKey = true; kreq(p, m.id); } ret"
39const P32: *u8 = "urn; }\n }\n function txVvFrame() {\n // RESOURCE-INTELLIGENT GEOMETRY: a weak MEASURED encoder (clsMeasured<=3) sends 160x120 = 1/4 the\n // encode cost + bits -> smooth 15-20fps beats choppy 320x240. Only when EVERY peer is geometry-flex\n // (vc>=2), and geometry may only change AT a keyframe (the P-chain's prev must match).\n const wantW = (geoFlexAll() && clsMeasured >= 0 && clsMeasured <= 3) ? 160 : VID_W;\n const wantH = wantW === 160 ? 120 : VID_H;\n const key = vvForceKey || (vvSeq % VV_KEY_EVERY === 0) || wantW !== vvTxW;\n if (key) { const w = bestLane(); if (!w) return false; vvLane = lanes.indexOf(w); vvTxW = wantW; vvTxH = wantH; } // lane + geometry switch only AT a key\n const w = lanes[vvLane];\n if (!w || w.readyState !== 1) { vvForceKey = true; return false; } // sticky lane died -> re-key next tick\n if (w.bufferedAmount > BACKPRESSURE_MAX) { bpSkips++; return true; } // counted -> ladder steps down\n if (wkReady && wkEncBusy) return true; // worker saturated -> skip tick (natural pacing, no queue)\n txCtx.drawImage(selfVideo, 0, 0, vvTxW, vvTxH);\n const img = txCtx.getImageData(0, 0,"
40const P33: *u8 = " vvTxW, vvTxH);\n if (wkReady) { // WORKER PATH (gap #1): encode OFF the main thread\n wkEncBusy = true; wkEncLane = vvLane;\n wk.postMessage({ op: \"enc\", rgba: img.data.buffer, w: vvTxW, h: vvTxH, qp: vvQp(), key: key ? 1 : 0 }, [img.data.buffer]);\n return true; // seq/send happen in onWk when the wire bytes return\n }\n U8().set(img.data, R_VVTX);\n NX.vv_rgba_to_yuv420(B(R_VVTX), B(vvTxW), B(vvTxH), B(R_VVTX + 0x50000));\n // ping-pong prev/recon so the encoder chains off exactly what the decoder reconstructed\n const prev = R_VVTX + (vvFlip === 0 ? 0x70000 : 0x90000);\n const recon = R_VVTX + (vvFlip === 0 ? 0x90000 : 0x70000);\n const qp = vvQp();\n const n = Number(NX.vv_enc(B(R_VVTX + 0x50000), B(prev), B(recon), B(vvTxW), B(vvTxH),\n B(qp), B(key ? 1 : 0), B(qp * 188), B(R_VVTX + 0xB0000 + 6), B(0x40000 - 6), B(R_VVTX + 0xF0000), B(R_VVTX + 0xF0100)));\n if (n <= 0) { vvForceKey = true; return true; } // over-cap frame: skip, re-key (never a corrupt chain)\n const hdr = U8();\n hdr[R_VVTX + 0xB0000] = key ? 1 : 0;\n hdr[R_VVTX + 0xB0000 + 1] = qp"
41const P34: *u8 = ";\n hdr[R_VVTX + 0xB0000 + 2] = vvTxW & 0xff; hdr[R_VVTX + 0xB0000 + 3] = vvTxW >> 8;\n hdr[R_VVTX + 0xB0000 + 4] = vvTxH & 0xff; hdr[R_VVTX + 0xB0000 + 5] = vvTxH >> 8;\n if (w.bufferedAmount <= BACKPRESSURE_MAX) { w.send(wirePackPtr(0x57, vvSeq, R_VVTX + 0xB0000, 6 + n)); }\n else { bpSkips++; vvForceKey = true; return true; }\n vvFlip = 1 - vvFlip;\n vvSeq++; vvForceKey = false;\n txSent++;\n return true;\n }\n function txOneFrame() {\n if (!joined) return;\n if (!planVideoOn || !camOn || !selfVideo || selfVideo.readyState < 2 || !bestLane()) {\n scheduleTx();\n return;\n }\n if (vcAll()) { txVvFrame(); scheduleTx(); return; } // SOVEREIGN path: whole room speaks 0x57\n if (bestLane().bufferedAmount > BACKPRESSURE_MAX) { bpSkips++; scheduleTx(); return; } // counted -> steps the ladder DOWN\n txCtx.drawImage(selfVideo, 0, 0, VID_W, VID_H);\n const q = rungQ();\n txCanvas.toBlob(async (blob) => {\n try {\n if (blob) {\n const buf = new Uint8Array(await blob.arrayBuffer());\n // CORE FEC: frame -> 10 shards, striped across the lanes (any 8 rebuild it; sendLane fails over)\n U8().set(buf, R_STAGE);"
42const P35: *u8 = "\n const bid = vseq++;\n const slot = Number(NX.vc_fecs_pack(B(R_FTBL), B(R_STAGE), B(buf.length), B(bid),\n B(R_FSD), B(R_FOUT2), B(R_STAGE2)));\n for (let r = 0; r < 10; r++)\n sendLane(r, wirePackPtr(0x46, bid, R_STAGE2 + r * slot, slot));\n txSent++; // measured TX fps -> the QoE beacon\n }\n } catch {}\n scheduleTx();\n }, \"image/jpeg\", q);\n }\n\n // ladder DECISION is the core's; the shim persists the good-counter slot\n const R_GOOD = R_INFO + 256;\n let audioPermil = 0; // measured live LPC ratio, shown in the net label\n function onRtt(rtt) {\n lastRtt = rtt; // QoE beacon reads the latest measured RTT\n netLabel.textContent = `relay: ${Math.round(rtt)}ms ${rungFps()}fps T${tierNow()}` +\n (planTier >= 0 ? ` B${planTier}${planVideoOn ? \"\" : \"\xc2\xb7"
43const P36: *u8 = "audio-only\"}` : \"\") +\n (audioPermil ? ` audio ${Math.round(audioPermil / 10)}%` : \"\");\n ladderIdx = Number(NX.vc_ladder_step(B(ladderIdx), B(NRUNGS()),\n B(Math.round(rtt)), B(RTT_DEGRADE_MS), B(RTT_RECOVER_MS), B(R_GOOD)));\n }\n\n // ---------- audio: capture/playback buffers bridge; SAMPLES = core ----------\n let actx = null, srcNode = null, procNode = null, aseq = 0;\n let playHead = 0;\n function startAudio(stream) {\n actx = new (window.AudioContext || window.webkitAudioContext)();\n actx.resume();\n srcNode = actx.createMediaStreamSource(stream);\n procNode = actx.createScriptProcessor(1024, 1, 1);\n let acc = new Float32Array(0);\n procNode.onaudioprocess = (e) => {\n if (!joined || !micOn || !bestLane() || !NX) return;\n const inb = e.inputBuffer.getChannelData(0);\n const merged = new Float32Array(acc.length + inb.length);\n merged.set(acc, 0);\n merged.set(inb, acc.length);\n acc = merged;\n while (acc.length >= AUDIO_CHUNK) {\n const chunk = acc.subarray(0, AUDIO_CHUNK);\n acc = acc.slice(AUDIO_CHUNK);\n // payload = [u32 rate][LPC 'L' bytes] -- quantize + LOSSLESS compress\n // BY THE CORE (~h"
44const P37: *u8 = "alf the bytes of raw PCM, bit-exact at the decoder)\n const u8 = U8();\n u8.set(new Uint8Array(chunk.buffer, chunk.byteOffset, AUDIO_CHUNK * 4), R_F32);\n NX.vc_wr_u32(B(R_PAY), 0n, B(actx.sampleRate | 0));\n NX.vc_f32_to_i16(B(R_F32), B(AUDIO_CHUNK), B(R_PCM));\n const el = Number(NX.vc_lpc_encode(B(R_PCM), B(AUDIO_CHUNK),\n B(R_PAY + 4), B(6 + AUDIO_CHUNK * 2 + 64), B(R_SCR)));\n if (el > 0) {\n audioPermil = (el * 1000 / (AUDIO_CHUNK * 2)) | 0;\n sendCtl(wirePackPtr(0x4C, aseq++, R_PAY, 4 + el));\n } else {\n // encoder refused (cannot happen with these caps) -> honest raw path\n U8().copyWithin(R_PAY + 4, R_PCM, R_PCM + AUDIO_CHUNK * 2);\n sendCtl(wirePackPtr(0x41, aseq++, R_PAY, 4 + AUDIO_CHUNK * 2));\n }\n }\n };\n srcNode.connect(procNode);\n procNode.connect(actx.destination);\n playHead = actx.currentTime + 0.15;\n }\n // raw 'A' frames (back-compat: clients on the pre-LPC app.js)\n function queueAudio(payload) {\n if (!actx || !NX || payload.length < 6) return;\n const u8 = U8();\n u8.set(payload, R_WIN);\n const srcRate = Number(NX.vc_rd_u32(B(R_WIN), 0n));"
45const P38: *u8 = "\n const n = (payload.length - 4) >> 1;\n u8.copyWithin(R_PCM, R_WIN + 4, R_WIN + 4 + n * 2);\n schedulePcm(srcRate, n);\n }\n // LPC 'L' frames: the core decodes (bit-exact or refuses -- tamper-evident)\n function queueAudioL(payload) {\n if (!actx || !NX || payload.length < 10) return;\n const u8 = U8();\n u8.set(payload, R_WIN);\n const srcRate = Number(NX.vc_rd_u32(B(R_WIN), 0n));\n const n = Number(NX.vc_lpc_decode(B(R_WIN + 4), B(payload.length - 4),\n B(R_PCM), B(0x10000), B(R_SCR)));\n if (n <= 0) return;\n schedulePcm(srcRate, n);\n }\n // shared playback tail: i16 PCM at R_PCM -> exact f32 -> jitter scheduling\n function schedulePcm(srcRate, n) {\n let ab;\n if (srcRate === (actx.sampleRate | 0)) {\n // LOSSLESS path: core converts i16 -> exact f32 bits; shim only moves buffers\n NX.vc_i16_to_f32(B(R_PCM), B(n), B(R_FOUT));\n ab = actx.createBuffer(1, n, actx.sampleRate);\n ab.getChannelData(0).set(new Float32Array(NX.memory.buffer, R_FOUT, n));\n } else {\n // NAMED DEBT: rate-mismatch linear interp still in JS (sinc-in-core rung)\n NX.vc_i16_to_f32(B(R_PCM), B(n), B(R_FOUT));\n const src = new Float32Array(NX.mem"
46const P39: *u8 = "ory.buffer, R_FOUT, n);\n ab = actx.createBuffer(1, Math.ceil(n * actx.sampleRate / srcRate), actx.sampleRate);\n const ch = ab.getChannelData(0);\n const ratio = srcRate / actx.sampleRate;\n for (let i = 0; i < ch.length; i++) {\n const x = i * ratio, x0 = Math.floor(x);\n const lo = x0 < n ? src[x0] : 0;\n const hi = src[Math.min(x0 + 1, n - 1)];\n ch[i] = lo + (hi - lo) * (x - x0);\n }\n }\n const node = actx.createBufferSource();\n node.buffer = ab;\n node.connect(actx.destination);\n const now = actx.currentTime;\n if (playHead < now + 0.05) playHead = now + 0.08;\n if (playHead > now + 0.6) playHead = now + 0.15;\n node.start(playHead);\n playHead += ab.duration;\n }\n\n // ---------- join / leave ----------\n $(\"join\").addEventListener(\"click\", async () => {\n await coreReady;\n if (!NX) { say(\"nishi core not loaded\"); return; }\n room = cleanName(roomIn.value, \"family\");\n me = cleanName(nameIn.value, myId);\n localStorage.setItem(\"nishi_name\", nameIn.value || \"\");\n history.replaceState(null, \"\", `#room=${room}`);\n // Camera/mic are OPTIONAL: you must always be able to JOIN and see/hear others.\n "
47const P40: *u8 = " // 3-tier graceful fallback -- full A/V -> audio-only -> view-only -- but NEVER bail.\n // (The old code RETURNED on getUserMedia failure, so a mobile camera-deny = never\n // joined the room = the \"couldn't see each other\" bug.)\n let gotCam = false, gotMic = false;\n try {\n localStream = await navigator.mediaDevices.getUserMedia({\n video: { width: { ideal: VID_W }, height: { ideal: VID_H }, frameRate: { ideal: 15 }, facingMode: \"user\" },\n audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true }\n });\n gotCam = true; gotMic = true;\n } catch (e1) {\n try {\n localStream = await navigator.mediaDevices.getUserMedia({\n audio: { echoCancellation: true, noiseSuppression: true, autoGainControl: true }\n });\n gotMic = true;\n say(\"camera off (\" + e1.name + \") \xe2\x80\x94 joining with audio only\");\n } catch (e2) {\n localStream = null;\n say(\"joining view-only (camera/mic blocked: \" + e2.name + \")\");\n }\n }\n\n const u8 = U8(); // 8-char id into core memory once\n for (let i = 0; i < 8; i++) u8[R_ID + i] = myId.charCodeAt(i) & 0x7f;\n\n const self"
48const P41: *u8 = "Tile = document.createElement(\"div\");\n selfTile.className = \"tile self\";\n const selfTag = gotCam ? \"\" : (gotMic ? \" (audio only)\" : \" (view-only)\");\n selfTile.innerHTML = `<video autoplay playsinline muted></video><span class=\"label\">${me} (you)${selfTag}</span>`;\n selfVideo = selfTile.querySelector(\"video\");\n if (localStream) selfVideo.srcObject = localStream;\n peersDiv.appendChild(selfTile);\n selfTile.addEventListener(\"dblclick\", () => { selfTile.classList.toggle(\"flipx\"); say(\"mirror \" + (selfTile.classList.contains(\"flipx\") ? \"off\" : \"on\")); }); // self default = mirrored; dbltap = true-view\n // tap the self PiP (duo mode) to SWAP who is full-screen (FaceTime-style)\n selfTile.addEventListener(\"click\", () => {\n // swap intent -> the CORE decides (it only applies in DUO + owns the swapped flag); adapter renders it\n if (NX && NX.uic_intent) { NX.uic_intent(B(R_UIC), UI_SWAP_VIEW); peersDiv.classList.toggle(\"swapped\", Number(NX.uic_swapped(B(R_UIC))) === 1); }\n else if (peersDiv.classList.contains(\"duo\")) peersDiv.classList.toggle(\"swapped\");\n });\n callLayout(); // start in solo; flips to duo when the first"
49const P42: *u8 = " peer joins\n\n lobby.style.display = \"none\";\n stage.style.display = \"block\";\n roomLabel.textContent = `room: ${room}`;\n chatLoadRoom();\n joined = true;\n // sync the sovereign core's mic/cam toggle to actual device capability (core defaults both on), then\n // mirror the core state into the hot-loop locals. The CORE is the SSOT; these vars just cache it.\n if (NX && NX.uic_intent) {\n if (!gotMic && Number(NX.uic_mic(B(R_UIC))) === 1) NX.uic_intent(B(R_UIC), UI_TOGGLE_MIC);\n if (!gotCam && Number(NX.uic_cam(B(R_UIC))) === 1) NX.uic_intent(B(R_UIC), UI_TOGGLE_CAM);\n micOn = Number(NX.uic_mic(B(R_UIC))) === 1; camOn = Number(NX.uic_cam(B(R_UIC))) === 1;\n } else { micOn = gotMic; camOn = gotCam; } // fallback if core not mounted -- TX loops self-skip what we don't have\n $(\"muteBtn\").classList.toggle(\"on\", micOn); $(\"camBtn\").classList.toggle(\"on\", camOn); // buttons reflect core state\n if (localStream && gotMic) startAudio(localStream);\n connectRoom(); // <-- ALWAYS join the room now\n startCtl(); // ping+presence+watchdog+QoE beacon on ANY live lane\n wlAcquire(); "
50const P43: *u8 = " // hold the screen awake for the call (rivals do; a locked screen = 1fps)\n scheduleTx();\n });\n\n $(\"leaveBtn\").addEventListener(\"click\", () => {\n wsSendJson({ from: myId, type: \"bye\" });\n joined = false;\n clearTimeout(txTimer);\n clearInterval(ctlTimer); ctlTimer = null;\n vvSlots.clear(); vvSeq = 0; vvForceKey = true; vvFlip = 0; // fresh codec chain next join\n if (wakeLk) { try { wakeLk.release(); } catch {} wakeLk = null; }\n for (let l = 0; l < LANES; l++) if (lanes[l]) {\n lanes[l].onclose = null; lanes[l].close(); lanes[l] = null;\n }\n ws = null;\n if (procNode) { try { procNode.disconnect(); srcNode.disconnect(); actx.close(); } catch {} procNode = null; actx = null; }\n if (localStream) for (const t of localStream.getTracks()) t.stop();\n localStream = null; selfVideo = null;\n for (const id of [...peers.keys()]) dropPeer(id);\n peersDiv.innerHTML = \"\";\n chatOpen = false; chatPanel.style.display = \"none\";\n $(\"chatBtn\").classList.remove(\"on\");\n chatUnread = 0; chatBadge();\n stage.style.display = \"none\";\n lobby.style.display = \"flex\";\n });\n\n // mic/cam buttons FIRE INTENTS to the sovereign core; the core"
51const P44: *u8 = " flips its state; the adapter mirrors it.\n // HARDENED 760 (field: \"buttons broken\"): (1) try/catch -- a throw anywhere may NEVER leave a dead\n // button (the local flip always lands); (2) the state PROPAGATES instantly (presence w/ mi/ca) so other\n // people's tiles show \"muted\"/\"camera off\" instead of a frozen last frame -- the invisible half of the bug.\n function sendStateNow() {\n wsSendJson({ from: myId, type: \"hello\", name: me, vc: 2, v: BUILD, ts: performance.now(),\n mi: micOn ? 1 : 0, ca: camOn ? 1 : 0 });\n }\n $(\"muteBtn\").addEventListener(\"click\", (e) => {\n try { if (NX && NX.uic_intent) { NX.uic_intent(B(R_UIC), UI_TOGGLE_MIC); micOn = Number(NX.uic_mic(B(R_UIC))) === 1; } else { micOn = !micOn; } }\n catch (err) { micOn = !micOn; }\n e.currentTarget.classList.toggle(\"on\", micOn);\n sendStateNow();\n });\n $(\"camBtn\").addEventListener(\"click\", (e) => {\n try { if (NX && NX.uic_intent) { NX.uic_intent(B(R_UIC), UI_TOGGLE_CAM); camOn = Number(NX.uic_cam(B(R_UIC))) === 1; } else { camOn = !camOn; } }\n catch (err) { camOn = !camOn; }\n e.currentTarget.classList.toggle(\"on\", camOn);\n if (!camOn) vvForceKey = true; // comi"
52const P45: *u8 = "ng back on -> instant key for everyone\n sendStateNow();\n });\n\n let screenVideo = null;\n $(\"shareBtn\").addEventListener(\"click\", async (e) => {\n try {\n if (screenVideo) {\n screenVideo.srcObject.getTracks().forEach(t => t.stop());\n screenVideo = null;\n e.currentTarget.classList.remove(\"on\");\n selfVideo.srcObject = localStream;\n return;\n }\n const ss = await navigator.mediaDevices.getDisplayMedia({ video: true });\n screenVideo = document.createElement(\"video\");\n screenVideo.muted = true; screenVideo.playsInline = true;\n screenVideo.srcObject = ss; screenVideo.play();\n ss.getVideoTracks()[0].onended = () => {\n screenVideo = null; e.currentTarget.classList.remove(\"on\");\n selfVideo.srcObject = localStream;\n };\n selfVideo.srcObject = ss;\n e.currentTarget.classList.add(\"on\");\n } catch {}\n });\n\n $(\"inviteBtn\").addEventListener(\"click\", async () => {\n const url = `${location.origin}${location.pathname}#room=${encodeURIComponent(room || roomIn.value || \"family\")}&join=1`;\n try { await navigator.clipboard.writeText(url); say(\"invite link copied\"); }\n catch { window.prompt(\"i"
53const P46: *u8 = "nvite link (copy):\", url); }\n });\n\n // ---------- room text chat (relay fans any frame out; zero server change) ----------\n // History = PROFILE namespace (nishi_chat_<room>), separate from clearable caches.\n const chatPanel = $(\"chat\"), chatLog = $(\"chatlog\"), chatIn = $(\"chatin\");\n let chatOpen = false, chatUnread = 0;\n const chatKey = () => `nishi_chat_${room}`;\n function chatHist() {\n try { return JSON.parse(localStorage.getItem(chatKey()) || \"[]\"); } catch { return []; }\n }\n function chatPersist(h) {\n try { localStorage.setItem(chatKey(), JSON.stringify(h.slice(-200))); } catch {}\n }\n function chatRender(name, text, mine) {\n const d = document.createElement(\"div\");\n d.className = \"cmsg\" + (mine ? \" mine\" : \"\");\n const w = document.createElement(\"span\");\n w.className = \"cwho\";\n w.textContent = mine ? \"you\" : name; // injection-safe\n const t = document.createElement(\"span\");\n t.textContent = text;\n d.appendChild(w); d.appendChild(t);\n chatLog.appendChild(d);\n while (chatLog.children.length > 200) chatLog.firstChild.remove();\n chatLog.scrollTop = chatLog.scrollHeight;\n }\n function chatBadge() {\n const b = $(\"chatBadge\");\n "
54const P47: *u8 = " b.style.display = chatUnread ? \"block\" : \"none\";\n b.textContent = chatUnread > 9 ? \"9+\" : String(chatUnread);\n }\n function addChat(name, text, mine) {\n chatRender(name, text, mine);\n const h = chatHist();\n h.push({ n: mine ? me : name, t: text, ts: Date.now(), m: mine ? 1 : 0 });\n chatPersist(h);\n if (!mine && !chatOpen) { chatUnread++; chatBadge(); }\n }\n function chatLoadRoom() {\n chatLog.innerHTML = \"\";\n for (const m of chatHist().slice(-200)) chatRender(m.m ? \"you\" : String(m.n || \"?\"), String(m.t || \"\"), !!m.m);\n }\n function sendChat() {\n const text = chatIn.value.trim().slice(0, 500);\n if (!text || !ws || ws.readyState !== 1 || !NX) return;\n // core-packed 0x43 frame (no JSON on the chat wire)\n const u8 = U8();\n const nb = new TextEncoder().encode(me), tb = new TextEncoder().encode(text);\n u8.set(nb, R_CHAT + 1024);\n u8.set(tb, R_CHAT + 2048);\n const pl = Number(NX.vc_chat_pack(B(R_CHAT), B(R_CHAT + 1024), B(nb.length), B(R_CHAT + 2048), B(Math.min(tb.length, 500))));\n if (pl > 0) sendCtl(wirePackPtr(0x43, 0, R_CHAT, pl));\n addChat(me, text, true);\n chatIn.value = \"\";\n }\n $(\"chatsend\").addEventListener(\"click\","
55const P48: *u8 = " sendChat);\n chatIn.addEventListener(\"keydown\", (e) => { if (e.key === \"Enter\") sendChat(); });\n $(\"chatBtn\").addEventListener(\"click\", (e) => {\n chatOpen = !chatOpen;\n chatPanel.style.display = chatOpen ? \"flex\" : \"none\";\n e.currentTarget.classList.toggle(\"on\", chatOpen);\n if (chatOpen) { chatUnread = 0; chatBadge(); chatLog.scrollTop = chatLog.scrollHeight; chatIn.focus(); }\n });\n\n // ---------- NV1 circles: CONTAINER BYTES ALL FROM THE CORE ----------\n function nv1Load(bytes) {\n const e = NX, u8 = U8();\n if (bytes.length > 0x1000000) return null;\n u8.set(bytes, R_NV1IN);\n if (Number(e.vc_nv1_validate(B(R_NV1IN), B(bytes.length), B(R_INFO))) !== 0) return null;\n const rate = I64(R_INFO), samples = I64(R_INFO + 16), dur = I64(R_INFO + 32);\n const pcm = new Float32Array(samples);\n const frames = [];\n let off = 24, fo = 0;\n for (;;) {\n const nxt = Number(e.vc_nv1_next(B(R_NV1IN), B(bytes.length), B(off), B(R_INFO)));\n if (nxt < 0) return null;\n const kind = I64(R_INFO), len = I64(R_INFO + 8), t = I64(R_INFO + 16), poff = I64(R_INFO + 24);\n if (kind === 0x45) break;\n if (kind === 0x41) {\n const n = len >> 1;\n"
56const P49: *u8 = " e.vc_i16_to_f32(B(R_NV1IN + poff), B(n), B(R_FOUT));\n pcm.set(new Float32Array(NX.memory.buffer, R_FOUT, n), fo);\n fo += n;\n } else if (kind === 0x56) {\n frames.push({ t, bytes: U8().slice(R_NV1IN + poff, R_NV1IN + poff + len) });\n }\n off = nxt;\n }\n return { rate, pcm, frames, dur };\n }\n\n const nv1Cache = new Map();\n let nvPlay = null;\n function nv1Stop() {\n if (!nvPlay) return;\n const p = nvPlay; nvPlay = null;\n try { p.src.stop(); } catch {}\n try { p.actx.close(); } catch {}\n cancelAnimationFrame(p.raf);\n }\n async function nv1Toggle(canvas, name) {\n if (nvPlay && nvPlay.canvas === canvas) { nv1Stop(); return; }\n nv1Stop();\n let d = nv1Cache.get(name);\n if (!d) {\n try {\n const r = await fetch(`/video/circle/${encodeURIComponent(name)}`);\n d = nv1Load(new Uint8Array(await r.arrayBuffer()));\n } catch { d = null; }\n if (!d) { say(\"could not load circle\"); return; }\n nv1Cache.set(name, d);\n }\n const actxP = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: d.rate });\n const ab = actxP.createBuffer(1, Math.max(1, d.pcm.length), d.rate);\n ab"
57const P50: *u8 = ".getChannelData(0).set(d.pcm); // exact bits from the core\n const src = actxP.createBufferSource();\n src.buffer = ab; src.connect(actxP.destination);\n const cctx = canvas.getContext(\"2d\");\n const playing = { actx: actxP, src, canvas, raf: 0, last: null };\n nvPlay = playing;\n const t0 = performance.now();\n src.start();\n let fi = 0;\n const step = () => {\n if (nvPlay !== playing) return;\n const el = performance.now() - t0;\n while (fi + 1 < d.frames.length && d.frames[fi + 1].t <= el) fi++;\n const f = d.frames[fi];\n if (f && f !== playing.last) {\n playing.last = f;\n createImageBitmap(new Blob([f.bytes], { type: \"image/jpeg\" })).then(bmp => {\n cctx.drawImage(bmp, 0, 0, canvas.width, canvas.height); bmp.close();\n }).catch(() => {});\n }\n if (el >= d.dur) { nv1Stop(); return; }\n playing.raf = requestAnimationFrame(step);\n };\n playing.raf = requestAnimationFrame(step);\n }\n\n // ---------- circles UI ----------\n $(\"circlesBtn\").addEventListener(\"click\", () => { openCircles(); });\n $(\"circleBtn\").addEventListener(\"click\", () => { startCircleRec(); });\n $(\"circRecBtn\").addEventLi"
58const P51: *u8 = "stener(\"click\", () => { startCircleRec(); });\n $(\"circlesBack\").addEventListener(\"click\", () => {\n circlesView.style.display = \"none\";\n (joined ? stage : lobby).style.display = joined ? \"block\" : \"flex\";\n });\n $(\"circPubBtn\").addEventListener(\"click\", () => { circPriv = false; refreshCircleTabs(); loadCircles(); });\n $(\"circPrivBtn\").addEventListener(\"click\", () => { circPriv = true; refreshCircleTabs(); loadCircles(); });\n function refreshCircleTabs() {\n $(\"circPubBtn\").classList.toggle(\"on\", !circPriv);\n $(\"circPrivBtn\").classList.toggle(\"on\", circPriv);\n }\n function openCircles() {\n room = cleanName(roomIn.value, room || \"family\");\n $(\"circForRoom\").textContent = `room: ${room}`;\n lobby.style.display = \"none\";\n stage.style.display = \"none\";\n circlesView.style.display = \"flex\";\n loadCircles();\n }\n async function loadCircles() {\n const grid = $(\"cgrid\");\n grid.innerHTML = \"<span style='color:#6a6a74'>loading\xe2\x80\xa6</span>\";\n try {\n const r = await fetch(`/video/circles?room=${encodeURIComponent(room)}&priv=${circPriv ? 1 : 0}`);\n const names = await r.json();\n grid.innerHTML = names.length ? \"\" : \"<span style='color:#6a6a7"
59const P52: *u8 = "4'>no circles yet \xe2\x80\x94 record one</span>\";\n names.sort().reverse();\n for (const n of names) {\n const d = document.createElement(\"div\");\n d.className = \"circle\";\n const who = (n.split(\"_\")[1] || \"?\");\n if (n.endsWith(\".nv1\")) {\n d.innerHTML = `<canvas width=\"${VID_W}\" height=\"${VID_H}\"></canvas>\n <span class=\"who\">${who}</span>`;\n const cv = d.querySelector(\"canvas\");\n (async () => {\n try {\n await coreReady;\n const r0 = await fetch(`/video/circle/${encodeURIComponent(n)}`);\n const dd = nv1Load(new Uint8Array(await r0.arrayBuffer()));\n if (!dd) return;\n nv1Cache.set(n, dd);\n if (dd.frames.length) {\n const bmp = await createImageBitmap(new Blob([dd.frames[0].bytes], { type: \"image/jpeg\" }));\n cv.getContext(\"2d\").drawImage(bmp, 0, 0, cv.width, cv.height);\n bmp.close();\n }\n } catch {}\n })();\n d.addEventListener(\"click\", () => { nv1Toggle(cv, n); });\n } else {\n d.innerHTML = `<video playsinline preload=\"metadata\""
60const P53: *u8 = " src=\"/video/circle/${encodeURIComponent(n)}\"></video>\n <span class=\"who\">${who}</span>`;\n d.addEventListener(\"click\", () => {\n const v = d.querySelector(\"video\");\n if (v.paused) { v.currentTime = 0; v.play(); } else v.pause();\n });\n }\n grid.appendChild(d);\n }\n } catch { grid.innerHTML = \"<span style='color:#a06a6a'>could not load circles</span>\"; }\n }\n\n // ---------- NV1 circle recorder (capture = platform; bytes = core) ----------\n async function startCircleRec() {\n await coreReady;\n if (!NX) { say(\"nishi core not loaded\"); return; }\n room = cleanName(roomIn.value, room || \"family\");\n me = cleanName(nameIn.value, me || myId);\n let stream = localStream;\n let temp = false;\n if (!stream) {\n try {\n stream = await navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 480 }, facingMode: \"user\" }, audio: true });\n temp = true;\n } catch (e) { say(\"camera blocked: \" + e.name); return; }\n }\n $(\"recwrap\").style.display = \"flex\";\n $(\"recview\").srcObject = stream;\n $(\"recPriv\").checked = circPriv;\n const actxR = new (window.AudioContext "
61const P54: *u8 = "|| window.webkitAudioContext)();\n actxR.resume();\n const srcR = actxR.createMediaStreamSource(stream);\n const procR = actxR.createScriptProcessor(4096, 1, 1);\n nvr = { actxR, srcR, procR, rate: actxR.sampleRate | 0, a: [], v: [],\n samples: 0, t0: performance.now(), vt: null };\n procR.onaudioprocess = (e) => {\n if (!nvr) return;\n const inb = e.inputBuffer.getChannelData(0);\n nvr.a.push({ t: nvr.samples * 1000 / nvr.rate, pcm: new Float32Array(inb) });\n nvr.samples += inb.length;\n };\n srcR.connect(procR); procR.connect(actxR.destination);\n const rv = $(\"recview\");\n const rc = document.createElement(\"canvas\");\n rc.width = VID_W; rc.height = VID_H;\n const rctx = rc.getContext(\"2d\");\n nvr.vt = setInterval(() => {\n if (!nvr || rv.readyState < 2) return;\n const t = performance.now() - nvr.t0;\n rctx.drawImage(rv, 0, 0, VID_W, VID_H);\n rc.toBlob(async (blob) => {\n if (blob && nvr) nvr.v.push({ t, bytes: new Uint8Array(await blob.arrayBuffer()) });\n }, \"image/jpeg\", 0.7);\n }, 100);\n recStartT = performance.now();\n recTimer = setInterval(() => {\n const s = Math.min(60, Math.floor(("
62const P55: *u8 = "performance.now() - recStartT) / 1000));\n $(\"rectimer\").textContent = `0:${String(s).padStart(2, \"0\")} / 1:00`;\n if (performance.now() - recStartT >= MAX_CIRCLE_MS) finishCircle(stream, temp, true);\n }, 250);\n $(\"recStop\").onclick = () => finishCircle(stream, temp, true);\n $(\"recCancel\").onclick = () => finishCircle(stream, temp, false);\n }\n async function finishCircle(stream, temp, send) {\n clearInterval(recTimer);\n if (!nvr) return;\n const r = nvr; nvr = null;\n clearInterval(r.vt);\n try { r.procR.disconnect(); r.srcR.disconnect(); r.actxR.close(); } catch {}\n await new Promise(res => setTimeout(res, 250));\n $(\"recwrap\").style.display = \"none\";\n if (temp) for (const t of stream.getTracks()) t.stop();\n if (!send || (!r.a.length && !r.v.length)) return;\n const durMs = Math.round(performance.now() - r.t0);\n // pack: every container byte written by the core (frames then audio;\n // the player schedules by per-chunk t_ms, so order is free)\n const e = NX, u8 = U8();\n let w = Number(e.vc_nv1_header(B(R_NV1), B(r.rate)));\n for (const fr of r.v) {\n u8.set(fr.bytes, R_STAGE);\n w = Number(e.vc_nv1_chunk(B(R_NV1), B(w)"
63const P56: *u8 = ", 0x56n, B(Math.round(fr.t)), B(R_STAGE), B(fr.bytes.length)));\n }\n for (const a of r.a) {\n u8.set(new Uint8Array(a.pcm.buffer, a.pcm.byteOffset, a.pcm.length * 4), R_STAGE);\n e.vc_f32_to_i16(B(R_STAGE), B(a.pcm.length), B(R_STAGE2));\n w = Number(e.vc_nv1_chunk(B(R_NV1), B(w), 0x41n, B(Math.round(a.t)), B(R_STAGE2), B(a.pcm.length * 2)));\n }\n w = Number(e.vc_nv1_end(B(R_NV1), B(w), B(durMs)));\n const body = u8.slice(R_NV1, R_NV1 + w);\n const priv = $(\"recPriv\").checked ? 1 : 0;\n say(priv ? \"saving to private archive\xe2\x80\xa6\" : \"sending circle\xe2\x80\xa6\");\n try {\n const resp = await fetch(`/video/circle?room=${encodeURIComponent(room)}&from=${encodeURIComponent(me)}&priv=${priv}&ext=nv1`,\n { method: \"POST\", body });\n const j = await resp.json();\n if (j.ok) {\n say(priv ? \"saved to private archive \xe2\x9c\x93\" : \"circle sent \xe2\x9c\x93\");\n if (circlesView.style.display === \"flex\") { circPriv = !!priv; refreshCircleTabs(); loadCircles(); }\n } else say(\"upload failed: \" + (j.err || \"?\"));\n } catch { say(\"upload failed (network)\"); }\n }\n\n if (qp(\"room\") && qp(\"join\") === \"1\") {\n say(\"tap Join to enter \" + qp"
64const P57: *u8 = "(\"room\"));\n }\n // EMBED mode (iframe on a 3rd-party site, ?embed=1): streamline chrome + focus Join. We do NOT auto-join\n // (getUserMedia needs a user gesture) -- one tap enters, camera/mic delegated via the iframe allow= attr.\n // SELF-UPGRADE boot hooks: check the server build once at load, and if a self-upgrade reload put us\n // here, land the user straight back IN their call (their state is OUR job to carry, not theirs).\n pollVer();\n try {\n const rj = sessionStorage.getItem(\"nx_rejoin\");\n if (rj) {\n sessionStorage.removeItem(\"nx_rejoin\");\n roomIn.value = rj;\n coreReady.then(() => { const jb = $(\"join\"); if (jb) jb.click(); });\n }\n } catch {}\n if (qp(\"embed\") === \"1\") {\n document.body.classList.add(\"embed\");\n const jb = $(\"join\"); if (jb) jb.focus();\n }\n})();\n"

functions

66func ep(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return n }
68func main(argc: i64, argv: *i64) -> i64