sonarium 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +271 -0
  3. package/dist/index.d.ts +1000 -0
  4. package/dist/index.js +2716 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/sonarium.iife.js +236 -0
  7. package/dist/sonarium.iife.js.map +1 -0
  8. package/package.json +63 -0
  9. package/src/core/engine.ts +468 -0
  10. package/src/core/listener.ts +61 -0
  11. package/src/core/matter-voice.ts +240 -0
  12. package/src/core/profile.ts +313 -0
  13. package/src/core/room.ts +135 -0
  14. package/src/core/scanner.ts +176 -0
  15. package/src/core/voices.ts +222 -0
  16. package/src/index.ts +74 -0
  17. package/src/interact/activate.ts +56 -0
  18. package/src/interact/drag.ts +52 -0
  19. package/src/interact/keyboard.ts +48 -0
  20. package/src/interact/midi.ts +40 -0
  21. package/src/interact/motion.ts +61 -0
  22. package/src/interact/pointer.ts +65 -0
  23. package/src/interact/scroll.ts +43 -0
  24. package/src/math/chroma.ts +111 -0
  25. package/src/math/mapping.ts +100 -0
  26. package/src/math/matter.ts +201 -0
  27. package/src/math/modular.ts +99 -0
  28. package/src/math/pulse.ts +64 -0
  29. package/src/math/scales.ts +90 -0
  30. package/src/math/util.ts +16 -0
  31. package/src/spatial/backend.ts +166 -0
  32. package/src/spatial/bus.ts +114 -0
  33. package/src/spatial/decoder.ts +63 -0
  34. package/src/spatial/encoder.ts +54 -0
  35. package/src/spatial/field.ts +75 -0
  36. package/src/spatial/perceptual.ts +43 -0
  37. package/src/spatial/room-foa.ts +81 -0
  38. package/src/spatial/rotation.ts +73 -0
  39. package/src/spatial/sh.ts +38 -0
  40. package/src/spatial/sphere.ts +36 -0
  41. package/src/themes/index.ts +60 -0
  42. package/src/types.ts +157 -0
  43. package/src/ui/gate.ts +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/engine.ts","../src/math/util.ts","../src/math/scales.ts","../src/math/modular.ts","../src/math/chroma.ts","../src/math/pulse.ts","../src/themes/index.ts","../src/ui/gate.ts","../src/spatial/backend.ts","../src/spatial/bus.ts","../src/spatial/sh.ts","../src/spatial/decoder.ts","../src/spatial/rotation.ts","../src/spatial/encoder.ts","../src/spatial/room-foa.ts","../src/spatial/sphere.ts","../src/spatial/perceptual.ts","../src/spatial/field.ts","../src/core/listener.ts","../src/math/mapping.ts","../src/core/room.ts","../src/math/matter.ts","../src/core/profile.ts","../src/core/scanner.ts","../src/core/voices.ts","../src/core/matter-voice.ts","../src/interact/pointer.ts","../src/interact/activate.ts","../src/interact/keyboard.ts","../src/interact/scroll.ts","../src/interact/motion.ts","../src/interact/drag.ts","../src/interact/midi.ts","../src/index.ts"],"sourcesContent":["/**\n * The orchestrator — the only file allowed to know every layer (ARCHITECTURE.md §1).\n * Lifecycle: idle → armed → running ⇄ muted → disposed (§3).\n */\nimport * as Tone from 'tone'\nimport { SCALES, midiToFreq, parseKey, siteKey, stepInScale, type SiteKey } from '../math/scales'\nimport { ribbonSteps } from '../math/modular'\nimport { clamp } from '../math/util'\nimport {\n chromaOf, modeFromPalette, pagePalette, parseCssColor, roomToneScaleFromWarmth,\n tempoScaleFromWarmth, type Chroma,\n} from '../math/chroma'\nimport {\n ECHO_MIN_AHEAD_S, ECHO_TRANSPOSE, ECHO_VELOCITY_SCALE, PHRASE_MAX_NOTES, PHRASE_MIN_NOTES,\n PHRASE_PROBABILITY, decayCount, duckFactor, echoGridS, nextGridOffset, phraseWindow,\n readingOrderKey, secondsPerBeat, strumStepS, tempoFromPage,\n} from '../math/pulse'\nimport type { Articulation, PerceptualFactors, SonariumOptions, SonicProfile, SonariumEvent, Theme, TriggerDetail } from '../types'\nimport { resolveTheme } from '../themes/index'\nimport { mountGate, isMutedPersisted, persistMuted, type GateHandle } from '../ui/gate'\nimport { AmbisonicBackend, PannerBackend, type SpatialBackend } from '../spatial/backend'\nimport { FieldRig } from '../spatial/field'\nimport { resolveFactors } from '../spatial/perceptual'\nimport { ListenerRig } from './listener'\nimport type { ProfileEnv } from './profile'\nimport { Room } from './room'\nimport { Scanner } from './scanner'\nimport { VoicePool } from './voices'\nimport { attachPointer } from '../interact/pointer'\nimport { attachActivate } from '../interact/activate'\nimport { attachKeyboard } from '../interact/keyboard'\nimport { attachScroll } from '../interact/scroll'\nimport { attachMotion } from '../interact/motion'\nimport { attachDrag } from '../interact/drag'\nimport { attachMidi } from '../interact/midi'\n\ninterface ResolvedOptions {\n root: Element\n theme: Theme\n key: SiteKey\n listener: 'pointer' | 'center'\n ambient: number\n motion: boolean\n gate: 'chip' | 'none'\n volume: number\n maxVoices: number\n panning: 'HRTF' | 'equalpower'\n spatial: 'ambisonic' | 'panner'\n reverb: 'auto' | number\n velocityFactor: number\n midi: boolean\n}\n\ntype State = 'idle' | 'armed' | 'running' | 'disposed'\n\nexport class Engine {\n readonly opts: ResolvedOptions\n state: State = 'idle'\n muted = false\n\n scanner!: Scanner\n pool: VoicePool | null = null\n room: Room | null = null\n rig: ListenerRig | FieldRig | null = null\n backend: SpatialBackend | null = null\n factors: PerceptualFactors\n /** The page's mood (CHROMA.md §3) and pulse (PULSE.md §1), fixed at create(). */\n readonly palette: Chroma\n readonly tempo: number\n private phraseLoop: Tone.Loop | null = null\n private activity = new WeakMap<Element, { c: number; t: number }>()\n\n private gate: GateHandle | null = null\n private env: ProfileEnv\n private detachers: Array<() => void> = []\n private listeners = new Map<SonariumEvent, Set<(detail?: unknown) => void>>()\n private unlockHandler: ((e: Event) => void) | null = null\n private appearBucket = 6\n private bucketTimer: ReturnType<typeof setInterval> | null = null\n\n constructor(userOpts: SonariumOptions = {}) {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n throw new Error('[sonarium] requires a browser environment (create() in the client only)')\n }\n const reduced = (userOpts.respectReducedMotion ?? true)\n && typeof matchMedia === 'function'\n && matchMedia('(prefers-reduced-motion: reduce)').matches\n\n // CHROMA.md §3 — the palette chooses the mode; the hostname keeps the root (identity).\n const rootStyle = getComputedStyle(document.documentElement)\n const bodyStyle = getComputedStyle(document.body)\n this.palette = pagePalette(\n chromaOf(parseCssColor(bodyStyle.backgroundColor)),\n chromaOf(parseCssColor(bodyStyle.color)),\n )\n const cssKey = rootStyle.getPropertyValue('--sonic-key').trim()\n let key = (userOpts.key && userOpts.key !== 'auto' ? parseKey(userOpts.key) : null)\n ?? (cssKey ? parseKey(cssKey) : null)\n if (!key) {\n const hashed = siteKey(location.hostname)\n const mode = modeFromPalette(this.palette)\n key = mode\n ? { ...hashed, scaleName: mode, scale: SCALES[mode] as readonly number[], label: `${hashed.label.split(' ')[0]} ${mode}` }\n : hashed\n }\n\n this.opts = {\n root: userOpts.root ?? document.body,\n theme: resolveTheme(userOpts.theme),\n key,\n listener: userOpts.listener ?? 'pointer',\n ambient: reduced ? 0 : clamp(userOpts.ambient ?? 0.12, 0, 1),\n motion: userOpts.motion ?? true,\n gate: userOpts.gate ?? 'chip',\n volume: userOpts.volume ?? -10,\n maxVoices: clamp(userOpts.maxVoices ?? 18, 4, 24),\n panning: userOpts.panning === 'equalpower' ? 'equalpower' : 'HRTF',\n spatial: userOpts.spatial === 'panner' ? 'panner' : 'ambisonic',\n reverb: userOpts.reverb ?? 'auto',\n velocityFactor: reduced ? 0.7 : 1,\n midi: userOpts.midi === true,\n }\n this.factors = resolveFactors(userOpts.perceptual)\n\n this.env = {\n root: this.opts.root,\n key: this.opts.key,\n theme: this.opts.theme,\n vw: window.innerWidth,\n vh: window.innerHeight,\n }\n\n this.muted = isMutedPersisted()\n\n // L1 perception is always on: the page is readable (describe()) before it is audible.\n this.scanner = new Scanner(this.env, { onAppear: (el) => this.whisper(el) })\n this.scanner.scan()\n\n // PULSE.md §1 — the layout sets the pace (overridable via --sonic-tempo).\n const cssTempo = parseFloat(rootStyle.getPropertyValue('--sonic-tempo'))\n this.tempo = cssTempo > 0\n ? clamp(Math.round(cssTempo), 30, 200)\n : tempoFromPage(this.scanner.registry.size, tempoScaleFromWarmth(this.palette.warmth))\n\n this.arm()\n }\n\n // ---------------------------------------------------------------- lifecycle\n\n private arm(): void {\n this.state = 'armed'\n if (this.opts.gate === 'chip') {\n this.gate = mountGate(() => this.toggleMute())\n this.gate.setState(this.muted ? 'muted' : 'armed')\n }\n if (!this.muted) {\n // Any gesture may unlock (standard autoplay pattern); the chip is the explicit path.\n // 'click' included for assistive tech and synthetic activation, which may skip pointerdown.\n // Listeners stay armed until start() actually succeeds — a gesture that fails to resume\n // the context (no user activation) must not consume the only unlock chance.\n this.unlockHandler = () => { void this.start() }\n window.addEventListener('pointerdown', this.unlockHandler, { capture: true })\n window.addEventListener('keydown', this.unlockHandler, { capture: true })\n window.addEventListener('click', this.unlockHandler, { capture: true })\n }\n }\n\n private removeUnlockListeners(): void {\n if (!this.unlockHandler) return\n window.removeEventListener('pointerdown', this.unlockHandler, { capture: true })\n window.removeEventListener('keydown', this.unlockHandler, { capture: true })\n window.removeEventListener('click', this.unlockHandler, { capture: true })\n this.unlockHandler = null\n }\n\n private starting = false\n\n async start(): Promise<void> {\n if (this.state === 'running' || this.state === 'disposed' || this.starting) return\n this.starting = true\n try {\n // Tone.start() can stay pending forever without user activation; don't wedge on it —\n // stay 'armed' and let the next (real) gesture try again.\n await Promise.race([Tone.start(), new Promise((r) => setTimeout(r, 1500))])\n } catch (err) {\n console.warn('[sonarium] audio context could not start yet', err)\n } finally {\n this.starting = false\n }\n if (Tone.getContext().state !== 'running' || (this.state as State) === 'disposed') return\n this.state = 'running'\n this.removeUnlockListeners()\n this.gate?.setState(this.muted ? 'muted' : 'on')\n\n this.buildAudioGraph()\n if (this.muted) this.room?.setMuted(true)\n\n this.detachers.push(\n attachPointer(this),\n attachActivate(this),\n attachKeyboard(this),\n attachScroll(this),\n attachDrag(this),\n )\n if (this.opts.motion) this.detachers.push(attachMotion(this))\n if (this.opts.midi) this.detachers.push(attachMidi(this))\n\n const onVis = () => this.room?.setHidden(document.hidden)\n document.addEventListener('visibilitychange', onVis)\n this.detachers.push(() => document.removeEventListener('visibilitychange', onVis))\n\n this.bucketTimer = setInterval(() => { this.appearBucket = Math.min(6, this.appearBucket + 6) }, 1000)\n\n // PULSE.md — the page's clock drives ambience, echoes and phrases.\n Tone.getTransport().bpm.value = this.tempo\n Tone.getTransport().start()\n this.room?.startAmbience(this.env.vw, this.opts.ambient, roomToneScaleFromWarmth(this.palette.warmth))\n if (this.opts.ambient > 0) {\n this.phraseLoop = new Tone.Loop((time) => this.playPhrase(time), '1m')\n this.phraseLoop.start('1m')\n }\n this.playIntroMotif()\n this.emit('start')\n }\n\n /** PULSE.md §3 — the ambience reads the layout as a score; scroll moves the playhead. */\n private playPhrase(time?: number): void {\n if (this.state !== 'running' || this.muted || document.hidden) return\n if (time === undefined || !Number.isFinite(time)) time = Tone.now()\n if (Math.random() > PHRASE_PROBABILITY) return\n const pool = this.scanner.visibleElements()\n .map((el) => ({ el, p: this.scanner.profileFor(el) }))\n .filter((x): x is { el: Element; p: SonicProfile } => !!x.p && x.p.role !== 'container' && x.p.velocityScale > 0.01)\n .sort((a, b) => readingOrderKey(a.p.rect.y, a.p.rect.x) - readingOrderKey(b.p.rect.y, b.p.rect.x))\n if (pool.length < PHRASE_MIN_NOTES) return\n const len = Math.min(pool.length, PHRASE_MIN_NOTES + Math.floor(Math.random() * (PHRASE_MAX_NOTES - PHRASE_MIN_NOTES + 1)))\n const scrollable = Math.max(1, document.documentElement.scrollHeight - window.innerHeight)\n const start = phraseWindow(pool.length, len, window.scrollY / scrollable)\n const step = secondsPerBeat(this.tempo) / 2\n const level = 0.07 * (this.opts.ambient / 0.12)\n pool.slice(start, start + len).forEach(({ el }, i) => this.excite(el, level, 'phrase', time + i * step))\n }\n\n /**\n * SPATIAL.md §6 — ambisonic field by default; if its construction throws on an exotic\n * browser, fall back to the v0.1 per-voice panner world rather than staying silent.\n */\n private buildAudioGraph(): void {\n const roomOpts = { volumeDb: this.opts.volume, reverb: this.opts.reverb, ambient: this.opts.ambient }\n if (this.opts.spatial === 'ambisonic') {\n try {\n this.room = new Room({ ...roomOpts, mode: 'ambisonic' }, this.env.vw, this.factors)\n const decoderKind = this.opts.panning === 'equalpower' ? 'stereo' : 'binaural'\n this.backend = new AmbisonicBackend(this.room, decoderKind, this.env.vw, this.factors)\n this.rig = new FieldRig(this.backend, this.opts.listener)\n this.rig.start()\n this.pool = new VoicePool(this.backend, this.opts.maxVoices)\n return\n } catch (err) {\n console.warn('[sonarium] ambisonic backend unavailable, falling back to panner', err)\n this.room?.dispose()\n this.room = null\n }\n }\n this.room = new Room({ ...roomOpts, mode: 'panner' }, this.env.vw, this.factors)\n this.backend = new PannerBackend(this.room, this.opts.panning)\n this.rig = new ListenerRig(this.opts.listener)\n this.rig.start()\n this.pool = new VoicePool(this.backend, this.opts.maxVoices)\n }\n\n /**\n * MODULAR.md §3 — the ribbon controller: press-and-drag turns an element into a sustained\n * voice swept across scale degrees (quantized — the glide between steps is the glissando).\n */\n ribbon(el: Element): { move(dxPx: number): void; release(): void } | null {\n if (this.state !== 'running' || this.muted || !this.pool) return null\n const target = this.scanner.resolve(el) ?? el\n const profile = this.scanner.profileFor(target)\n if (!profile) return null\n const handle = this.pool.sustain(profile, 0.6)\n if (!handle) return null\n this.emit('trigger', { el: target, profile, velocity: 0.6, articulation: 'ribbon' } satisfies TriggerDetail)\n const key = this.opts.key\n const glide = 0.03 + profile.voice.patch.portamentoS\n let lastMidi = profile.midi\n return {\n move: (dxPx: number) => {\n const midi = stepInScale(profile.midi, key, ribbonSteps(dxPx, this.env.vw, key.scale.length))\n if (midi !== lastMidi) {\n lastMidi = midi\n handle.setFreq(midiToFreq(midi), glide)\n }\n },\n release: () => handle.release(),\n }\n }\n\n /** MATTER.md §2.2 — scroll drivers report air movement; rides the room-tone noise. */\n airRush(level: number): void {\n if (this.state !== 'running' || this.muted || level <= 0.005) return\n this.room?.rush(level)\n }\n\n /** Live spat5.oper surface: adjust presence/roomPresence/envelopment/warmth/brilliance. */\n setPerceptual(partial: Partial<PerceptualFactors>): void {\n this.factors = resolveFactors({ ...this.factors, ...partial })\n this.backend?.setFactors(this.factors)\n }\n\n toggleMute(): void {\n if (this.state !== 'running') {\n // First tap on the chip both unlocks and (if persisted-muted) unmutes.\n this.muted = false\n persistMuted(false)\n void this.start()\n return\n }\n this.muted = !this.muted\n persistMuted(this.muted)\n this.room?.setMuted(this.muted)\n this.gate?.setState(this.muted ? 'muted' : 'on')\n this.emit('mute', this.muted)\n }\n\n dispose(): void {\n if (this.state === 'disposed') return\n this.state = 'disposed'\n this.removeUnlockListeners()\n if (this.bucketTimer) clearInterval(this.bucketTimer)\n this.phraseLoop?.dispose()\n for (const detach of this.detachers.splice(0)) {\n try { detach() } catch { /* already gone */ }\n }\n this.scanner?.dispose()\n this.rig?.dispose()\n this.pool?.dispose()\n this.backend?.dispose()\n this.room?.dispose()\n this.gate?.dispose()\n this.emit('dispose')\n this.listeners.clear()\n }\n\n // ---------------------------------------------------------------- sounding\n\n /**\n * The single entry point for anything that wants to sound an element (Invariant: L2 drivers\n * never touch Tone). Resolves the element to its profile and rents a voice.\n * `transpose` shifts in semitones relative to the quantized pitch — callers must pass\n * consonant intervals only (e.g. keyboard.ts FILL_INTERVALS).\n */\n excite(el: Element, velocity: number, articulation: Articulation, when?: number, transpose = 0): void {\n if (this.state !== 'running' || this.muted || !this.pool) return\n if (when !== undefined && !Number.isFinite(when)) when = undefined // NaN must never reach a ramp\n const target = this.scanner.resolve(el) ?? el\n let profile = this.scanner.profileFor(target)\n if (!profile) return\n\n // PULSE.md §4 — the calm system: repeated sounds recede (motifs/echoes/phrases exempt).\n if (articulation !== 'motif' && articulation !== 'echo' && articulation !== 'phrase' && articulation !== 'whisper') {\n const now = performance.now()\n const a = this.activity.get(target) ?? { c: 0, t: now }\n a.c = decayCount(a.c, now - a.t) + 1\n a.t = now\n this.activity.set(target, a)\n velocity *= duckFactor(a.c - 1)\n }\n if (transpose !== 0) {\n profile = { ...profile, midi: profile.midi + transpose, freqHz: profile.freqHz * Math.pow(2, transpose / 12) }\n }\n if (articulation === 'tick') {\n profile = { ...profile, durationS: Math.min(profile.durationS, 0.07), release: 0.05 }\n }\n if (articulation === 'toggle-on' || articulation === 'toggle-off') {\n const dir = articulation === 'toggle-on' ? 1 : -1\n const base = { ...profile, durationS: 0.12 }\n this.pool.trigger(base, velocity * this.opts.velocityFactor, when)\n // perfect-5th answer note (I6): 7 semitones up/down from the quantized pitch\n const second = { ...profile, midi: profile.midi + dir * 7, freqHz: profile.freqHz * Math.pow(2, (dir * 7) / 12), durationS: 0.16 }\n this.pool.trigger(second, velocity * this.opts.velocityFactor, (when ?? Tone.now()) + 0.09)\n } else {\n this.pool.trigger(profile, velocity * this.opts.velocityFactor, when)\n }\n\n // PULSE.md §2 — the room answers strong hits on the next 8th, one octave up, quiet.\n // The primary hit above was NOT delayed (the latency invariant, §0).\n if (articulation === 'hit' && velocity >= 0.55) {\n const offset = nextGridOffset(Tone.getTransport().seconds, echoGridS(this.tempo), ECHO_MIN_AHEAD_S)\n this.excite(target, velocity * ECHO_VELOCITY_SCALE, 'echo', Tone.now() + offset, ECHO_TRANSPOSE)\n }\n\n this.emit('trigger', { el: target, profile, velocity, articulation } satisfies TriggerDetail)\n }\n\n /** I3/I11 — strum a set of elements left→right (or right→left for a reverse flick). */\n strum(els: Element[], velocity: number, articulation: Articulation = 'strum', reverse = false): void {\n if (this.state !== 'running' || !this.pool) return\n const sorted = els\n .map((el) => ({ el, p: this.scanner.profileFor(el) }))\n .filter((x): x is { el: Element; p: SonicProfile } => !!x.p)\n .sort((a, b) => (reverse ? b.p.rect.x - a.p.rect.x : a.p.rect.x - b.p.rect.x))\n .slice(0, 6)\n // metered: 32nd-note spacing at the page's tempo (PULSE.md §3)\n const t0 = Tone.now()\n const step = strumStepS(this.tempo)\n sorted.forEach(({ el }, i) => this.excite(el, velocity, articulation, t0 + i * step))\n }\n\n private whisper(el: Element): void {\n if (this.appearBucket <= 0) return\n this.appearBucket--\n this.excite(el, 0.12, 'whisper')\n }\n\n /** I12 — the page introduces itself: its largest landmarks, in DOM order, in the site key. */\n private playIntroMotif(): void {\n const candidates = Array.from(\n this.opts.root.querySelectorAll('h1, h2, nav, main, [role=banner], header, button, [role=button]'),\n ).filter((el) => {\n const r = el.getBoundingClientRect()\n return r.width > 0 && r.height > 0 && r.top < this.env.vh\n })\n const byArea = candidates\n .map((el) => ({ el, area: el.getBoundingClientRect().width * el.getBoundingClientRect().height }))\n .sort((a, b) => b.area - a.area)\n .slice(0, 5)\n .map((x) => x.el)\n const inDomOrder = candidates.filter((el) => byArea.includes(el))\n const t0 = Tone.now() + 0.1\n const step = secondsPerBeat(this.tempo) / 4 // the motif walks 16ths at the page's tempo\n inDomOrder.forEach((el, i) => this.excite(el, 0.3, 'motif', t0 + i * step))\n }\n\n // ---------------------------------------------------------------- introspection\n\n /** Invariant #6 — explain why an element sounds the way it does. Works before start(). */\n describe(el: Element): SonicProfile | null {\n return this.scanner.profileFor(el)\n }\n\n geometryChanged(): void {\n this.env.vw = window.innerWidth\n this.env.vh = window.innerHeight\n this.scanner?.updateEnv(this.env.vw, this.env.vh)\n this.scanner?.invalidateRects()\n }\n\n roomResized(): void {\n this.geometryChanged()\n this.room?.resize(this.env.vw)\n this.backend?.onViewport(this.env.vw)\n }\n\n // ---------------------------------------------------------------- events\n\n on(event: SonariumEvent, fn: (detail?: unknown) => void): () => void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set())\n this.listeners.get(event)!.add(fn)\n return () => this.listeners.get(event)?.delete(fn)\n }\n\n private emit(event: SonariumEvent, detail?: unknown): void {\n for (const fn of this.listeners.get(event) ?? []) {\n try { fn(detail) } catch (err) { console.warn('[sonarium] listener error', err) }\n }\n }\n}\n","export const clamp = (v: number, a: number, b: number): number => Math.min(b, Math.max(a, v))\n\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t\n\n/** Normalized position of v in [a, b], clamped to [0, 1]. */\nexport const norm = (v: number, a: number, b: number): number => clamp((v - a) / (b - a), 0, 1)\n\n/** FNV-1a 32-bit — stable, dependency-free hash for site identity (MAPPING.md §0). */\nexport function fnv1a(str: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n}\n","import { clamp, fnv1a } from './util'\n\n/** MAPPING.md §0 — the five scales reachable from a hostname hash. */\nexport const SCALES: Record<string, readonly number[]> = {\n pentMajor: [0, 2, 4, 7, 9],\n pentMinor: [0, 3, 5, 7, 10],\n dorian: [0, 2, 3, 5, 7, 9, 10],\n lydian: [0, 2, 4, 6, 7, 9, 11],\n mixolydian: [0, 2, 4, 5, 7, 9, 10],\n} as const\n\nexport const SCALE_NAMES = Object.keys(SCALES) as (keyof typeof SCALES)[]\n\nexport const OCTAVES = 3\n/** C3 — the bottom of the 3-octave pitch space. */\nexport const BASE_MIDI = 48\n\nconst NOTE_TO_PC: Record<string, number> = {\n C: 0, 'C#': 1, Db: 1, D: 2, 'D#': 3, Eb: 3, E: 4, F: 5, 'F#': 6,\n Gb: 6, G: 7, 'G#': 8, Ab: 8, A: 9, 'A#': 10, Bb: 10, B: 11,\n}\n\nconst PC_TO_NOTE = ['C', 'C#', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B'] as const\n\nexport interface SiteKey {\n root: number\n scaleName: string\n scale: readonly number[]\n label: string\n}\n\n/** Deterministic per-domain musical identity (T8 audio branding). Same host → same key, always. */\nexport function siteKey(hostname: string): SiteKey {\n const host = hostname || 'localhost'\n const h = fnv1a(host)\n const root = h % 12\n const scaleName = SCALE_NAMES[(h >>> 4) % SCALE_NAMES.length] as string\n const scale = SCALES[scaleName] as readonly number[]\n return { root, scaleName, scale, label: `${PC_TO_NOTE[root]} ${scaleName}` }\n}\n\n/** Parse \"D dorian\" / \"Eb pentMinor\" → SiteKey. Returns null when unrecognized. */\nexport function parseKey(spec: string): SiteKey | null {\n const m = spec.trim().match(/^([A-Ga-g][#b]?)\\s+(\\w+)$/)\n if (!m) return null\n const note = (m[1] as string).charAt(0).toUpperCase() + (m[1] as string).slice(1)\n const root = NOTE_TO_PC[note]\n const scaleName = m[2] as string\n const scale = SCALES[scaleName]\n if (root === undefined || !scale) return null\n return { root, scaleName, scale, label: `${PC_TO_NOTE[root]} ${scaleName}` }\n}\n\n/**\n * The Musical Quantizer (Invariant #2): degree ∈ [0,1] → MIDI note inside the key,\n * laid across OCTAVES octaves from BASE_MIDI + root. stepOffset shifts by whole scale steps\n * (sibling melodies S4, heading registers S6, kiki nudge G10).\n */\nexport function degreeToMidi(degree: number, key: SiteKey, stepOffset = 0): number {\n const steps = key.scale.length * OCTAVES\n let idx = Math.round(clamp(degree, 0, 1) * (steps - 1)) + Math.round(stepOffset)\n idx = clamp(idx, 0, steps - 1)\n const oct = Math.floor(idx / key.scale.length)\n const pc = key.scale[idx % key.scale.length] as number\n return BASE_MIDI + key.root + oct * 12 + pc\n}\n\nexport const midiToFreq = (m: number): number => 440 * Math.pow(2, (m - 69) / 12)\n\n/**\n * Walk N scale steps up/down from a midi note, staying on the key's pitch classes\n * (the ribbon controller's quantizer — MODULAR.md §3; Invariant #2 holds under drag).\n */\nexport function stepInScale(midi: number, key: SiteKey, steps: number): number {\n if (steps === 0) return midi\n const pcs = key.scale.map((s) => (s + key.root) % 12)\n const dir = steps > 0 ? 1 : -1\n let m = midi\n for (let i = 0; i < Math.abs(steps); i++) {\n do {\n m += dir\n } while (!pcs.includes(((m % 12) + 12) % 12) && m > 12 && m < 120)\n }\n return clamp(m, 12, 120)\n}\n\nexport function midiToNoteName(m: number): string {\n const pc = ((m % 12) + 12) % 12\n return `${PC_TO_NOTE[pc]}${Math.floor(m / 12) - 1}`\n}\n","/**\n * The Modular patch — MODULAR.md made executable. CSS properties plug modulation cables:\n * border-width drives the wavefolder, texture×edge sets FM, mass thickens unison, animation\n * and dashed borders patch the LFO. Pure: no DOM, no Tone.\n */\nimport { clamp } from './util'\n\nexport interface ModularVisuals {\n /** seconds; 0 = no animation */\n animationS: number\n borderStyle: 'solid' | 'dashed' | 'dotted' | 'none'\n borderWidthPx: number\n /** seconds; 0 = no transition */\n transitionS: number\n}\n\nexport interface PatchParams {\n fold: { drive: number; mix: number }\n fm: { index: number }\n unison: { detuneCents: number; mix: number }\n lfo: { rateHz: number; shape: 'sine' | 'square'; vibratoCents: number; tremolo: number; filterDepth: number }\n portamentoS: number\n}\n\n/** M1 — heavy borders saturate: drive ∈ [0,1], mix follows. */\nexport function foldFromBorder(borderWidthPx: number, edge: number): PatchParams['fold'] {\n const drive = clamp(borderWidthPx / 6, 0, 1) * (0.25 + 0.75 * clamp(edge, 0, 1))\n return { drive, mix: drive > 0.01 ? 0.25 + 0.55 * drive : 0 }\n}\n\n/** M2 — rough sharp surfaces ring metallic (audio-rate FM index, × carrier Hz in-voice). */\nexport const fmIndex = (texture: number, edge: number): number =>\n 1.5 * clamp(texture, 0, 1) * clamp(edge, 0, 1)\n\n/** M3 — big elements are thick, not just low. */\nexport function unisonFromMass(mass: number): PatchParams['unison'] {\n const m = clamp(mass, 0, 1)\n return m >= 0.45 ? { detuneCents: 4 + 10 * m, mix: 0.4 } : { detuneCents: 0, mix: 0 }\n}\n\n/** M4/M5 — the LFO patch bay: animation owns it; dashed/dotted borders chop; else idle. */\nexport function lfoFromCss(animationS: number, borderStyle: ModularVisuals['borderStyle']): PatchParams['lfo'] {\n if (animationS > 0.05) {\n return {\n rateHz: clamp(1 / animationS, 0.08, 8),\n shape: borderStyle === 'dashed' || borderStyle === 'dotted' ? 'square' : 'sine',\n vibratoCents: 6,\n tremolo: 0.18,\n filterDepth: 0.25,\n }\n }\n if (borderStyle === 'dashed' || borderStyle === 'dotted') {\n return {\n rateHz: borderStyle === 'dotted' ? 7 : 3.5,\n shape: 'square',\n vibratoCents: 0,\n tremolo: 0.3,\n filterDepth: 0.35,\n }\n }\n return { rateHz: 0, shape: 'sine', vibratoCents: 0, tremolo: 0, filterDepth: 0 }\n}\n\n/** M6 — elements that ease visually ease in pitch. Seconds added to the glide. */\nexport const portamentoFromTransition = (transitionS: number): number =>\n clamp(transitionS / 2, 0, 0.25)\n\n/** M7 — typography enters the weave: bold text carries weight (MASS bonus). */\nexport const massBonusFromFontWeight = (weight: number): number =>\n clamp((weight - 400) / 300, 0, 1) * 0.12\n\nexport function patchFrom(matter: { edge: number; mass: number; texture: number }, visuals: ModularVisuals): PatchParams {\n return {\n fold: foldFromBorder(visuals.borderWidthPx, matter.edge),\n fm: { index: fmIndex(matter.texture, matter.edge) },\n unison: unisonFromMass(matter.mass),\n lfo: lfoFromCss(visuals.animationS, visuals.borderStyle),\n portamentoS: portamentoFromTransition(visuals.transitionS),\n }\n}\n\n/**\n * The wavefolder transfer curve: y = sin(2.5·(π/2)·x). Near-linear for quiet signals,\n * folding for hot ones — the amp envelope sweeps the spectrum through the fold every note.\n */\nexport function foldCurve(samples = 2049): Float32Array {\n const out = new Float32Array(samples)\n for (let i = 0; i < samples; i++) {\n const x = (i / (samples - 1)) * 2 - 1\n out[i] = Math.sin(2.5 * (Math.PI / 2) * x)\n }\n return out\n}\n\n/** Drag-glissando ribbon (MODULAR.md §3): horizontal travel → scale-step offset, ±1 octave. */\nexport function ribbonSteps(dxPx: number, vw: number, scaleLen: number): number {\n const t = clamp(dxPx / (vw * 0.6), -1, 1)\n return Math.round(t * scaleLen)\n}\n","/**\n * The Chroma weave — CHROMA.md made executable. Color tints the Matter voice per element and\n * chooses the musical mode per page. Pure: no DOM, no Tone.\n */\nimport { clamp, lerp } from './util'\n\nexport interface Rgb {\n r: number\n g: number\n b: number\n a: number\n}\n\nexport interface Hsl {\n h: number\n s: number\n l: number\n}\n\nexport interface Chroma {\n /** 0 cool … 1 warm (desaturated colors regress to 0.5) */\n warmth: number\n saturation: number\n luminance: number\n}\n\n/** Computed styles emit rgb()/rgba(). Returns null for anything else (treat as no color). */\nexport function parseCssColor(css: string): Rgb | null {\n const m = css.trim().match(/^rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\s*(?:,\\s*(\\d*(?:\\.\\d+)?)\\s*)?\\)$/)\n if (!m) return null\n return {\n r: clamp(parseFloat(m[1] as string) / 255, 0, 1),\n g: clamp(parseFloat(m[2] as string) / 255, 0, 1),\n b: clamp(parseFloat(m[3] as string) / 255, 0, 1),\n a: m[4] === undefined ? 1 : clamp(parseFloat(m[4] as string), 0, 1),\n }\n}\n\nexport function rgbToHsl({ r, g, b }: Rgb): Hsl {\n const max = Math.max(r, g, b)\n const min = Math.min(r, g, b)\n const l = (max + min) / 2\n const d = max - min\n if (d < 1e-6) return { h: 0, s: 0, l }\n const s = d / (1 - Math.abs(2 * l - 1))\n let h: number\n if (max === r) h = ((g - b) / d) % 6\n else if (max === g) h = (b - r) / d + 2\n else h = (r - g) / d + 4\n h *= 60\n if (h < 0) h += 360\n return { h, s: clamp(s, 0, 1), l }\n}\n\n/** CHROMA.md §1 — cosine distance of hue from 30° (orange); greys regress to neutral 0.5. */\nexport function warmthFromHue(h: number, s: number): number {\n const raw = 0.5 + 0.5 * Math.cos(((h - 30) * Math.PI) / 180)\n return lerp(0.5, raw, clamp(s * 2, 0, 1))\n}\n\nexport function chromaOf(rgb: Rgb | null): Chroma {\n if (!rgb || rgb.a < 0.05) return { warmth: 0.5, saturation: 0, luminance: 0.5 }\n const { h, s, l } = rgbToHsl(rgb)\n return { warmth: warmthFromHue(h, s), saturation: s, luminance: l }\n}\n\n// ------------------------------------------------------------- element weave (CH1–CH5)\n\n/** CH1 — dark UI sounds dark. */\nexport const brightnessFromLuminance = (l: number): number => lerp(0.78, 1.22, clamp(l, 0, 1))\n\n/** CH2 — bright lifts, gently. */\nexport const velocityFromLuminance = (l: number): number => lerp(0.92, 1.06, clamp(l, 0, 1))\n\n/** CH3 — warm = energetic onset (thesis T5). Multiplier on the woven attack. */\nexport const attackScaleFromWarmth = (w: number): number => lerp(1.18, 0.82, clamp(w, 0, 1))\n\n/** CH4 — warm = full-bodied: bonus on the sub oscillator level (subs only, not shimmer). */\nexport const subBonusFromWarmth = (w: number): number => 0.08 * clamp(w, 0, 1)\n\n/** CH5 — vivid color = vivid spectrum: richness passed to genPartials (rolloff reduction). */\nexport const richnessFromSaturation = (s: number): number => 0.35 * clamp(s, 0, 1)\n\n// ------------------------------------------------------------- page weave (CH6–CH8)\n\nexport type ModeName = 'lydian' | 'mixolydian' | 'dorian' | 'pentMinor' | null\n\n/**\n * CH6 — the palette chooses the mode; null = neutral, keep the hostname-hashed scale\n * (identity unchanged). Root pitch-class always stays hostname-hashed (S9).\n */\nexport function modeFromPalette(pal: Chroma): ModeName {\n if (pal.warmth >= 0.55) return pal.luminance >= 0.5 ? 'lydian' : 'mixolydian'\n if (pal.warmth <= 0.45) return pal.luminance >= 0.5 ? 'dorian' : 'pentMinor'\n return null\n}\n\n/** Visual weight of the page: bg dominates, text tints. */\nexport function pagePalette(bg: Chroma, text: Chroma): Chroma {\n return {\n warmth: bg.warmth * 0.7 + text.warmth * 0.3,\n saturation: bg.saturation * 0.7 + text.saturation * 0.3,\n luminance: bg.luminance * 0.7 + text.luminance * 0.3,\n }\n}\n\n/** CH7 — warm rooms hum warmer. Multiplier on the ambience cutoff. */\nexport const roomToneScaleFromWarmth = (w: number): number => lerp(0.85, 1.25, clamp(w, 0, 1))\n\n/** CH8 — warm pages run slightly faster (consumed by PULSE.md P2). */\nexport const tempoScaleFromWarmth = (w: number): number => lerp(0.94, 1.06, clamp(w, 0, 1))\n","/**\n * The Pulse — PULSE.md made executable: tempo from the layout, grid offsets for echoes,\n * metered strum spacing, and the calm system. Pure: no DOM, no Tone.\n * THE LATENCY INVARIANT (PULSE.md §0): nothing here ever delays a primary hit.\n */\nimport { clamp, lerp } from './util'\n\n/** P1+P2 — layout density × page warmth → bpm, clamped to [56, 116]. */\nexport function tempoFromPage(elementCount: number, warmthScale: number): number {\n const base = lerp(66, 104, clamp(elementCount / 120, 0, 1))\n return Math.round(clamp(base * warmthScale, 56, 116))\n}\n\nexport const secondsPerBeat = (bpm: number): number => 60 / Math.max(1, bpm)\n\n/**\n * P3 — offset (seconds from now) to the next grid boundary of `gridS` seconds that is at\n * least `minAheadS` away. `phaseS` = seconds elapsed since the grid's epoch.\n */\nexport function nextGridOffset(phaseS: number, gridS: number, minAheadS: number): number {\n if (gridS <= 0) return minAheadS\n let offset = gridS - (((phaseS % gridS) + gridS) % gridS)\n while (offset < minAheadS) offset += gridS\n return offset\n}\n\n/** Strums step in 32nd notes — the same gesture, now in the groove. Seconds. */\nexport const strumStepS = (bpm: number): number => secondsPerBeat(bpm) / 8\n\n/** Echoes answer on 8ths, one octave up, quiet (PULSE.md §2). */\nexport const ECHO_TRANSPOSE = 12\nexport const ECHO_VELOCITY_SCALE = 0.22\nexport const ECHO_MIN_AHEAD_S = 0.08\nexport const echoGridS = (bpm: number): number => secondsPerBeat(bpm) / 2\n\n// ------------------------------------------------------------- the calm system (P5)\n\nexport const DUCK_RECOVERY_MS = 2000\n\n/** Activity count decays linearly: fully forgiven after count·2 s of silence. */\nexport const decayCount = (count: number, dtMs: number): number =>\n Math.max(0, count - dtMs / DUCK_RECOVERY_MS)\n\n/** Velocity multiplier: the 6th rapid repeat sits at ~40%, never below. */\nexport const duckFactor = (count: number): number =>\n Math.max(0.4, Math.pow(0.85, Math.max(0, count)))\n\n// ------------------------------------------------------------- phrases (P4)\n\nexport const PHRASE_PROBABILITY = 0.55\nexport const PHRASE_MIN_NOTES = 2\nexport const PHRASE_MAX_NOTES = 4\n\n/** Reading order: rows of ~80 px, then left→right. Sort key for (top, left). */\nexport const readingOrderKey = (top: number, left: number): number =>\n Math.round(top / 80) * 100000 + clamp(left, 0, 99999)\n\n/**\n * Window the score by scroll progress: with n elements and a phrase of len, the playhead\n * starts at `progress·(n − len)`.\n */\nexport function phraseWindow(n: number, len: number, progress: number): number {\n return Math.round(clamp(progress, 0, 1) * Math.max(0, n - len))\n}\n","/**\n * L3 Composition — themes are plain data (MAPPING.md §3). Adding a theme means adding an\n * object here; no engine code may special-case a theme name.\n */\nimport type { Theme } from '../types'\n\n// v0.3: aurora speaks through the woven MatterVoice — geometry IS the instrument\n// (MATTER.md). fm bells (headings) and membrane thuds (media) stay as character voices.\nconst aurora: Theme = {\n name: 'aurora',\n defaults: { synthKind: 'matter', octaveShift: 0, baseVelocity: 0.8, releaseScale: 1 },\n roles: {\n toggle: { synthKind: 'matter', baseVelocity: 0.7, releaseScale: 0.8 },\n button: { synthKind: 'matter', baseVelocity: 0.9 },\n link: { synthKind: 'matter', octaveShift: 1, baseVelocity: 0.6, releaseScale: 0.7 },\n input: { synthKind: 'matter', baseVelocity: 0.55, releaseScale: 1.6 },\n heading: { synthKind: 'fm', octaveShift: 0, baseVelocity: 0.75, releaseScale: 2.2 },\n media: { synthKind: 'membrane', octaveShift: -1, baseVelocity: 0.8 },\n item: { synthKind: 'matter', baseVelocity: 0.6, releaseScale: 0.8 },\n text: { synthKind: 'matter', baseVelocity: 0.35, releaseScale: 1.8 },\n },\n}\n\nconst mono: Theme = {\n name: 'mono',\n defaults: { synthKind: 'synth', octaveShift: 0, baseVelocity: 0.7, releaseScale: 0.5 },\n roles: {\n toggle: { synthKind: 'noise', baseVelocity: 0.6 },\n button: { synthKind: 'synth', pinWave: 'square', baseVelocity: 0.7, releaseScale: 0.4 },\n link: { synthKind: 'noise', baseVelocity: 0.45, releaseScale: 0.3 },\n input: { synthKind: 'synth', pinWave: 'sine', octaveShift: -1, baseVelocity: 0.5 },\n heading: { synthKind: 'synth', pinWave: 'sine', octaveShift: 1, baseVelocity: 0.6 },\n media: { synthKind: 'noise', baseVelocity: 0.55 },\n item: { synthKind: 'noise', baseVelocity: 0.4, releaseScale: 0.3 },\n text: { synthKind: 'synth', pinWave: 'sine', baseVelocity: 0 },\n },\n}\n\nconst paper: Theme = {\n name: 'paper',\n defaults: { synthKind: 'pluck', octaveShift: 0, baseVelocity: 0.8, releaseScale: 1 },\n roles: {\n toggle: { synthKind: 'pluck', baseVelocity: 0.7 },\n button: { synthKind: 'pluck', baseVelocity: 0.9 },\n link: { synthKind: 'pluck', octaveShift: 1, baseVelocity: 0.65 },\n input: { synthKind: 'synth', pinWave: 'triangle', baseVelocity: 0.5, releaseScale: 1.4 },\n heading: { synthKind: 'pluck', octaveShift: -1, baseVelocity: 0.85, releaseScale: 1.6 },\n media: { synthKind: 'membrane', octaveShift: -1, baseVelocity: 0.7 },\n item: { synthKind: 'pluck', baseVelocity: 0.6 },\n text: { synthKind: 'synth', pinWave: 'sine', baseVelocity: 0.3, releaseScale: 1.6 },\n },\n}\n\nexport const THEMES: Record<string, Theme> = { aurora, mono, paper }\n\nexport function resolveTheme(theme: string | Theme | undefined): Theme {\n if (!theme) return aurora\n if (typeof theme === 'string') return THEMES[theme] ?? aurora\n return theme\n}\n","/**\n * The unlock & mute chip — autoplay policy treated as a feature (PLAN.md R2).\n * Shadow DOM so host styles can't break it; ARIA so keyboard/SR users get the same control.\n */\nconst STORAGE_KEY = 'sonarium:muted'\n\nexport const isMutedPersisted = (): boolean => {\n try { return localStorage.getItem(STORAGE_KEY) === '1' } catch { return false }\n}\n\nexport const persistMuted = (muted: boolean): void => {\n try { localStorage.setItem(STORAGE_KEY, muted ? '1' : '0') } catch { /* private mode */ }\n}\n\nexport interface GateHandle {\n setState: (state: 'armed' | 'on' | 'muted') => void\n dispose: () => void\n}\n\nexport function mountGate(onToggle: () => void): GateHandle {\n const host = document.createElement('div')\n host.setAttribute('data-sonic', 'off') // the chip itself must never sound\n const shadow = host.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n button {\n position: fixed; right: 16px; bottom: 16px; z-index: 2147483646;\n width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,255,255,.25);\n background: rgba(20, 22, 30, .82); color: #fff; font-size: 18px; line-height: 1;\n cursor: pointer; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);\n box-shadow: 0 4px 16px rgba(0,0,0,.35); transition: transform .15s ease, opacity .3s ease;\n }\n button:hover { transform: scale(1.08); }\n button:focus-visible { outline: 2px solid #7cd4fd; outline-offset: 2px; }\n button.armed { animation: pulse 1.6s ease-in-out infinite; }\n @keyframes pulse { 0%,100% { box-shadow: 0 4px 16px rgba(0,0,0,.35); } 50% { box-shadow: 0 0 0 10px rgba(124,212,253,.18); } }\n </style>\n <button type=\"button\" class=\"armed\" aria-label=\"Enable sound\" title=\"Sonarium — enable sound\">🔇</button>\n `\n const btn = shadow.querySelector('button') as HTMLButtonElement\n btn.addEventListener('click', (e) => {\n e.stopPropagation()\n onToggle()\n })\n document.body.appendChild(host)\n\n return {\n setState(state) {\n btn.classList.toggle('armed', state === 'armed')\n if (state === 'on') {\n btn.textContent = '🔊'\n btn.setAttribute('aria-label', 'Mute Sonarium')\n } else if (state === 'muted') {\n btn.textContent = '🔇'\n btn.setAttribute('aria-label', 'Unmute Sonarium')\n } else {\n btn.textContent = '🔇'\n btn.setAttribute('aria-label', 'Enable sound')\n }\n },\n dispose() {\n host.remove()\n },\n }\n}\n","/**\n * SpatialBackend — the seam between the voice pool and the spatial engine (SPATIAL.md §6).\n * 'ambisonic' encodes every lane into the shared FOA field; 'panner' is the v0.1 per-voice\n * HRTF path, kept as option and automatic fallback. Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport { clamp } from '../math/util'\nimport type { SonicProfile } from '../types'\nimport type { Room } from '../core/room'\nimport { AmbisonicBus } from './bus'\nimport { SourceEncoder } from './encoder'\nimport { FoaRoom } from './room-foa'\nimport { foaGains } from './sh'\nimport type { Mat3 } from './rotation'\nimport {\n directGain, directivityDirectGain, directivitySendScale, resolveFactors,\n roomGain, type PerceptualFactors,\n} from './perceptual'\n\nexport interface LaneOutput {\n /** The lane's filter connects here. */\n input: Tone.InputNode\n /** Place the voice in space from its profile (called at trigger time). */\n setPlacement(profile: SonicProfile, when?: number): void\n dispose(): void\n}\n\nexport interface SpatialBackend {\n readonly kind: 'ambisonic' | 'panner'\n createOutput(): LaneOutput\n setFactors(factors: PerceptualFactors): void\n /** Rotate the field (ambisonic) — no-op on the panner backend. */\n setRotation(m: Mat3): void\n onViewport(vw: number): void\n dispose(): void\n}\n\n// ---------------------------------------------------------------------------- ambisonic\n\nexport class AmbisonicBackend implements SpatialBackend {\n readonly kind = 'ambisonic' as const\n private bus: AmbisonicBus\n private foaRoom: FoaRoom\n private factors: PerceptualFactors\n\n constructor(private room: Room, decoderKind: 'binaural' | 'stereo', vw: number, factors?: Partial<PerceptualFactors>) {\n this.factors = resolveFactors(factors)\n this.bus = new AmbisonicBus(room.spatialIn, decoderKind)\n this.foaRoom = new FoaRoom(this.bus.inputs, room.reverb, vw, this.factors)\n }\n\n createOutput(): LaneOutput {\n const enc = new SourceEncoder(this.bus.inputs)\n const send = new Tone.Gain(0.15)\n // MATTER.md reverb weave: dark sources bloom dark — the tail is colored per voice.\n const sendColor = new Tone.Filter({ type: 'lowpass', frequency: 5000, rolloff: -12 })\n enc.input.connect(send)\n send.connect(sendColor)\n sendColor.connect(this.room.reverb)\n enc.input.connect(this.foaRoom.erIn)\n const backend = this\n return {\n input: enc.input,\n setPlacement(profile: SonicProfile, when?: number) {\n const t = when ?? Tone.now()\n const s = profile.sphere\n const w = profile.voice.reverb\n const extent = clamp(s.extent + w.extentBonus, 0, 0.95)\n const g = foaGains(s.azimuth, s.elevation, extent)\n const direct = directGain(backend.factors.presence) * directivityDirectGain(s.directivity)\n enc.set(g, direct, when)\n const wetSend = clamp(\n profile.reverbSend * directivitySendScale(s.directivity) * roomGain(backend.factors.roomPresence),\n 0,\n 1.5,\n )\n sendColor.frequency.rampTo(w.sendCutoffHz, 0.02, t)\n send.gain.cancelScheduledValues(t)\n if (w.bloom > 0.35) {\n // round sources swell into the room over the note; sharp ones arrive dry-then-done\n send.gain.setValueAtTime(wetSend * 0.35, t)\n send.gain.rampTo(wetSend, Math.max(0.08, profile.durationS), t)\n } else {\n send.gain.rampTo(wetSend, 0.02, t)\n }\n },\n dispose() {\n enc.dispose()\n send.dispose()\n sendColor.dispose()\n },\n }\n }\n\n setFactors(factors: PerceptualFactors): void {\n this.factors = factors\n this.foaRoom.setFactors(factors)\n this.room.setFactors(factors)\n }\n\n setRotation(m: Mat3): void {\n this.bus.setRotation(m)\n }\n\n onViewport(vw: number): void {\n this.foaRoom.setViewport(vw)\n }\n\n dispose(): void {\n this.foaRoom.dispose()\n this.bus.dispose()\n }\n}\n\n// ---------------------------------------------------------------------------- panner (v0.1)\n\nexport class PannerBackend implements SpatialBackend {\n readonly kind = 'panner' as const\n\n constructor(private room: Room, private panningModel: 'HRTF' | 'equalpower') {}\n\n createOutput(): LaneOutput {\n const panner = new Tone.Panner3D({\n panningModel: this.panningModel,\n distanceModel: 'inverse',\n refDistance: 1,\n rolloffFactor: 0.4,\n positionX: 0, positionY: 0, positionZ: -2,\n })\n const dry = new Tone.Gain(1)\n const send = new Tone.Gain(0.18)\n const sendColor = new Tone.Filter({ type: 'lowpass', frequency: 5000, rolloff: -12 })\n panner.connect(dry)\n panner.connect(send)\n send.connect(sendColor)\n dry.connect(this.room.buses.dryIn)\n sendColor.connect(this.room.buses.wetIn)\n return {\n input: panner,\n setPlacement(profile: SonicProfile, when?: number) {\n const t = when ?? Tone.now()\n panner.positionX.rampTo(profile.pan.x, 0.02, t)\n panner.positionY.rampTo(profile.pan.y, 0.02, t)\n panner.positionZ.rampTo(profile.pan.z, 0.02, t)\n sendColor.frequency.rampTo(profile.voice.reverb.sendCutoffHz, 0.02, t)\n send.gain.rampTo(clamp(profile.reverbSend, 0, 1), 0.02, t)\n },\n dispose() {\n panner.dispose()\n dry.dispose()\n send.dispose()\n sendColor.dispose()\n },\n }\n }\n\n setFactors(factors: PerceptualFactors): void {\n this.room.setFactors(factors)\n }\n\n setRotation(): void { /* the panner world rotates via Tone.Listener (ListenerRig) */ }\n\n onViewport(): void { /* room resize handled by Room */ }\n\n dispose(): void { /* lane outputs disposed by the pool */ }\n}\n","/**\n * AmbisonicBus — the field itself (SPATIAL.md §3): W/Y/Z/X summing buses → live 3×3 rotation\n * (nine GainNodes; W invariant) → binaural decode through fixed virtual speakers, each rendered\n * by one native HRTF PannerNode. Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport { CUBE_LAYOUT, decodeMatrix } from './decoder'\nimport { IDENTITY, type Mat3 } from './rotation'\nimport type { BusInputs } from './encoder'\n\nconst SPEAKER_RADIUS = 2.5\n\nexport class AmbisonicBus {\n readonly inputs: BusInputs\n private rot: Tone.Gain[][] // rot[out][in] over (X, Y, Z) = indices 0,1,2\n private outW: Tone.Gain\n private outXYZ: [Tone.Gain, Tone.Gain, Tone.Gain]\n private nodes: { dispose(): void }[] = []\n\n constructor(destination: Tone.InputNode, decoderKind: 'binaural' | 'stereo') {\n this.inputs = { w: new Tone.Gain(1), y: new Tone.Gain(1), z: new Tone.Gain(1), x: new Tone.Gain(1) }\n this.outW = new Tone.Gain(1)\n this.outXYZ = [new Tone.Gain(1), new Tone.Gain(1), new Tone.Gain(1)]\n this.inputs.w.connect(this.outW)\n\n // Rotation matrix acts on the (X, Y, Z) triple: out = R · in.\n const inXYZ = [this.inputs.x, this.inputs.y, this.inputs.z]\n this.rot = []\n for (let r = 0; r < 3; r++) {\n const row: Tone.Gain[] = []\n for (let c = 0; c < 3; c++) {\n const g = new Tone.Gain(IDENTITY[r]![c]!)\n inXYZ[c]!.connect(g)\n g.connect(this.outXYZ[r]!)\n row.push(g)\n }\n this.rot.push(row)\n }\n\n if (decoderKind === 'stereo') this.buildStereoDecode(destination)\n else this.buildVirtualSpeakerDecode(destination)\n\n this.nodes.push(this.inputs.w, this.inputs.y, this.inputs.z, this.inputs.x, this.outW, ...this.outXYZ, ...this.rot.flat())\n }\n\n /** SPATIAL.md §3.2 — 8 cube speakers, each a static mix of (W, X', Y', Z') into a fixed HRTF panner. */\n private buildVirtualSpeakerDecode(destination: Tone.InputNode): void {\n const rows = decodeMatrix(CUBE_LAYOUT)\n rows.forEach((row, i) => {\n const dir = CUBE_LAYOUT[i]!.dir\n const sum = new Tone.Gain(1)\n const mw = new Tone.Gain(row.w)\n const mx = new Tone.Gain(row.x)\n const my = new Tone.Gain(row.y)\n const mz = new Tone.Gain(row.z)\n this.outW.connect(mw)\n this.outXYZ[0]!.connect(mx)\n this.outXYZ[1]!.connect(my)\n this.outXYZ[2]!.connect(mz)\n mw.connect(sum)\n mx.connect(sum)\n my.connect(sum)\n mz.connect(sum)\n // AmbiX (+x fwd, +y left, +z up) → WebAudio (+x right, +y up, −z fwd).\n const panner = new Tone.Panner3D({\n panningModel: 'HRTF',\n distanceModel: 'inverse',\n refDistance: SPEAKER_RADIUS,\n rolloffFactor: 0, // fixed-radius speakers: direction only, no distance shading\n positionX: -dir[1] * SPEAKER_RADIUS,\n positionY: dir[2] * SPEAKER_RADIUS,\n positionZ: -dir[0] * SPEAKER_RADIUS,\n })\n sum.connect(panner)\n panner.connect(destination)\n this.nodes.push(sum, mw, mx, my, mz, panner)\n })\n }\n\n /** Fallback decode without HRTF: two virtual cardioids at ±90° (SPATIAL.md §3.2). */\n private buildStereoDecode(destination: Tone.InputNode): void {\n const L = new Tone.Gain(1)\n const R = new Tone.Gain(1)\n const wL = new Tone.Gain(0.5)\n const wR = new Tone.Gain(0.5)\n const yL = new Tone.Gain(0.5)\n const yR = new Tone.Gain(-0.5)\n this.outW.connect(wL)\n this.outW.connect(wR)\n this.outXYZ[1]!.connect(yL)\n this.outXYZ[1]!.connect(yR)\n wL.connect(L)\n yL.connect(L)\n wR.connect(R)\n yR.connect(R)\n const merge = new Tone.Merge()\n L.connect(merge, 0, 0)\n R.connect(merge, 0, 1)\n merge.connect(destination)\n this.nodes.push(L, R, wL, wR, yL, yR, merge)\n }\n\n /** Rotate the whole field (FieldRig calls this with lookMatrix output). Ramped, zipper-free. */\n setRotation(m: Mat3, rampS = 0.04): void {\n for (let r = 0; r < 3; r++)\n for (let c = 0; c < 3; c++)\n this.rot[r]![c]!.gain.rampTo(m[r]![c]!, rampS)\n }\n\n dispose(): void {\n for (const n of this.nodes) n.dispose()\n this.nodes = []\n }\n}\n","/**\n * Pure spherical-harmonic encoding — SPATIAL.md §1–2. AmbiX: ACN order [W, Y, Z, X],\n * SN3D normalization, +x forward, +y left, +z up, +azimuth left. No DOM, no Tone.\n */\n\nexport const DEG = Math.PI / 180\n\n/** ACN channel indices, for readability everywhere else. */\nexport const ACN = { W: 0, Y: 1, Z: 2, X: 3 } as const\n\nexport interface FoaGains {\n w: number\n y: number\n z: number\n x: number\n}\n\n/**\n * First-order encode of a plane wave from (azimuth, elevation), with extent σ blending the\n * directional components into the omni channel (SPATIAL.md §2). Angles in radians.\n */\nexport function foaGains(azimuth: number, elevation: number, extent = 0): FoaGains {\n const s = Math.min(1, Math.max(0, extent))\n const cosEl = Math.cos(elevation)\n const dir = 1 - s\n return {\n w: 1 + 0.41 * s,\n y: dir * Math.sin(azimuth) * cosEl,\n z: dir * Math.sin(elevation),\n x: dir * Math.cos(azimuth) * cosEl,\n }\n}\n\n/** Unit direction vector for (azimuth, elevation) in the AmbiX frame. */\nexport function unitVector(azimuth: number, elevation: number): [number, number, number] {\n const cosEl = Math.cos(elevation)\n return [Math.cos(azimuth) * cosEl, Math.sin(azimuth) * cosEl, Math.sin(elevation)]\n}\n","/**\n * Pure FOA decoding — SPATIAL.md §3.2. Sampling decoder with max-rE weighting over a fixed\n * virtual-speaker layout; each speaker is later rendered by one native HRTF panner.\n */\nimport { unitVector, type FoaGains } from './sh'\n\nexport interface Speaker {\n /** Unit direction in the AmbiX frame. */\n dir: [number, number, number]\n label: string\n}\n\nconst C = 1 / Math.sqrt(3)\n\n/** Cube vertices: full-sphere coverage including elevation, symmetric, M = 8. */\nexport const CUBE_LAYOUT: Speaker[] = [\n { dir: [C, C, C], label: 'front-left-up' },\n { dir: [C, -C, C], label: 'front-right-up' },\n { dir: [C, C, -C], label: 'front-left-down' },\n { dir: [C, -C, -C], label: 'front-right-down' },\n { dir: [-C, C, C], label: 'back-left-up' },\n { dir: [-C, -C, C], label: 'back-right-up' },\n { dir: [-C, C, -C], label: 'back-left-down' },\n { dir: [-C, -C, -C], label: 'back-right-down' },\n]\n\n/** max-rE weights for 3D first order (Zotter & Frank): g0 = 1, g1 = 1/√3. */\nexport const MAXRE_G0 = 1\nexport const MAXRE_G1 = 1 / Math.sqrt(3)\n\nexport interface DecodeRow {\n /** Per-ACN gains [w, y, z, x] for one speaker: s = w·W + y·Y + z·Z + x·X. */\n w: number\n y: number\n z: number\n x: number\n}\n\n/**\n * Sampling decode matrix for SN3D input: sm = (1/M)·[g0·W + 3·g1·(X·xm + Y·ym + Z·zm)].\n * The 3 re-normalizes first-order SN3D to N3D inside the projection.\n */\nexport function decodeMatrix(layout: Speaker[]): DecodeRow[] {\n const M = layout.length\n return layout.map(({ dir }) => ({\n w: (1 / M) * MAXRE_G0,\n x: (3 / M) * MAXRE_G1 * dir[0],\n y: (3 / M) * MAXRE_G1 * dir[1],\n z: (3 / M) * MAXRE_G1 * dir[2],\n }))\n}\n\n/** Decode an encoded source to speaker signals (used by tests and the worklet path later). */\nexport function decodeGains(rows: DecodeRow[], g: FoaGains): number[] {\n return rows.map((r) => r.w * g.w + r.y * g.y + r.z * g.z + r.x * g.x)\n}\n\n/** Total decoded energy for a direction — tests assert flatness across the sphere. */\nexport function decodedEnergy(rows: DecodeRow[], azimuth: number, elevation: number): number {\n const v = unitVector(azimuth, elevation)\n const g: FoaGains = { w: 1, x: v[0], y: v[1], z: v[2] }\n return decodeGains(rows, g).reduce((acc, s) => acc + s * s, 0)\n}\n","/**\n * Pure field rotation — SPATIAL.md §3.1. The 3×3 matrix acts on the (X, Y, Z) channel triple\n * (W is rotation-invariant). Row-major: m[r][c], applied as X' = m00·X + m01·Y + m02·Z, etc.\n * Composition R = Rz(yaw) · Ry(pitch) · Rx(roll). Angles in radians.\n */\n\nexport type Mat3 = [\n [number, number, number],\n [number, number, number],\n [number, number, number],\n]\n\nexport const IDENTITY: Mat3 = [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1],\n]\n\nfunction mul(a: Mat3, b: Mat3): Mat3 {\n const out: Mat3 = [\n [0, 0, 0],\n [0, 0, 0],\n [0, 0, 0],\n ]\n for (let r = 0; r < 3; r++)\n for (let c = 0; c < 3; c++)\n out[r]![c] = a[r]![0]! * b[0]![c]! + a[r]![1]! * b[1]![c]! + a[r]![2]! * b[2]![c]!\n return out\n}\n\n/** Acts on column vectors (X, Y, Z)ᵀ in the AmbiX frame (+x fwd, +y left, +z up). */\nexport function rotationMatrix(yaw: number, pitch: number, roll = 0): Mat3 {\n const cy = Math.cos(yaw), sy = Math.sin(yaw)\n const cp = Math.cos(pitch), sp = Math.sin(pitch)\n const cr = Math.cos(roll), sr = Math.sin(roll)\n const Rz: Mat3 = [\n [cy, -sy, 0],\n [sy, cy, 0],\n [0, 0, 1],\n ]\n const Ry: Mat3 = [\n [cp, 0, sp],\n [0, 1, 0],\n [-sp, 0, cp],\n ]\n const Rx: Mat3 = [\n [1, 0, 0],\n [0, cr, -sr],\n [0, sr, cr],\n ]\n return mul(mul(Rz, Ry), Rx)\n}\n\nexport function applyMat3(m: Mat3, v: [number, number, number]): [number, number, number] {\n return [\n m[0]![0]! * v[0] + m[0]![1]! * v[1] + m[0]![2]! * v[2],\n m[1]![0]! * v[0] + m[1]![1]! * v[1] + m[1]![2]! * v[2],\n m[2]![0]! * v[0] + m[2]![1]! * v[1] + m[2]![2]! * v[2],\n ]\n}\n\n/**\n * Look semantics (SPATIAL.md §3.1): the field rotation is the INVERSE of the head's intrinsic\n * yaw-then-pitch rotation. Looking right by α (head Rz(−α)) and up by β (head Ry(−β)) gives\n * field R = (Rz(−α)·Ry(−β))⁻¹ = Ry(β)·Rz(α). The sign/composition decision lives here and\n * only here, pinned by tests: look right → right-side sources arrive frontward; look up →\n * overhead sources arrive frontward.\n */\nexport function lookMatrix(yawRight: number, pitchUp: number): Mat3 {\n const pitch = rotationMatrix(0, pitchUp, 0) // = Ry(pitchUp)\n const yaw = rotationMatrix(yawRight, 0, 0) // = Rz(yawRight)\n return mul(pitch, yaw)\n}\n","/**\n * SourceEncoder — one per voice lane: four GainNodes carrying the lane's mono signal into the\n * W/Y/Z/X buses with first-order SH gains (SPATIAL.md §2). Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport type { FoaGains } from './sh'\n\nexport interface BusInputs {\n w: Tone.Gain\n y: Tone.Gain\n z: Tone.Gain\n x: Tone.Gain\n}\n\nexport class SourceEncoder {\n readonly input: Tone.Gain\n private gw: Tone.Gain\n private gy: Tone.Gain\n private gz: Tone.Gain\n private gx: Tone.Gain\n\n constructor(bus: BusInputs) {\n this.input = new Tone.Gain(1)\n this.gw = new Tone.Gain(1)\n this.gy = new Tone.Gain(0)\n this.gz = new Tone.Gain(0)\n this.gx = new Tone.Gain(1)\n this.input.connect(this.gw)\n this.input.connect(this.gy)\n this.input.connect(this.gz)\n this.input.connect(this.gx)\n this.gw.connect(bus.w)\n this.gy.connect(bus.y)\n this.gz.connect(bus.z)\n this.gx.connect(bus.x)\n }\n\n /** Apply SH gains × an overall direct-path gain, ramped to avoid zipper noise. */\n set(g: FoaGains, directGain: number, when?: number, rampS = 0.015): void {\n const t = when ?? Tone.now()\n this.gw.gain.rampTo(g.w * directGain, rampS, t)\n this.gy.gain.rampTo(g.y * directGain, rampS, t)\n this.gz.gain.rampTo(g.z * directGain, rampS, t)\n this.gx.gain.rampTo(g.x * directGain, rampS, t)\n }\n\n dispose(): void {\n this.input.dispose()\n this.gw.dispose()\n this.gy.dispose()\n this.gz.dispose()\n this.gx.dispose()\n }\n}\n","/**\n * FoaRoom — the Spat room model in the field (SPATIAL.md §3.3): early reflections encoded at\n * mirror directions + the diffuse tail whose extent IS the envelopment factor. Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport { foaGains, DEG } from './sh'\nimport { reflectionScaleFromViewport } from './sphere'\nimport { roomGain, tailExtent, tailLevel, type PerceptualFactors } from './perceptual'\nimport { SourceEncoder, type BusInputs } from './encoder'\n\nconst ER_BASE_TIMES = [0.013, 0.019, 0.027, 0.034]\nconst ER_TAP_LEVELS = [1, 0.85, 0.7, 0.6]\nconst ER_DIRECTIONS: Array<[number, number]> = [\n [110 * DEG, 30 * DEG],\n [-110 * DEG, 30 * DEG],\n [110 * DEG, -30 * DEG],\n [-110 * DEG, -30 * DEG],\n]\n\nexport class FoaRoom {\n /** Lanes tap their direct signal here (mono sum). */\n readonly erIn: Tone.Gain\n private erMaster: Tone.Gain\n private delays: Tone.Delay[] = []\n private split: Tone.Split\n private tailL: SourceEncoder\n private tailR: SourceEncoder\n private nodes: { dispose(): void }[] = []\n\n constructor(bus: BusInputs, reverb: Tone.Reverb, vw: number, factors: PerceptualFactors) {\n this.erIn = new Tone.Gain(1)\n this.erMaster = new Tone.Gain(0.22 * roomGain(factors.roomPresence))\n this.erIn.connect(this.erMaster)\n\n const scale = reflectionScaleFromViewport(vw)\n ER_BASE_TIMES.forEach((t, i) => {\n const delay = new Tone.Delay({ delayTime: t * scale, maxDelay: 0.12 })\n const tap = new Tone.Gain(ER_TAP_LEVELS[i] as number)\n const enc = new SourceEncoder(bus)\n const [az, el] = ER_DIRECTIONS[i] as [number, number]\n enc.set(foaGains(az, el, 0.35), 1)\n this.erMaster.connect(delay)\n delay.connect(tap)\n tap.connect(enc.input)\n this.delays.push(delay)\n this.nodes.push(delay, tap, enc)\n })\n\n // Diffuse tail: reverb L/R become two wide sources at ±120°; their extent = envelopment.\n this.split = new Tone.Split()\n reverb.connect(this.split)\n this.tailL = new SourceEncoder(bus)\n this.tailR = new SourceEncoder(bus)\n this.split.connect(this.tailL.input, 0)\n this.split.connect(this.tailR.input, 1)\n this.applyTail(factors)\n this.nodes.push(this.erIn, this.erMaster, this.split, this.tailL, this.tailR)\n }\n\n private applyTail(f: PerceptualFactors): void {\n const ext = tailExtent(f.envelopment)\n const level = tailLevel(f.envelopment)\n this.tailL.set(foaGains(120 * DEG, 0, ext), level)\n this.tailR.set(foaGains(-120 * DEG, 0, ext), level)\n }\n\n setFactors(f: PerceptualFactors): void {\n this.erMaster.gain.rampTo(0.22 * roomGain(f.roomPresence), 0.1)\n this.applyTail(f)\n }\n\n setViewport(vw: number): void {\n const scale = reflectionScaleFromViewport(vw)\n this.delays.forEach((d, i) => d.delayTime.rampTo((ER_BASE_TIMES[i] as number) * scale, 0.3))\n }\n\n dispose(): void {\n for (const n of this.nodes) n.dispose()\n this.nodes = []\n }\n}\n","/**\n * Pure sphere mappings — SPATIAL.md §4 (canon rows SP1–SP5). The page is laid on the front\n * hemisphere of a sphere around the listener; geometry becomes spherical source properties.\n * No DOM, no Tone.\n */\nimport { clamp, norm } from '../math/util'\nimport { DEG } from './sh'\nimport type { Rect } from '../types'\n\nexport const AZ_MAX = 70 * DEG\nexport const EL_MAX = 45 * DEG\n\n/** SP1/SP2 — screen position → direction. Screen-right = −azimuth (sign tested). */\nexport function sphereFromRect(rect: Rect, vw: number, vh: number): { azimuth: number; elevation: number } {\n const tx = norm(rect.x + rect.w / 2, 0, vw)\n const ty = norm(rect.y + rect.h / 2, 0, vh)\n return {\n azimuth: -(2 * tx - 1) * AZ_MAX,\n elevation: (1 - 2 * ty) * EL_MAX,\n }\n}\n\n/** SP4 — big elements wrap around the listener (T2 extended into space). */\nexport function extentFromSize(sizeT: number): number {\n return clamp(0.05 + 0.75 * Math.pow(clamp(sizeT, 0, 1), 1.2), 0, 0.95)\n}\n\n/** SP5 — Kiki/Bouba in the spatial domain: sharp beams, round radiates. */\nexport function directivityFromRoundness(roundness: number): number {\n return clamp(1 - roundness, 0, 1)\n}\n\n/** SP6 — early-reflection time scale follows the room (viewport). */\nexport function reflectionScaleFromViewport(vw: number): number {\n return 0.6 + norm(vw, 360, 2200) * 1.0\n}\n","/**\n * Pure perceptual-factor formulas — SPATIAL.md §5. The spat5.oper surface: five factors in\n * [0,1], each mapping monotonically to DSP parameters. Defaults mirror the spec table.\n */\nimport { clamp, lerp } from '../math/util'\nimport type { PerceptualFactors } from '../types'\n\nexport type { PerceptualFactors }\n\nexport const DEFAULT_FACTORS: PerceptualFactors = {\n presence: 0.7,\n roomPresence: 0.5,\n envelopment: 0.55,\n warmth: 0.5,\n brilliance: 0.5,\n}\n\nexport function resolveFactors(partial: Partial<PerceptualFactors> | undefined): PerceptualFactors {\n const f = { ...DEFAULT_FACTORS, ...(partial ?? {}) }\n for (const k of Object.keys(f) as (keyof PerceptualFactors)[]) f[k] = clamp(f[k], 0, 1)\n return f\n}\n\n/** presence → direct-path gain (linear). */\nexport const directGain = (presence: number): number => lerp(0.5, 1.2, clamp(presence, 0, 1))\n\n/** roomPresence → early-reflection + reverb-send master (linear). */\nexport const roomGain = (roomPresence: number): number => lerp(0, 1.6, clamp(roomPresence, 0, 1))\n\n/** envelopment → diffuse-tail extent (σ of the tail encoders) and tail level. */\nexport const tailExtent = (envelopment: number): number => clamp(envelopment, 0, 1)\nexport const tailLevel = (envelopment: number): number => lerp(0.7, 1.25, clamp(envelopment, 0, 1))\n\n/** warmth → low-shelf dB at 250 Hz. */\nexport const warmthDb = (warmth: number): number => lerp(-3, 3, clamp(warmth, 0, 1))\n\n/** brilliance → high-shelf dB at 4 kHz. */\nexport const brillianceDb = (brilliance: number): number => lerp(-4, 3, clamp(brilliance, 0, 1))\n\n/** directivity δ → source presence/brightness/room behaviour (SPATIAL.md §2). */\nexport const directivityDirectGain = (d: number): number => lerp(0.75, 1.1, clamp(d, 0, 1))\nexport const directivitySendScale = (d: number): number => lerp(1.35, 0.8, clamp(d, 0, 1))\nexport const directivityFilterScale = (d: number): number => lerp(0.85, 1.15, clamp(d, 0, 1))\n","/**\n * FieldRig — embodiment for the ambisonic backend (SPATIAL.md §3.1): mouse-look on desktop,\n * device attitude on mobile, lerped per frame into one field rotation. Exposes the same\n * pointTo/tiltTo surface as the legacy ListenerRig so L2 drivers don't care which world they\n * live in.\n */\nimport { clamp, lerp } from '../math/util'\nimport { DEG } from './sh'\nimport { lookMatrix } from './rotation'\nimport type { SpatialBackend } from './backend'\n\nconst POINTER_YAW_MAX = 40 * DEG\nconst POINTER_PITCH_MAX = 20 * DEG\nconst TILT_YAW_MAX = 35 * DEG\nconst TILT_PITCH_MAX = 25 * DEG\n\nexport class FieldRig {\n private target = { yaw: 0, pitch: 0 }\n private tilt = { yaw: 0, pitch: 0 }\n private look = { yaw: 0, pitch: 0 }\n private raf = 0\n private running = false\n\n constructor(\n private backend: SpatialBackend,\n private mode: 'pointer' | 'center',\n ) {}\n\n start(): void {\n if (this.running) return\n this.running = true\n const step = () => {\n if (!this.running) return\n const gy = clamp(this.target.yaw + this.tilt.yaw, -Math.PI / 2, Math.PI / 2)\n const gp = clamp(this.target.pitch + this.tilt.pitch, -Math.PI / 3, Math.PI / 3)\n const ny = lerp(this.look.yaw, gy, 0.1)\n const np = lerp(this.look.pitch, gp, 0.1)\n if (Math.abs(ny - this.look.yaw) > 1e-4 || Math.abs(np - this.look.pitch) > 1e-4) {\n this.look.yaw = ny\n this.look.pitch = np\n this.backend.setRotation(lookMatrix(this.look.yaw, this.look.pitch))\n }\n this.raf = requestAnimationFrame(step)\n }\n this.raf = requestAnimationFrame(step)\n }\n\n /** I9 — cursor (viewport-normalized 0..1) becomes look direction: right edge = look right. */\n pointTo(tx: number, ty: number): void {\n if (this.mode !== 'pointer') return\n this.target.yaw = (2 * clamp(tx, 0, 1) - 1) * POINTER_YAW_MAX\n this.target.pitch = (1 - 2 * clamp(ty, 0, 1)) * POINTER_PITCH_MAX\n }\n\n /** I10 — device attitude: γ right-tilt = look right, β beyond ~40° = look up/down. */\n tiltTo(gamma: number, beta: number): void {\n this.tilt.yaw = clamp(gamma / 45, -1, 1) * TILT_YAW_MAX\n this.tilt.pitch = clamp((beta - 40) / 45, -1, 1) * -TILT_PITCH_MAX\n }\n\n /** Public look API (head tracking / WebXR later plugs in here). Radians, right/up positive. */\n lookAt(yawRight: number, pitchUp: number): void {\n this.target.yaw = yawRight\n this.target.pitch = pitchUp\n }\n\n get state(): { yaw: number; pitch: number } {\n return { yaw: this.look.yaw, pitch: this.look.pitch }\n }\n\n dispose(): void {\n this.running = false\n cancelAnimationFrame(this.raf)\n }\n}\n","/**\n * L0/L2 bridge — the ListenerRig: where the ears are (ARCHITECTURE.md §2).\n * Pointer/center modes + device-tilt offset, lerped each frame to avoid zipper artifacts.\n */\nimport * as Tone from 'tone'\nimport { ROOM_HALF_H, ROOM_HALF_W } from '../math/mapping'\nimport { clamp, lerp } from '../math/util'\n\nexport class ListenerRig {\n private target = { x: 0, y: 0 }\n private tilt = { x: 0, y: 0 }\n private pos = { x: 0, y: 0 }\n private raf = 0\n private running = false\n\n constructor(private mode: 'pointer' | 'center') {}\n\n start(): void {\n if (this.running) return\n this.running = true\n const listener = Tone.getListener()\n // Listener faces -z (WebAudio default); voices live at negative z (MAPPING.md S1).\n listener.forwardX.value = 0\n listener.forwardY.value = 0\n listener.forwardZ.value = -1\n listener.upY.value = 1\n const step = () => {\n if (!this.running) return\n const gx = clamp(this.target.x + this.tilt.x, -ROOM_HALF_W, ROOM_HALF_W)\n const gy = clamp(this.target.y + this.tilt.y, -ROOM_HALF_H, ROOM_HALF_H)\n this.pos.x = lerp(this.pos.x, gx, 0.12)\n this.pos.y = lerp(this.pos.y, gy, 0.12)\n try {\n listener.positionX.value = this.pos.x\n listener.positionY.value = this.pos.y\n listener.positionZ.value = 0\n } catch { /* context may be closing */ }\n this.raf = requestAnimationFrame(step)\n }\n this.raf = requestAnimationFrame(step)\n }\n\n /** I9 — pointer position (viewport-normalized 0..1) targets the ears. */\n pointTo(tx: number, ty: number): void {\n if (this.mode !== 'pointer') return\n // ×0.8: ears track the cursor but stay slightly behind it, keeping the field stable.\n this.target.x = (2 * clamp(tx, 0, 1) - 1) * ROOM_HALF_W * 0.8\n this.target.y = (1 - 2 * clamp(ty, 0, 1)) * ROOM_HALF_H * 0.8\n }\n\n /** I10 — device tilt offsets the ears (γ → x ±4 m, β → y ±2 m). */\n tiltTo(gamma: number, beta: number): void {\n this.tilt.x = clamp(gamma / 45, -1, 1) * 4\n this.tilt.y = clamp((beta - 40) / 45, -1, 1) * -2\n }\n\n dispose(): void {\n this.running = false\n cancelAnimationFrame(this.raf)\n }\n}\n","/**\n * Every formula in MAPPING.md §1–2, one named pure function each.\n * This file is the executable form of the Mapping Canon: no DOM, no Tone, no side effects.\n * Change a formula here ⇄ change MAPPING.md in the same commit (PLAN.md Invariant #3).\n */\nimport { clamp, lerp, norm } from './util'\nimport type { Rect, Wave } from '../types'\n\nexport const ROOM_HALF_W = 8 // meters — G1\nexport const ROOM_HALF_H = 4 // meters — G2\n\n/** G1 — element center x → azimuth (positionX, meters). */\nexport function panX(rect: Rect, vw: number): number {\n return (2 * norm(rect.x + rect.w / 2, 0, vw) - 1) * ROOM_HALF_W\n}\n\n/** G2 — element center y → elevation (positionY, meters; screen-top = up). */\nexport function panY(rect: Rect, vh: number): number {\n return (1 - 2 * norm(rect.y + rect.h / 2, 0, vh)) * ROOM_HALF_H\n}\n\n/** G3 — vertical position → brightness tilt multiplier on the filter cutoff. */\nexport function brightnessTilt(rect: Rect, vh: number): number {\n return lerp(1.45, 0.7, norm(rect.y + rect.h / 2, 0, vh))\n}\n\n/** G4 — log-normalized size 0 (tiny) … 1 (viewport-filling). */\nexport function sizeT(rect: Rect, vw: number, vh: number): number {\n const a = Math.max(1, rect.w * rect.h)\n const A = Math.max(1, vw * vh)\n return norm(Math.log(1 + (100 * a) / A), 0, Math.log(101))\n}\n\n/**\n * G4 — pitch degree, inverted: big elements speak low (T2). Compressed into [0.1, 0.85] so\n * sibling/heading step offsets have melodic headroom instead of clamping at the edges.\n */\nexport const degreeFromSize = (t: number): number => 0.1 + 0.75 * (1 - t)\n\n/** G5 — big elements speak louder (T2). */\nexport const velocityFromSize = (t: number): number => lerp(0.85, 1.25, t)\n\n/** G6 — roundness r ∈ [0,1]: 0 = razor corner (kiki), 1 = pill/circle (bouba). */\nexport function roundness(radiusPx: number, rect: Rect): number {\n const half = Math.min(rect.w, rect.h) / 2\n return half <= 0 ? 0 : clamp(radiusPx / half, 0, 1)\n}\n\n/** G7 — the Kiki/Bouba waveform ladder. */\nexport function waveFromRoundness(r: number): Wave {\n if (r < 0.15) return 'square'\n if (r < 0.45) return 'sawtooth'\n if (r < 0.8) return 'triangle'\n return 'sine'\n}\n\n/** G8 — sharp = plosive onset, round = soft bloom. Seconds. */\nexport const attackFromRoundness = (r: number): number => lerp(0.002, 0.045, r)\n\n/** G9 — sharp edges ring with resonance. */\nexport const qFromRoundness = (r: number): number => lerp(2.4, 0.5, r)\n\n/** G10 — sharper ↔ slightly higher (T1), in whole scale steps. */\nexport const pitchNudgeFromRoundness = (r: number): number => (1 - r) * 1\n\n/** G11 — elongation → duration: long elements sweep, squares tick. Seconds. */\nexport function durationFromElongation(rect: Rect): number {\n const e = Math.max(rect.w, rect.h) / Math.max(1, Math.min(rect.w, rect.h))\n return clamp(0.18 * Math.sqrt(e), 0.12, 1.6)\n}\n\n/** G13 — box-shadow blur lifts the element into the room's reverb. */\nexport const sendFromShadowBlur = (blurPx: number): number => clamp(blurPx / 40, 0, 0.5)\n\n/** S1 — DOM depth → distance behind the sound stage (listener at z=0 facing −z). */\nexport const zFromDepth = (depth: number): number => -(1 + 0.7 * Math.min(depth, 10))\n\n/** S2 — deeper nesting = duller voice. Hz. */\nexport const cutoffFromDepth = (depth: number): number => Math.max(700, 9000 * Math.pow(0.82, depth))\n\n/** S3 — deeper nesting = quieter (distance loudness, Zahorik 2002). */\nexport const velocityFromDepth = (depth: number): number => Math.max(0.55, Math.pow(0.97, depth))\n\n/** S5 — positive z-index pulls the element toward the listener. Meters toward z=0. */\nexport const zBonusFromZIndex = (z: number): number => clamp(z / 50, 0, 1) * 0.8\n\n/** S4 — siblings climb the scale, wrapping each octave (do-re-mi…-do) so long lists stay melodic. */\nexport const stepsFromSiblingIndex = (i: number, scaleLen = 7): number => i % Math.max(1, scaleLen)\n\n/** S6 — headings: h1 lands lowest/grandest. Whole scale steps (negative = down). */\nexport const stepsFromHeadingLevel = (level: number): number => -(7 - clamp(level, 1, 6)) * 2\n\n/** S7/S8 — the viewport is the room. */\nexport function reverbFromViewport(vw: number): { decay: number; wet: number } {\n const t = norm(vw, 360, 2200)\n return { decay: lerp(0.6, 4.5, t), wet: lerp(0.08, 0.32, t) }\n}\n\n/** I13 — room tone color follows room size. Hz. */\nexport const ambienceCutoffFromViewport = (vw: number): number => lerp(400, 1400, norm(vw, 360, 2200))\n","/**\n * L0 Acoustic Substrate — the Room: master chain (spatial input → warmth/brilliance shelves →\n * volume → limiter), viewport-sized reverb (S7/S8), ambience (I13), visibility fading (I14),\n * mute. In 'panner' mode it also owns the classic dry/wet routing; in 'ambisonic' mode the\n * AmbisonicBackend consumes `reverb` and `spatialIn` directly (SPATIAL.md §6). Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport { ambienceCutoffFromViewport, reverbFromViewport } from '../math/mapping'\nimport { clamp } from '../math/util'\nimport { brillianceDb, warmthDb, type PerceptualFactors } from '../spatial/perceptual'\nimport type { VoiceBuses } from './voices'\n\nexport interface RoomOptions {\n volumeDb: number\n reverb: 'auto' | number\n ambient: number\n mode: 'panner' | 'ambisonic'\n}\n\nexport class Room {\n /** Classic v0.1 buses — meaningful in 'panner' mode (dryIn = spatialIn, wetIn = reverb). */\n readonly buses: VoiceBuses\n /** Everything audible enters here (gets the perceptual EQ + limiter). */\n readonly spatialIn: Tone.Gain\n readonly reverb: Tone.Reverb\n\n private master: Tone.Volume\n private limiter: Tone.Limiter\n private lowShelf: Tone.Filter\n private highShelf: Tone.Filter\n private wetGain: Tone.Gain | null = null\n private noise: Tone.Noise | null = null\n private noiseFilter: Tone.Filter | null = null\n private noiseGain: Tone.Gain | null = null\n private rushGain: Tone.Gain | null = null\n private resizeTimer: ReturnType<typeof setTimeout> | null = null\n private mutedNow = false\n private toneScale = 1\n\n constructor(private opts: RoomOptions, vw: number, factors: PerceptualFactors) {\n this.limiter = new Tone.Limiter(-1).toDestination()\n this.master = new Tone.Volume(opts.volumeDb).connect(this.limiter)\n this.highShelf = new Tone.Filter({ type: 'highshelf', frequency: 4000, gain: brillianceDb(factors.brilliance) }).connect(this.master)\n this.lowShelf = new Tone.Filter({ type: 'lowshelf', frequency: 250, gain: warmthDb(factors.warmth) }).connect(this.highShelf)\n this.spatialIn = new Tone.Gain(1).connect(this.lowShelf)\n\n const { decay, wet } = this.roomParams(vw)\n this.reverb = new Tone.Reverb({ decay, preDelay: 0.02, wet: 1 })\n if (opts.mode === 'panner') {\n this.wetGain = new Tone.Gain(wet).connect(this.spatialIn)\n this.reverb.connect(this.wetGain)\n }\n this.buses = { dryIn: this.spatialIn, wetIn: this.reverb }\n }\n\n setFactors(f: PerceptualFactors): void {\n this.lowShelf.gain.rampTo(warmthDb(f.warmth), 0.1)\n this.highShelf.gain.rampTo(brillianceDb(f.brilliance), 0.1)\n }\n\n private roomParams(vw: number): { decay: number; wet: number } {\n if (this.opts.reverb !== 'auto') {\n const decay = clamp(Number(this.opts.reverb) || 1.5, 0.1, 12)\n return { decay, wet: 0.25 }\n }\n return reverbFromViewport(vw)\n }\n\n /** Debounced: Tone.Reverb regenerates its impulse response when decay changes. */\n resize(vw: number): void {\n if (this.resizeTimer) clearTimeout(this.resizeTimer)\n this.resizeTimer = setTimeout(() => {\n const { decay, wet } = this.roomParams(vw)\n try {\n this.reverb.decay = decay\n this.wetGain?.gain.rampTo(wet, 0.3)\n this.noiseFilter?.frequency.rampTo(ambienceCutoffFromViewport(vw) * this.toneScale, 0.5)\n } catch (err) {\n console.warn('[sonarium] room resize failed', err)\n }\n }, 400)\n }\n\n /** I13 — room tone (sparkles became the phrase engine, PULSE.md §3). toneScale = CH7 warmth. */\n startAmbience(vw: number, level: number, toneScale = 1): void {\n if (level <= 0) return\n this.toneScale = toneScale\n this.noise = new Tone.Noise('brown')\n this.noiseFilter = new Tone.Filter({ frequency: ambienceCutoffFromViewport(vw) * toneScale, type: 'lowpass' })\n this.noiseGain = new Tone.Gain(Tone.dbToGain(-46) * clamp(level / 0.12, 0, 3))\n this.noise.connect(this.noiseFilter)\n this.noiseFilter.connect(this.noiseGain)\n this.noiseGain.connect(this.spatialIn)\n // Air-rush path (MATTER.md §2.2): scroll velocity swells the same room-tone noise.\n this.rushGain = new Tone.Gain(0)\n this.noiseFilter.connect(this.rushGain)\n this.rushGain.connect(this.spatialIn)\n this.noise.start()\n }\n\n /** MATTER.md §2.2 — moving through the page moves air. Swells fast, decays in ~450 ms. */\n rush(level: number): void {\n if (!this.rushGain || this.mutedNow) return\n const now = Tone.now()\n this.rushGain.gain.cancelScheduledValues(now)\n this.rushGain.gain.rampTo(level, 0.05, now)\n this.rushGain.gain.rampTo(0, 0.45, now + 0.07)\n }\n\n /** I14 — never sound in a background tab. */\n setHidden(hidden: boolean): void {\n if (this.mutedNow) return\n this.master.volume.rampTo(hidden ? -Infinity : this.opts.volumeDb, 0.3)\n }\n\n setMuted(muted: boolean): void {\n this.mutedNow = muted\n this.master.volume.rampTo(muted ? -Infinity : this.opts.volumeDb, 0.15)\n }\n\n dispose(): void {\n if (this.resizeTimer) clearTimeout(this.resizeTimer)\n this.noise?.dispose()\n this.noiseFilter?.dispose()\n this.noiseGain?.dispose()\n this.rushGain?.dispose()\n this.reverb.dispose()\n this.wetGain?.dispose()\n this.spatialIn.dispose()\n this.lowShelf.dispose()\n this.highShelf.dispose()\n this.master.dispose()\n this.limiter.dispose()\n }\n}\n","/**\n * The Matter weave — MATTER.md made executable. Four macro-dimensions condensed from visual\n * properties, each woven into bundles of co-varying synthesis parameters so the ear hears one\n * coherent object (Bregman fusion; Grey/McAdams timbre axes). Pure: no DOM, no Tone.\n * Change a formula here ⇄ change MATTER.md §2 in the same commit (Invariant #3).\n */\nimport { clamp, lerp } from './util'\n\nexport interface Matter {\n /** boundary abruptness, kiki↔bouba: 1 − roundness */\n edge: number\n /** size/weight: log-area sizeT */\n mass: number\n /** surface noisiness/airiness: shadows, translucency, dashed borders, media */\n texture: number\n /** distance into the room: normalized DOM depth */\n air: number\n}\n\nexport interface MatterVisuals {\n roundness: number\n sizeT: number\n depth: number\n shadowBlurPx: number\n opacity: number\n dashedBorder: boolean\n isMedia: boolean\n backdropBlurPx: number\n /** MODULAR.md M7 — typography enters the weave (bold text carries weight). Default 0. */\n massBonus?: number\n}\n\nexport function deriveMatter(v: MatterVisuals): Matter {\n const texture = clamp(\n clamp(v.shadowBlurPx / 40, 0, 0.4) +\n (1 - clamp(v.opacity, 0, 1)) * 0.6 +\n (v.dashedBorder ? 0.15 : 0) +\n (v.isMedia ? 0.35 : 0) +\n clamp(v.backdropBlurPx / 40, 0, 0.2),\n 0,\n 1,\n )\n return {\n edge: clamp(1 - v.roundness, 0, 1),\n mass: clamp(v.sizeT + (v.massBonus ?? 0), 0, 1),\n texture,\n air: clamp(Math.min(v.depth, 10) / 10, 0, 1),\n }\n}\n\n// ------------------------------------------------------------------ spectrum (MATTER.md §2.1)\n\nexport const PARTIAL_COUNT = 24\n\n/**\n * Continuous spectrum: EDGE sets the rolloff (bright↔pure), elongation sets hollowness\n * (long thin elements = pipes = odd harmonics), richness (CHROMA.md CH5: saturation)\n * subtracts from the rolloff exponent — vivid color = vivid spectrum. Normalized to Σa² = 1\n * so the whole continuum sits at equal loudness.\n */\nexport function genPartials(edge: number, elongation: number, richness = 0): Float32Array {\n const p = Math.max(0.8, 1 + 2.6 * (1 - clamp(edge, 0, 1)) - clamp(richness, 0, 0.5))\n const evenness = lerp(1, 0.12, clamp((elongation - 1) / 4, 0, 1))\n const a = new Float32Array(PARTIAL_COUNT)\n let energy = 0\n for (let k = 1; k <= PARTIAL_COUNT; k++) {\n const amp = (k % 2 === 1 ? 1 : evenness) / Math.pow(k, p)\n a[k - 1] = amp\n energy += amp * amp\n }\n const norm = 1 / Math.sqrt(energy || 1)\n for (let i = 0; i < PARTIAL_COUNT; i++) a[i] = (a[i] as number) * norm\n return a\n}\n\n// ------------------------------------------------------------------ noise weaves\n\nexport interface TransientSpec {\n /** noise burst length, seconds */\n lengthS: number\n /** high-pass corner of the burst, Hz */\n hpHz: number\n /** burst level relative to the voice (×velocity) */\n level: number\n}\n\n/** EDGE → the /k/ of kiki: a filtered click at onset. edge 0 → none. */\nexport function transient(edge: number): TransientSpec {\n const e = clamp(edge, 0, 1)\n return {\n lengthS: lerp(0.005, 0.025, e),\n hpHz: 2000 + 4000 * e,\n level: 0.7 * e,\n }\n}\n\nexport interface BreathSpec {\n /** sustained airy layer level (0 = pure tone) */\n level: number\n /** band-pass center as a ratio of the fundamental */\n bpRatio: number\n}\n\n/** TEXTURE → breath: translucent/soft-shadowed things are airy. */\nexport function breath(texture: number): BreathSpec {\n const t = clamp(texture, 0, 1)\n return { level: 0.22 * t, bpRatio: lerp(2.5, 1.2, t) }\n}\n\n/** TEXTURE → detune jitter in cents (rough surfaces are pitch-unstable). */\nexport const detuneJitterCents = (texture: number): number => 6 * clamp(texture, 0, 1)\n\n// ------------------------------------------------------------------ pitch behaviour\n\nexport interface SubShimmerSpec {\n /** semitone offset of osc B: −12 chest sub for massive, +12 sparkle for tiny */\n interval: number\n level: number\n}\n\n/** MASS → the second oscillator: big = chest, tiny = sparkle. */\nexport function subShimmer(mass: number): SubShimmerSpec {\n const m = clamp(mass, 0, 1)\n return {\n interval: m >= 0.45 ? -12 : 12,\n level: lerp(0.1, 0.38, clamp(Math.abs(m - 0.45) * 2, 0, 1)),\n }\n}\n\n/** ROUND → glide: the bouba swoop-in. Returns portamento seconds (0 for sharp). */\nexport const glideS = (edge: number): number => lerp(0.028, 0, clamp(edge, 0, 1))\n\n// ------------------------------------------------------------------ envelope weave\n\nexport interface EnvelopeSpec {\n attackS: number\n decayS: number\n sustain: number\n releaseScale: number\n}\n\n/** EDGE strikes, MASS adds inertia. */\nexport function envelopeWeave(edge: number, mass: number): EnvelopeSpec {\n const e = clamp(edge, 0, 1)\n const m = clamp(mass, 0, 1)\n return {\n attackS: lerp(0.045, 0.002, e) + 0.008 * m,\n decayS: lerp(0.4, 0.12, e),\n sustain: lerp(0.35, 0.15, e),\n releaseScale: lerp(0.8, 1.5, m),\n }\n}\n\n// ------------------------------------------------------------------ filter weave\n\nexport interface FilterWeaveSpec {\n q: number\n /** transient brightness bite: cutoff multiplier at onset, decaying to 1 */\n biteAmount: number\n biteDecayS: number\n}\n\n/** EDGE rings and bites. (Base cutoff itself comes from AIR via S2 + tilt, as before.) */\nexport function filterWeave(edge: number): FilterWeaveSpec {\n const e = clamp(edge, 0, 1)\n return {\n q: lerp(0.5, 2.4, e),\n biteAmount: 1 + 3 * e,\n biteDecayS: lerp(0.15, 0.06, e),\n }\n}\n\n// ------------------------------------------------------------------ reverb weave\n\nexport interface ReverbWeaveSpec {\n /** multiplier on the profile's base send */\n sendScale: number\n /** low-pass on the way into the reverb: dark sources bloom dark. Hz */\n sendCutoffHz: number\n /** 0 = arrive at full send immediately (sharp); 1 = swell from 35% over the note (round) */\n bloom: number\n /** spatial extent bonus from airy texture */\n extentBonus: number\n}\n\nexport function reverbWeave(edge: number, mass: number, texture: number): ReverbWeaveSpec {\n const e = clamp(edge, 0, 1)\n const m = clamp(mass, 0, 1)\n const t = clamp(texture, 0, 1)\n return {\n sendScale: lerp(1.3, 0.7, e) * lerp(0.85, 1.15, m),\n sendCutoffHz: lerp(1200, 7000, e),\n bloom: 1 - e,\n extentBonus: 0.15 * t,\n }\n}\n\n// ------------------------------------------------------------------ interaction weave\n\n/** I8 — scroll velocity (px/ms) → air-rush gain on the room tone, decaying over ~400 ms. */\nexport const airRushGain = (pxPerMs: number): number => clamp(pxPerMs * 0.06, 0, 0.18)\n","/**\n * L1 Page Reading — element → SonicProfile. Imports math + DOM, never Tone\n * (ARCHITECTURE.md §1 dependency rules).\n */\nimport {\n attackFromRoundness, brightnessTilt, cutoffFromDepth, degreeFromSize, durationFromElongation,\n panX, panY, pitchNudgeFromRoundness, qFromRoundness, roundness, sendFromShadowBlur, sizeT,\n stepsFromHeadingLevel, stepsFromSiblingIndex, velocityFromDepth, velocityFromSize,\n waveFromRoundness, zBonusFromZIndex, zFromDepth,\n} from '../math/mapping'\nimport { clamp } from '../math/util'\nimport { degreeToMidi, midiToFreq, midiToNoteName, type SiteKey } from '../math/scales'\nimport {\n breath, deriveMatter, detuneJitterCents, envelopeWeave, filterWeave, genPartials, glideS,\n reverbWeave, subShimmer, transient,\n} from '../math/matter'\nimport {\n attackScaleFromWarmth, brightnessFromLuminance, chromaOf, parseCssColor,\n richnessFromSaturation, subBonusFromWarmth, velocityFromLuminance, type Chroma,\n} from '../math/chroma'\nimport { massBonusFromFontWeight, patchFrom, type ModularVisuals } from '../math/modular'\nimport { directivityFromRoundness, extentFromSize, sphereFromRect } from '../spatial/sphere'\nimport { directivityFilterScale } from '../spatial/perceptual'\nimport { DEG } from '../spatial/sh'\nimport type { MatterVoiceParams, Rect, Role, SonicProfile, SphereProps, Theme, VoiceRecipe, Wave } from '../types'\n\nconst HEADING = /^H[1-6]$/\n\nexport function roleOf(el: Element): Role {\n const aria = (el.getAttribute('role') || '').toLowerCase()\n const override = (el as HTMLElement).dataset?.sonicRole as Role | undefined\n if (override) return override\n const tag = el.tagName\n const type = (el.getAttribute('type') || '').toLowerCase()\n if (tag === 'INPUT' && (type === 'checkbox' || type === 'radio')) return 'toggle'\n if (aria === 'switch' || aria === 'checkbox' || tag === 'SUMMARY') return 'toggle'\n if (tag === 'BUTTON' || aria === 'button' || (tag === 'INPUT' && (type === 'button' || type === 'submit' || type === 'reset'))) return 'button'\n if ((tag === 'A' && el.hasAttribute('href')) || aria === 'link') return 'link'\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || (el as HTMLElement).isContentEditable) return 'input'\n if (HEADING.test(tag) || aria === 'heading') return 'heading'\n if (tag === 'IMG' || tag === 'VIDEO' || tag === 'SVG' || tag === 'CANVAS' || tag === 'PICTURE' || tag === 'AUDIO') return 'media'\n if (tag === 'LI' || tag === 'TR' || ['listitem', 'option', 'menuitem', 'tab'].includes(aria)) return 'item'\n if (['NAV', 'SECTION', 'ARTICLE', 'ASIDE', 'FORM', 'FIELDSET', 'HEADER', 'FOOTER', 'MAIN', 'DIALOG'].includes(tag)) return 'container'\n if (['navigation', 'region', 'group', 'list', 'menu', 'tablist', 'dialog'].includes(aria)) return 'container'\n if (tag === 'P' || tag === 'BLOCKQUOTE' || tag === 'LABEL' || tag === 'SPAN') return 'text'\n return 'container'\n}\n\nexport function domDepth(el: Element, root: Element): number {\n let d = 0\n let n: Element | null = el\n while (n && n !== root && d < 32) {\n n = n.parentElement\n d++\n }\n return d\n}\n\nfunction eligibleSiblingIndex(el: Element): number {\n const parent = el.parentElement\n if (!parent) return 0\n let i = 0\n for (const sib of Array.from(parent.children)) {\n if (sib === el) return i\n if (sib.tagName === el.tagName || roleOf(sib) === roleOf(el)) i++\n }\n return 0\n}\n\nfunction recipeFor(role: Role, theme: Theme): VoiceRecipe {\n return { ...theme.defaults, ...(theme.roles[role] ?? {}) }\n}\n\nfunction isQuiet(el: Element): boolean {\n let n: Element | null = el\n while (n) {\n if ((n as HTMLElement).dataset?.sonic === 'quiet') return true\n n = n.parentElement\n }\n return false\n}\n\nconst NOTE_RE = /^([A-Ga-g][#b]?)(-?\\d)$/\nfunction pinnedMidi(spec: string | undefined): number | null {\n if (!spec) return null\n const m = spec.trim().match(NOTE_RE)\n if (!m) return null\n const pcs: Record<string, number> = { C: 0, 'C#': 1, Db: 1, D: 2, 'D#': 3, Eb: 3, E: 4, F: 5, 'F#': 6, Gb: 6, G: 7, 'G#': 8, Ab: 8, A: 9, 'A#': 10, Bb: 10, B: 11 }\n const name = (m[1] as string).charAt(0).toUpperCase() + (m[1] as string).slice(1)\n const pc = pcs[name]\n if (pc === undefined) return null\n return (parseInt(m[2] as string, 10) + 1) * 12 + pc\n}\n\nexport interface ProfileEnv {\n root: Element\n key: SiteKey\n theme: Theme\n vw: number\n vh: number\n}\n\n/** CSS custom property, trimmed; '' when unset. Inherits down the tree (the aural stylesheet). */\nfunction sonicVar(cs: CSSStyleDeclaration, name: string): string {\n return cs.getPropertyValue(name).trim()\n}\n\n/** Compute the full acoustic identity of an element. Pure given (el state, env). */\nexport function profileOf(el: Element, env: ProfileEnv): SonicProfile {\n const { key, theme, vw, vh } = env\n const html = el as HTMLElement\n const reasons: Record<string, string> = {}\n\n const cs = getComputedStyle(el)\n const r = el.getBoundingClientRect()\n const rect: Rect = { x: r.x, y: r.y, w: Math.max(1, r.width), h: Math.max(1, r.height) }\n // Priority: data-sonic-role > --sonic-role > inference (CHROMA.md §4).\n const role = (html.dataset?.sonicRole as Role | undefined)\n || (sonicVar(cs, '--sonic-role') as Role | '')\n || roleOf(el)\n const recipe = recipeFor(role, theme)\n reasons.role = `<${el.tagName.toLowerCase()}> reads as \"${role}\" → ${recipe.synthKind} voice (theme ${theme.name})`\n // border-radius percentages survive into computed style — resolve against the box.\n const radiusRaw = cs.borderTopLeftRadius\n const radiusPx = radiusRaw.endsWith('%')\n ? ((parseFloat(radiusRaw) || 0) / 100) * Math.min(rect.w, rect.h)\n : parseFloat(radiusRaw) || 0\n const opacity = parseFloat(cs.opacity)\n const shadowBlur = parseShadowBlur(cs.boxShadow)\n const zIndex = cs.position !== 'static' ? parseInt(cs.zIndex, 10) || 0 : 0\n\n // Space (G1, G2, S1, S5)\n const depth = domDepth(el, env.root)\n const pan = {\n x: panX(rect, vw),\n y: panY(rect, vh),\n z: zFromDepth(depth) + zBonusFromZIndex(zIndex),\n }\n reasons.position = `center (${Math.round(rect.x + rect.w / 2)}, ${Math.round(rect.y + rect.h / 2)}) px → (${pan.x.toFixed(1)}, ${pan.y.toFixed(1)}) m; depth ${depth} → ${pan.z.toFixed(1)} m away`\n\n // Pitch (G4, S4, S6, G10) through the quantizer\n const st = sizeT(rect, vw, vh)\n const degree = degreeFromSize(st)\n const round = roundness(radiusPx, rect)\n let steps = stepsFromSiblingIndex(eligibleSiblingIndex(el), key.scale.length) + pitchNudgeFromRoundness(round)\n if (role === 'heading') {\n const level = HEADING.test(el.tagName) ? parseInt(el.tagName[1] as string, 10) : 2\n steps += stepsFromHeadingLevel(level)\n }\n steps += recipe.octaveShift * key.scale.length\n const pinned = pinnedMidi(html.dataset?.sonicNote ?? sonicVar(cs, '--sonic-note') ?? undefined)\n const midi = pinned ?? degreeToMidi(degree, key, steps)\n reasons.pitch = pinned !== null\n ? `pinned by data-sonic-note → ${midiToNoteName(midi)}`\n : `area ${(rect.w * rect.h / 1000).toFixed(1)}k px² (size ${st.toFixed(2)}) + sibling/heading offsets → ${midiToNoteName(midi)} in ${key.label}`\n\n // Timbre (G6–G9) — Kiki/Bouba\n const wave: Wave = (html.dataset?.sonicWave as Wave)\n || (sonicVar(cs, '--sonic-wave') as Wave | '')\n || recipe.pinWave\n || waveFromRoundness(round)\n const attack = attackFromRoundness(round)\n reasons.timbre = `roundness ${round.toFixed(2)} (radius ${radiusPx}px) → ${wave} wave, ${(attack * 1000).toFixed(0)} ms attack`\n\n // Duration (G11)\n const durationS = durationFromElongation(rect)\n reasons.duration = `aspect ${(Math.max(rect.w, rect.h) / Math.min(rect.w, rect.h)).toFixed(1)}:1 → ${durationS.toFixed(2)} s`\n\n // Sphere — the 聲球 (SPATIAL.md SP1–SP5)\n const dir = sphereFromRect(rect, vw, vh)\n const extentOverride = parseFloat(html.dataset?.sonicExtent ?? sonicVar(cs, '--sonic-extent'))\n const sphere: SphereProps = {\n azimuth: dir.azimuth,\n elevation: dir.elevation,\n extent: isNaN(extentOverride) ? extentFromSize(st) : clamp(extentOverride, 0, 1),\n directivity: directivityFromRoundness(round),\n }\n reasons.sphere = `az ${(sphere.azimuth / DEG).toFixed(0)}°, el ${(sphere.elevation / DEG).toFixed(0)}°, extent ${sphere.extent.toFixed(2)} (size wraps the listener), directivity ${sphere.directivity.toFixed(2)} (sharp beams, round radiates)`\n\n // The Chroma weave (CHROMA.md §1) — the element's color as mood, extracted once, used below.\n const chroma = elementChroma(el, cs, role)\n\n // Filter (S2 · G3, G9, CH1) — depth, height, directivity and color luminance share the cutoff\n const filterHz = cutoffFromDepth(depth) * brightnessTilt(rect, vh)\n * directivityFilterScale(sphere.directivity) * brightnessFromLuminance(chroma.luminance)\n reasons.filter = `depth ${depth} + vertical position + directivity + luminance → low-pass ${Math.round(filterHz)} Hz`\n\n // Loudness (G5, G12, S3, CH2, quiet via attribute or --sonic custom property)\n let velocityScale = recipe.baseVelocity * velocityFromSize(st) * velocityFromDepth(depth)\n * (isNaN(opacity) ? 1 : opacity) * velocityFromLuminance(chroma.luminance)\n const sonicMode = sonicVar(cs, '--sonic')\n if (isQuiet(el) || sonicMode === 'quiet') velocityScale *= 0.4\n if (sonicMode === 'off') {\n velocityScale = 0\n reasons.silenced = '--sonic: off (aural stylesheet)'\n }\n velocityScale = clamp(velocityScale, 0, 1.5)\n\n // The Matter weave (MATTER.md §2) — one material, many co-varying cues.\n const elongation = Math.max(rect.w, rect.h) / Math.max(1, Math.min(rect.w, rect.h))\n const textish = role === 'text' || role === 'heading' || role === 'link' || role === 'button'\n const fontWeight = textish ? parseInt(cs.fontWeight, 10) || 400 : 400\n const matter = deriveMatter({\n roundness: round,\n sizeT: st,\n depth,\n shadowBlurPx: shadowBlur,\n opacity: isNaN(opacity) ? 1 : opacity,\n dashedBorder: cs.borderTopStyle === 'dashed' || cs.borderTopStyle === 'dotted',\n isMedia: role === 'media',\n backdropBlurPx: parseBackdropBlur(cs),\n massBonus: massBonusFromFontWeight(fontWeight),\n })\n\n // The modular patch (MODULAR.md §1) — CSS plugs the cables.\n const modVisuals: ModularVisuals = {\n animationS: cs.animationName && cs.animationName !== 'none' ? firstSeconds(cs.animationDuration) : 0,\n borderStyle: (['solid', 'dashed', 'dotted'].includes(cs.borderTopStyle) ? cs.borderTopStyle : 'none') as ModularVisuals['borderStyle'],\n borderWidthPx: parseFloat(cs.borderTopWidth) || 0,\n transitionS: firstSeconds(cs.transitionDuration),\n }\n const patch = patchFrom(matter, modVisuals)\n // Chroma tints the matter (CH3–CH5) — never a second instrument.\n const env0 = envelopeWeave(matter.edge, matter.mass)\n const sub0 = subShimmer(matter.mass)\n const voice: MatterVoiceParams = {\n matter,\n partials: Array.from(genPartials(matter.edge, elongation, richnessFromSaturation(chroma.saturation))),\n transient: transient(matter.edge),\n breath: breath(matter.texture),\n subShimmer: {\n interval: sub0.interval,\n level: sub0.level + (sub0.interval < 0 ? subBonusFromWarmth(chroma.warmth) : 0),\n },\n glideS: glideS(matter.edge),\n jitterCents: detuneJitterCents(matter.texture),\n envelope: { ...env0, attackS: env0.attackS * attackScaleFromWarmth(chroma.warmth) },\n filter: filterWeave(matter.edge),\n reverb: reverbWeave(matter.edge, matter.mass, matter.texture),\n patch,\n }\n if (patch.fold.mix > 0.05 || patch.fm.index > 0.05 || patch.lfo.rateHz > 0.01 || patch.unison.mix > 0) {\n reasons.patch = [\n patch.fold.mix > 0.05 ? `border drives the wavefolder ×${patch.fold.drive.toFixed(2)}` : '',\n patch.fm.index > 0.05 ? `FM ring ${patch.fm.index.toFixed(2)}` : '',\n patch.unison.mix > 0 ? `unison +${patch.unison.detuneCents.toFixed(0)}¢` : '',\n patch.lfo.rateHz > 0.01 ? `${patch.lfo.shape} LFO ${patch.lfo.rateHz.toFixed(2)} Hz (${modVisuals.animationS > 0 ? 'css animation' : 'dashed border'})` : '',\n ].filter(Boolean).join(' · ')\n }\n reasons.chroma = `warmth ${chroma.warmth.toFixed(2)} · sat ${chroma.saturation.toFixed(2)} · lum ${chroma.luminance.toFixed(2)} → ${chroma.warmth > 0.6 ? 'eager onset, full body' : chroma.warmth < 0.4 ? 'cool, unhurried onset' : 'neutral temperament'}${chroma.saturation > 0.5 ? ', vivid spectrum' : ''}`\n reasons.matter = `edge ${matter.edge.toFixed(2)} · mass ${matter.mass.toFixed(2)} · texture ${matter.texture.toFixed(2)} · air ${matter.air.toFixed(2)} → ${voice.transient.level > 0.1 ? 'clicky' : 'soft'}, ${voice.breath.level > 0.05 ? 'breathy' : 'clean'}, ${voice.subShimmer.interval < 0 ? 'chest sub' : 'sparkle +8va'}, ${voice.reverb.bloom > 0.5 ? 'blooms into the room' : 'dry strike'}`\n\n // Room (G13 + MATTER reverb weave + SP3 distance wetness)\n const reverbSend = clamp(\n (0.18 + sendFromShadowBlur(shadowBlur) + 0.05 * Math.min(depth, 10) * 0.5) * voice.reverb.sendScale,\n 0,\n 1.2,\n )\n\n return {\n role, rect, pan, sphere,\n midi, freqHz: midiToFreq(midi), degree,\n wave, attack, release: 0.3 * recipe.releaseScale, durationS,\n filterHz, filterQ: qFromRoundness(round),\n velocityScale, reverbSend,\n synthKind: recipe.synthKind, octaveShift: recipe.octaveShift,\n voice, chroma,\n reasons,\n }\n}\n\n/** CHROMA.md §1 — text-ish roles speak in their text color; boxes speak in their background,\n * walking up past transparent ancestors. */\nfunction elementChroma(el: Element, cs: CSSStyleDeclaration, role: Role): Chroma {\n if (role === 'text' || role === 'heading' || role === 'link') {\n return chromaOf(parseCssColor(cs.color))\n }\n let probe: Element | null = el\n let style: CSSStyleDeclaration | undefined = cs\n for (let hops = 0; probe && hops < 6; hops++) {\n const rgb = parseCssColor((style ?? getComputedStyle(probe)).backgroundColor)\n if (rgb && rgb.a >= 0.05) return chromaOf(rgb)\n probe = probe.parentElement\n style = undefined\n }\n return chromaOf(parseCssColor(getComputedStyle(document.documentElement).backgroundColor))\n}\n\n/** First duration in a comma list (\"2s, 0.5s\" → 2; \"250ms\" → 0.25). */\nfunction firstSeconds(list: string): number {\n const first = (list || '').split(',')[0]?.trim() ?? ''\n if (!first) return 0\n const v = parseFloat(first)\n if (isNaN(v)) return 0\n return first.endsWith('ms') ? v / 1000 : v\n}\n\nfunction parseBackdropBlur(cs: CSSStyleDeclaration): number {\n const bf = cs.backdropFilter || (cs as unknown as Record<string, string>).webkitBackdropFilter || ''\n const m = bf.match(/blur\\((\\d+(\\.\\d+)?)px\\)/)\n return m ? parseFloat(m[1] as string) : 0\n}\n\nfunction parseShadowBlur(boxShadow: string): number {\n if (!boxShadow || boxShadow === 'none') return 0\n // blur is the 3rd length in each shadow; take the max across shadows\n let max = 0\n for (const part of boxShadow.split(/,(?![^(]*\\))/)) {\n const lengths = part.match(/-?\\d+(\\.\\d+)?px/g)\n if (lengths && lengths.length >= 3) max = Math.max(max, parseFloat(lengths[2] as string))\n }\n return max\n}\n","/**\n * L1 Page Reading — eligibility, registry, observers, visible set (ARCHITECTURE.md §5).\n * Imports DOM only; produces data + callbacks, triggers nothing audible itself.\n */\nimport type { SonicProfile } from '../types'\nimport { profileOf, roleOf, type ProfileEnv } from './profile'\n\nexport const ELIGIBLE_SELECTOR = [\n 'button', '[role=button]', 'input', 'textarea', 'select', '[contenteditable]',\n 'a[href]', '[role=link]', 'summary', '[role=switch]', '[role=checkbox]',\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', '[role=heading]',\n 'img', 'video', 'canvas', 'svg', 'picture',\n 'li', 'tr', '[role=listitem]', '[role=option]', '[role=menuitem]', '[role=tab]',\n 'nav', 'section', 'article', 'aside', 'form', 'fieldset', 'dialog',\n '[data-sonic-role]', '[data-sonic-note]',\n].join(',')\n\nconst MAX_TRACKED = 400\n\ninterface Entry {\n profile: SonicProfile | null\n visible: boolean\n}\n\nexport interface ScannerCallbacks {\n /** Fired when an element scrolls/loads into view after the initial scan (I7 whisper). */\n onAppear: (el: Element) => void\n}\n\nexport class Scanner {\n readonly registry = new Map<Element, Entry>()\n private io: IntersectionObserver | null = null\n private mo: MutationObserver | null = null\n private capWarned = false\n private initialScanDone = false\n private mutationTimer: ReturnType<typeof setTimeout> | null = null\n\n constructor(\n private env: ProfileEnv,\n private cb: ScannerCallbacks,\n ) {}\n\n scan(): void {\n if (typeof IntersectionObserver !== 'undefined') {\n this.io = new IntersectionObserver((entries) => {\n for (const e of entries) {\n const entry = this.registry.get(e.target)\n if (!entry) continue\n const was = entry.visible\n entry.visible = e.isIntersecting\n if (e.isIntersecting) entry.profile = null // rect changed while away; recompute lazily\n if (e.isIntersecting && !was && this.initialScanDone) this.cb.onAppear(e.target)\n }\n }, { threshold: 0.15 })\n }\n\n this.register(this.env.root)\n for (const el of Array.from(this.env.root.querySelectorAll(ELIGIBLE_SELECTOR))) this.register(el)\n\n if (typeof MutationObserver !== 'undefined') {\n this.mo = new MutationObserver((muts) => this.queueMutations(muts))\n this.mo.observe(this.env.root, { subtree: true, childList: true, attributes: true, attributeFilter: ['class', 'style', 'data-sonic', 'data-sonic-note', 'data-sonic-wave', 'data-sonic-role'] })\n }\n\n // Let the initial IntersectionObserver flood settle before treating entries as \"appearances\".\n setTimeout(() => { this.initialScanDone = true }, 300)\n }\n\n private register(el: Element): void {\n if (this.registry.has(el) || this.isOff(el)) return\n if (this.registry.size >= MAX_TRACKED) {\n if (!this.capWarned) {\n this.capWarned = true\n console.warn(`[sonarium] page exceeds ${MAX_TRACKED} tracked elements; extra elements stay silent`)\n }\n return\n }\n this.registry.set(el, { profile: null, visible: false })\n this.io?.observe(el)\n }\n\n private unregister(el: Element): void {\n if (!this.registry.has(el)) return\n this.registry.delete(el)\n this.io?.unobserve(el)\n }\n\n isOff(el: Element): boolean {\n let n: Element | null = el\n while (n) {\n if ((n as HTMLElement).dataset?.sonic === 'off') return true\n n = n.parentElement\n }\n return false\n }\n\n private queueMutations(muts: MutationRecord[]): void {\n if (this.mutationTimer) clearTimeout(this.mutationTimer)\n const records = muts\n this.mutationTimer = setTimeout(() => {\n for (const m of records) {\n if (m.type === 'attributes' && m.target instanceof Element) {\n const entry = this.registry.get(m.target)\n if (entry) entry.profile = null\n continue\n }\n for (const node of Array.from(m.addedNodes)) {\n if (!(node instanceof Element)) continue\n if (node.matches?.(ELIGIBLE_SELECTOR)) this.register(node)\n for (const el of Array.from(node.querySelectorAll?.(ELIGIBLE_SELECTOR) ?? [])) this.register(el)\n }\n for (const node of Array.from(m.removedNodes)) {\n if (!(node instanceof Element)) continue\n this.unregister(node)\n for (const el of Array.from(node.querySelectorAll?.(ELIGIBLE_SELECTOR) ?? [])) this.unregister(el)\n }\n }\n }, 150)\n }\n\n /** Profile with lazy compute + cache (cheap path: geometry invalidation only nulls it). */\n profileFor(el: Element): SonicProfile | null {\n if (this.isOff(el)) return null\n let entry = this.registry.get(el)\n if (!entry) {\n // Untracked but asked for (e.g. describe() on an arbitrary element): compute one-off.\n return safeProfile(el, this.env)\n }\n if (!entry.profile) entry.profile = safeProfile(el, this.env)\n return entry.profile\n }\n\n /** Geometry changed globally (scroll/resize): rects are stale, voices params survive. */\n invalidateRects(): void {\n for (const entry of this.registry.values()) entry.profile = null\n }\n\n visibleElements(): Element[] {\n const out: Element[] = []\n for (const [el, entry] of this.registry) if (entry.visible) out.push(el)\n return out\n }\n\n /** The element (or nearest registered ancestor) the scanner knows about. */\n resolve(target: Element | null): Element | null {\n let n: Element | null = target\n while (n) {\n if (this.registry.has(n)) return n\n n = n.parentElement\n }\n return null\n }\n\n updateEnv(vw: number, vh: number): void {\n this.env.vw = vw\n this.env.vh = vh\n }\n\n dispose(): void {\n if (this.mutationTimer) clearTimeout(this.mutationTimer)\n this.io?.disconnect()\n this.mo?.disconnect()\n this.registry.clear()\n }\n}\n\nfunction safeProfile(el: Element, env: ProfileEnv): SonicProfile | null {\n try {\n return profileOf(el, env)\n } catch (err) {\n console.warn('[sonarium] profile failed', err)\n return null\n }\n}\n\nexport { roleOf }\n","/**\n * L0 Acoustic Substrate — VoicePool (ARCHITECTURE.md §4).\n * Profiles are data; voices are rented lanes configured at trigger time. Spatial placement is\n * delegated to the active SpatialBackend (ambisonic field or per-voice panners — SPATIAL.md §6).\n * Imports Tone only; never reads the DOM.\n */\nimport * as Tone from 'tone'\nimport { clamp } from '../math/util'\nimport type { SonicProfile, SynthKind } from '../types'\nimport type { LaneOutput, SpatialBackend } from '../spatial/backend'\nimport { MatterVoice } from './matter-voice'\n\ntype AnySynth = Tone.Synth | Tone.FMSynth | Tone.PluckSynth | Tone.MembraneSynth | Tone.NoiseSynth | MatterVoice\n\ninterface Lane {\n kind: SynthKind\n synth: AnySynth\n filter: Tone.Filter\n out: LaneOutput\n busyUntil: number\n}\n\nexport interface VoiceBuses {\n dryIn: Tone.InputNode\n wetIn: Tone.InputNode\n}\n\nexport class VoicePool {\n private lanes: Lane[] = []\n private sleepTimer: ReturnType<typeof setInterval>\n\n constructor(\n private backend: SpatialBackend,\n private maxVoices: number,\n ) {\n this.maxVoices = clamp(maxVoices, 4, 24)\n // MODULAR.md §4 — idle matter lanes power down (silent page ⇒ ~zero steady-state CPU).\n this.sleepTimer = setInterval(() => {\n const now = Tone.now()\n for (const lane of this.lanes) {\n if (lane.synth instanceof MatterVoice && lane.busyUntil < now - 30) lane.synth.sleep()\n }\n }, 10000)\n }\n\n private createSynth(kind: SynthKind): AnySynth {\n switch (kind) {\n case 'matter':\n return new MatterVoice()\n case 'fm':\n return new Tone.FMSynth({ harmonicity: 3, modulationIndex: 8, envelope: { attack: 0.01, decay: 0.3, sustain: 0.1, release: 1.4 }, modulationEnvelope: { attack: 0.01, decay: 0.4, sustain: 0.2, release: 1 } })\n case 'pluck':\n return new Tone.PluckSynth({ attackNoise: 1, dampening: 3000, resonance: 0.92 })\n case 'membrane':\n return new Tone.MembraneSynth({ pitchDecay: 0.04, octaves: 5, envelope: { attack: 0.001, decay: 0.35, sustain: 0.01, release: 0.6 } })\n case 'noise':\n return new Tone.NoiseSynth({ noise: { type: 'white' }, envelope: { attack: 0.001, decay: 0.06, sustain: 0, release: 0.05 } })\n default:\n return new Tone.Synth({ oscillator: { type: 'triangle' }, envelope: { attack: 0.01, decay: 0.1, sustain: 0.25, release: 0.3 } })\n }\n }\n\n private createLane(kind: SynthKind): Lane {\n const synth = this.createSynth(kind)\n const filter = new Tone.Filter({ frequency: 4000, type: 'lowpass', rolloff: -12, Q: 1 })\n const out = this.backend.createOutput()\n synth.connect(filter)\n filter.connect(out.input)\n // The LFO's filter-wobble tap (MODULAR.md M4/M5) modulates the lane filter additively.\n if (synth instanceof MatterVoice) synth.modFilterOut.connect(filter.frequency)\n const lane: Lane = { kind, synth, filter, out, busyUntil: 0 }\n this.lanes.push(lane)\n return lane\n }\n\n private acquire(kind: SynthKind): Lane {\n const now = Tone.now()\n let candidate: Lane | null = null\n let oldestSameKind: Lane | null = null\n let oldestAny: Lane | null = null\n for (const lane of this.lanes) {\n if (lane.kind === kind) {\n if (lane.busyUntil <= now) { candidate = lane; break }\n if (!oldestSameKind || lane.busyUntil < oldestSameKind.busyUntil) oldestSameKind = lane\n }\n if (!oldestAny || lane.busyUntil < oldestAny.busyUntil) oldestAny = lane\n }\n if (candidate) return candidate\n if (this.lanes.length < this.maxVoices) return this.createLane(kind)\n if (oldestSameKind) return oldestSameKind\n // Cap reached and no lane of this kind: recycle the globally oldest lane into this kind.\n const victim = oldestAny ?? (this.lanes[0] as Lane)\n victim.synth.dispose()\n victim.synth = this.createSynth(kind)\n victim.synth.connect(victim.filter)\n victim.kind = kind\n return victim\n }\n\n /** Configure a lane from the profile, then sound it. `when` lets strums schedule ahead. */\n trigger(profile: SonicProfile, velocity: number, when?: number): void {\n const raw = velocity * profile.velocityScale\n if (raw <= 0.01) return // silent roles (e.g. mono theme text) stay silent\n const t = when ?? Tone.now()\n const vel = clamp(raw, 0.03, 1)\n const lane = this.acquire(profile.synthKind)\n\n const baseCutoff = Math.max(200, profile.filterHz)\n if (lane.kind === 'matter') {\n // EDGE bite: the filter strikes bright then settles (MATTER.md filter weave).\n const w = profile.voice\n lane.filter.Q.rampTo(w.filter.q, 0.02, t)\n lane.filter.frequency.cancelScheduledValues(t)\n lane.filter.frequency.setValueAtTime(Math.min(12000, baseCutoff * w.filter.biteAmount), t)\n lane.filter.frequency.exponentialRampTo(baseCutoff, w.filter.biteDecayS, t)\n } else {\n lane.filter.frequency.rampTo(baseCutoff, 0.02, t)\n lane.filter.Q.rampTo(profile.filterQ, 0.02, t)\n }\n lane.out.setPlacement(profile, t)\n\n const dur = profile.durationS\n try {\n switch (lane.kind) {\n case 'matter': {\n const mv = lane.synth as MatterVoice\n mv.trigger({\n freqHz: profile.freqHz,\n velocity: vel,\n durationS: dur,\n releaseScaleBase: profile.release / 0.3,\n voice: profile.voice,\n }, t, baseCutoff)\n lane.busyUntil = t + dur + mv.releaseTail()\n return\n }\n case 'noise': {\n ;(lane.synth as Tone.NoiseSynth).triggerAttackRelease(Math.min(dur, 0.2), t, vel)\n break\n }\n case 'pluck': {\n const pluck = lane.synth as Tone.PluckSynth\n pluck.set({ dampening: clamp(profile.filterHz, 400, 7000) })\n pluck.triggerAttackRelease(profile.freqHz, dur, t, vel)\n break\n }\n case 'membrane': {\n const mem = lane.synth as Tone.MembraneSynth\n mem.set({ envelope: { attack: Math.max(0.001, profile.attack / 4), release: profile.release } })\n mem.triggerAttackRelease(Math.max(30, profile.freqHz / 4), dur, t, vel)\n break\n }\n case 'fm': {\n const fm = lane.synth as Tone.FMSynth\n fm.set({ envelope: { attack: profile.attack, release: profile.release * 2 } })\n fm.triggerAttackRelease(profile.freqHz, dur, t, vel)\n break\n }\n default: {\n const syn = lane.synth as Tone.Synth\n syn.set({\n oscillator: { type: profile.wave },\n envelope: { attack: profile.attack, decay: 0.08, sustain: 0.25, release: profile.release },\n })\n syn.triggerAttackRelease(profile.freqHz, dur, t, vel)\n }\n }\n lane.busyUntil = t + dur + profile.release\n } catch (err) {\n console.warn('[sonarium] trigger failed', err)\n }\n }\n\n get activeCount(): number {\n const now = Tone.now()\n return this.lanes.filter((l) => l.busyUntil > now).length\n }\n\n /** MODULAR.md §3 — a sustained ribbon voice. Returns null when no matter lane can gate. */\n sustain(profile: SonicProfile, velocity: number): { setFreq(hz: number, glideS: number): void; release(): void } | null {\n const raw = velocity * profile.velocityScale\n if (raw <= 0.01) return null\n const lane = this.acquire('matter')\n if (!(lane.synth instanceof MatterVoice)) return null\n const mv = lane.synth\n const t = Tone.now()\n const baseCutoff = Math.max(200, profile.filterHz)\n lane.filter.Q.rampTo(profile.voice.filter.q, 0.02, t)\n lane.filter.frequency.cancelScheduledValues(t)\n lane.filter.frequency.setValueAtTime(Math.min(12000, baseCutoff * profile.voice.filter.biteAmount), t)\n lane.filter.frequency.exponentialRampTo(baseCutoff, profile.voice.filter.biteDecayS, t)\n lane.out.setPlacement(profile, t)\n mv.gateOn({\n freqHz: profile.freqHz,\n velocity: clamp(raw, 0.03, 1),\n durationS: 9999,\n releaseScaleBase: profile.release / 0.3,\n voice: profile.voice,\n }, t, baseCutoff)\n lane.busyUntil = t + 9999\n const voice = profile.voice\n return {\n setFreq(hz: number, glideS: number) {\n mv.setFreq(hz, glideS, voice.subShimmer.interval, voice.patch.fm.index)\n },\n release() {\n const tail = mv.gateOff()\n lane.busyUntil = Tone.now() + tail\n },\n }\n }\n\n dispose(): void {\n clearInterval(this.sleepTimer)\n for (const lane of this.lanes) {\n lane.synth.dispose()\n lane.filter.dispose()\n lane.out.dispose()\n }\n this.lanes = []\n }\n}\n","/**\n * MatterVoice — the woven, modular instrument (MATTER.md §3 + MODULAR.md §2).\n * Harmonic core (custom spectrum + sub/shimmer partner + unison twin) through a wavefolder,\n * audio-rate FM cable from oscB, breath + burst noise layers, and one LFO patched from CSS\n * (vibrato / tremolo / filter wobble). Supports one-shot triggers, sustained ribbon gating,\n * and sleeping (all sources stop when idle; restart in place). Imports Tone only.\n */\nimport * as Tone from 'tone'\nimport { foldCurve } from '../math/modular'\nimport type { MatterVoiceParams } from '../types'\n\nexport interface MatterTrigger {\n freqHz: number\n velocity: number\n durationS: number\n releaseScaleBase: number\n voice: MatterVoiceParams\n}\n\nconst FOLD_CURVE = foldCurve()\n\nexport class MatterVoice {\n /** Pool connects this to the lane filter's frequency param (LFO wobble tap). */\n readonly modFilterOut: Tone.Gain\n\n private oscA: Tone.Oscillator\n private oscA2: Tone.Oscillator\n private oscB: Tone.Oscillator\n private oscBGain: Tone.Gain\n private fmGain: Tone.Gain\n private foldPre: Tone.Gain\n private foldShaper: Tone.WaveShaper\n private foldWet: Tone.Gain\n private foldDry: Tone.Gain\n private unisonGain: Tone.Gain\n private breathNoise: Tone.Noise\n private breathFilter: Tone.Filter\n private breathGain: Tone.Gain\n private burstNoise: Tone.Noise\n private burstFilter: Tone.Filter\n private burstEnv: Tone.AmplitudeEnvelope\n private ampEnv: Tone.AmplitudeEnvelope\n private mix: Tone.Gain\n private lfo: Tone.LFO\n private lfoVib: Tone.Gain\n private lfoTrem: Tone.Gain\n private out: Tone.Gain\n private startedSources = false\n private held = false\n\n constructor() {\n this.out = new Tone.Gain(1)\n this.mix = new Tone.Gain(0.9)\n\n this.oscA = new Tone.Oscillator({ frequency: 220 })\n this.oscA2 = new Tone.Oscillator({ frequency: 220 })\n this.oscB = new Tone.Oscillator({ frequency: 110, type: 'sine' })\n this.oscBGain = new Tone.Gain(0.2)\n\n // The wavefolder (MODULAR.md M1): oscA splits dry/folded; envelope sweeps the fold.\n this.foldPre = new Tone.Gain(0.3)\n this.foldShaper = new Tone.WaveShaper(FOLD_CURVE)\n this.foldWet = new Tone.Gain(0)\n this.foldDry = new Tone.Gain(1)\n this.oscA.connect(this.foldPre)\n this.foldPre.connect(this.foldShaper)\n this.foldShaper.connect(this.foldWet)\n this.foldWet.connect(this.mix)\n this.oscA.connect(this.foldDry)\n this.foldDry.connect(this.mix)\n\n // Unison twin stays clean (thickness without mud).\n this.unisonGain = new Tone.Gain(0)\n this.oscA2.connect(this.unisonGain)\n this.unisonGain.connect(this.mix)\n\n // The FM cable (M2): oscB modulates oscA's frequency at audio rate.\n this.fmGain = new Tone.Gain(0)\n this.oscB.connect(this.fmGain)\n this.fmGain.connect(this.oscA.frequency)\n this.oscB.connect(this.oscBGain)\n this.oscBGain.connect(this.mix)\n\n this.breathNoise = new Tone.Noise('pink')\n this.breathFilter = new Tone.Filter({ type: 'bandpass', frequency: 600, Q: 1.1 })\n this.breathGain = new Tone.Gain(0)\n this.breathNoise.connect(this.breathFilter)\n this.breathFilter.connect(this.breathGain)\n this.breathGain.connect(this.mix)\n\n this.ampEnv = new Tone.AmplitudeEnvelope({ attack: 0.01, decay: 0.2, sustain: 0.25, release: 0.3 })\n this.mix.connect(this.ampEnv)\n this.ampEnv.connect(this.out)\n\n // The /k/ of kiki: bypasses the amp envelope so it stays a crisp onset event.\n this.burstNoise = new Tone.Noise('white')\n this.burstFilter = new Tone.Filter({ type: 'highpass', frequency: 3000 })\n this.burstEnv = new Tone.AmplitudeEnvelope({ attack: 0.001, decay: 0.02, sustain: 0, release: 0.02 })\n this.burstNoise.connect(this.burstFilter)\n this.burstFilter.connect(this.burstEnv)\n this.burstEnv.connect(this.out)\n\n // One LFO, three depth taps (M4/M5): vibrato, tremolo, filter wobble.\n this.lfo = new Tone.LFO({ frequency: 0.5, min: -1, max: 1, type: 'sine' })\n this.lfoVib = new Tone.Gain(0)\n this.lfoTrem = new Tone.Gain(0)\n this.modFilterOut = new Tone.Gain(0)\n this.lfo.connect(this.lfoVib)\n this.lfo.connect(this.lfoTrem)\n this.lfo.connect(this.modFilterOut)\n this.lfoVib.connect(this.oscA.detune)\n this.lfoVib.connect(this.oscA2.detune)\n this.lfoTrem.connect(this.mix.gain)\n }\n\n connect(dest: Tone.InputNode): this {\n this.out.connect(dest)\n return this\n }\n\n private ensureRunning(when: number): void {\n if (this.startedSources) return\n this.startedSources = true\n this.oscA.start(when)\n this.oscA2.start(when)\n this.oscB.start(when)\n this.breathNoise.start(when)\n this.burstNoise.start(when)\n this.lfo.start(when)\n }\n\n /** MODULAR.md §4 — idle lanes power down completely; the next trigger restarts in place. */\n sleep(): void {\n if (!this.startedSources || this.held) return\n this.startedSources = false\n try {\n this.oscA.stop()\n this.oscA2.stop()\n this.oscB.stop()\n this.breathNoise.stop()\n this.burstNoise.stop()\n this.lfo.stop()\n } catch { /* already stopped */ }\n }\n\n /** Everything both trigger() and gateOn() share: spectrum, patch, pitch, modulation. */\n private applyVoice(t: MatterTrigger, when: number, baseCutoffHz: number): void {\n const v = t.voice\n this.ensureRunning(when)\n this.oscA.partials = v.partials\n this.oscA2.partials = v.partials\n\n // Pitch behaviour: glide for round (+M6 portamento), jitter for rough texture.\n const jitter = (Math.random() * 2 - 1) * v.jitterCents\n this.oscA.detune.setValueAtTime(jitter, when)\n const glide = v.glideS + v.patch.portamentoS\n if (glide > 0.002 && !this.held) {\n this.oscA.frequency.setValueAtTime(t.freqHz * 0.917, when)\n this.oscA.frequency.rampTo(t.freqHz, glide, when)\n } else {\n this.oscA.frequency.setValueAtTime(t.freqHz, when)\n }\n this.oscA2.frequency.setValueAtTime(t.freqHz, when)\n this.oscA2.detune.setValueAtTime(jitter + v.patch.unison.detuneCents, when)\n this.unisonGain.gain.rampTo(v.patch.unison.mix, 0.02, when)\n this.oscB.frequency.setValueAtTime(t.freqHz * Math.pow(2, v.subShimmer.interval / 12), when)\n this.oscBGain.gain.rampTo(v.subShimmer.level, 0.02, when)\n\n // Modular patch: fold drive/mix, FM index (× carrier), LFO rate/shape/depths.\n this.foldPre.gain.rampTo(0.3 + v.patch.fold.drive * 1.2, 0.02, when)\n this.foldWet.gain.rampTo(v.patch.fold.mix, 0.02, when)\n this.foldDry.gain.rampTo(1 - v.patch.fold.mix * 0.7, 0.02, when)\n this.fmGain.gain.rampTo(v.patch.fm.index * t.freqHz, 0.02, when)\n const lfoOn = v.patch.lfo.rateHz > 0.01\n this.lfo.frequency.value = Math.max(0.01, v.patch.lfo.rateHz)\n this.lfo.type = v.patch.lfo.shape\n this.lfoVib.gain.rampTo(lfoOn ? v.patch.lfo.vibratoCents : 0, 0.05, when)\n this.lfoTrem.gain.rampTo(lfoOn ? 0.9 * v.patch.lfo.tremolo : 0, 0.05, when)\n this.modFilterOut.gain.rampTo(lfoOn ? v.patch.lfo.filterDepth * baseCutoffHz : 0, 0.05, when)\n\n // Breath rides the tone (common fate = fusion).\n this.breathFilter.frequency.rampTo(Math.min(8000, t.freqHz * v.breath.bpRatio), 0.02, when)\n this.breathGain.gain.rampTo(v.breath.level, 0.02, when)\n\n // Envelope weave.\n this.ampEnv.attack = v.envelope.attackS\n this.ampEnv.decay = v.envelope.decayS\n this.ampEnv.sustain = v.envelope.sustain\n this.ampEnv.release = 0.3 * t.releaseScaleBase * v.envelope.releaseScale\n }\n\n trigger(t: MatterTrigger, when: number, baseCutoffHz = 4000): void {\n this.applyVoice(t, when, baseCutoffHz)\n this.ampEnv.triggerAttackRelease(t.durationS, when, t.velocity)\n if (t.voice.transient.level > 0.02) {\n this.burstFilter.frequency.setValueAtTime(t.voice.transient.hpHz, when)\n this.burstEnv.decay = t.voice.transient.lengthS\n this.burstEnv.triggerAttackRelease(t.voice.transient.lengthS, when, t.velocity * t.voice.transient.level)\n }\n }\n\n // ----------------------------------------------------------- ribbon (MODULAR.md §3)\n\n gateOn(t: MatterTrigger, when: number, baseCutoffHz = 4000): void {\n this.applyVoice(t, when, baseCutoffHz)\n this.held = true\n this.ampEnv.sustain = Math.max(0.4, t.voice.envelope.sustain)\n this.ampEnv.triggerAttack(when, t.velocity)\n }\n\n /** Ribbon pitch move — quantized upstream; the portamento IS the glissando feel. */\n setFreq(freqHz: number, glideS: number, subInterval: number, fmIndex: number): void {\n const g = Math.max(0.015, glideS)\n this.oscA.frequency.rampTo(freqHz, g)\n this.oscA2.frequency.rampTo(freqHz, g)\n this.oscB.frequency.rampTo(freqHz * Math.pow(2, subInterval / 12), g)\n this.fmGain.gain.rampTo(fmIndex * freqHz, g)\n }\n\n gateOff(when?: number): number {\n this.held = false\n this.ampEnv.triggerRelease(when ?? Tone.now())\n return this.ampEnv.release as number\n }\n\n releaseTail(): number {\n return this.ampEnv.release as number\n }\n\n dispose(): void {\n for (const n of [\n this.oscA, this.oscA2, this.oscB, this.oscBGain, this.fmGain,\n this.foldPre, this.foldShaper, this.foldWet, this.foldDry, this.unisonGain,\n this.breathNoise, this.breathFilter, this.breathGain,\n this.burstNoise, this.burstFilter, this.burstEnv,\n this.lfo, this.lfoVib, this.lfoTrem, this.modFilterOut,\n this.ampEnv, this.mix, this.out,\n ]) n.dispose()\n }\n}\n","/**\n * L2 — pointer: hover previews (I1) + look-around (I9).\n * Ghost-trigger guards (v0.5, user-reported): a \"hover\" only counts when the POINTER moved onto\n * the element. Scrolling moves elements under a stationary cursor and DOM mutations appear under\n * it — both fire pointerover without any user hover intent, and both are suppressed here.\n */\nimport type { Engine } from '../core/engine'\nimport type { Role } from '../types'\n\nconst PREVIEW_ROLES: ReadonlySet<Role> = new Set(['button', 'link', 'toggle', 'input', 'item', 'heading', 'media', 'text'])\nconst HOVER_THROTTLE_MS = 80\n/** pointerover within this window after a scroll = the page moved, not the hand. */\nconst SCROLL_SUPPRESS_MS = 250\n/** pointerover needs pointer movement at most this long ago to count as intentional. */\nconst MOVE_FRESHNESS_MS = 400\n/** The resolved element must be within this many ancestors of the actual target —\n * hovering a blank region must not preview some distant registered container. */\nconst MAX_RESOLVE_HOPS = 4\n\nexport function attachPointer(engine: Engine): () => void {\n const lastHover = new WeakMap<Element, number>()\n let lastScrollT = -Infinity\n let lastMoveT = -Infinity\n\n const onMove = (e: PointerEvent) => {\n lastMoveT = performance.now()\n engine.rig?.pointTo(e.clientX / window.innerWidth, e.clientY / window.innerHeight)\n }\n\n const onScroll = () => {\n lastScrollT = performance.now()\n }\n\n const withinHops = (target: Element, resolved: Element): boolean => {\n let n: Element | null = target\n for (let d = 0; n && d <= MAX_RESOLVE_HOPS; d++) {\n if (n === resolved) return true\n n = n.parentElement\n }\n return false\n }\n\n const onOver = (e: PointerEvent) => {\n const now = performance.now()\n if (now - lastScrollT < SCROLL_SUPPRESS_MS) return // page slid under the cursor\n if (now - lastMoveT > MOVE_FRESHNESS_MS) return // nothing moved the pointer here\n const target = e.target as Element | null\n const el = engine.scanner?.resolve(target)\n if (!el || !target || !withinHops(target, el)) return\n const profile = engine.scanner.profileFor(el)\n if (!profile || !PREVIEW_ROLES.has(profile.role)) return\n if (now - (lastHover.get(el) ?? -Infinity) < HOVER_THROTTLE_MS) return\n lastHover.set(el, now)\n engine.excite(el, 0.25, 'preview')\n }\n\n window.addEventListener('pointermove', onMove, { passive: true })\n window.addEventListener('pointerover', onOver, { passive: true })\n window.addEventListener('scroll', onScroll, { passive: true, capture: true })\n return () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerover', onOver)\n window.removeEventListener('scroll', onScroll, { capture: true })\n }\n}\n","/**\n * L2 — activation: full notes on press (I2), container strums (I3), toggle intervals (I6).\n */\nimport type { Engine } from '../core/engine'\nimport { ELIGIBLE_SELECTOR } from '../core/scanner'\n\nconst DEDUPE_MS = 80\n\nexport function attachActivate(engine: Engine): () => void {\n const lastHit = new WeakMap<Element, number>()\n\n const activate = (target: Element | null) => {\n const el = engine.scanner?.resolve(target)\n if (!el) return\n const now = performance.now()\n if (now - (lastHit.get(el) ?? -Infinity) < DEDUPE_MS) return\n lastHit.set(el, now)\n\n const profile = engine.scanner.profileFor(el)\n if (!profile) return\n if (profile.role === 'toggle') return // sounded by the change handler (I6)\n if (profile.role === 'container') {\n const children = Array.from(el.querySelectorAll(ELIGIBLE_SELECTOR))\n .filter((c) => c.parentElement && engine.scanner.resolve(c) === c)\n .filter((c) => {\n const r = c.getBoundingClientRect()\n return r.width > 0 && r.bottom > 0 && r.top < window.innerHeight\n })\n if (children.length >= 2) {\n engine.strum(children, 0.5)\n return\n }\n }\n engine.excite(el, 0.75, 'hit')\n }\n\n // pointerdown for latency (<30 ms budget); click catches keyboard activation (Enter/Space).\n const onPointerDown = (e: PointerEvent) => activate(e.target as Element | null)\n const onClick = (e: MouseEvent) => activate(e.target as Element | null)\n\n const onChange = (e: Event) => {\n const t = e.target\n if (!(t instanceof HTMLInputElement) || (t.type !== 'checkbox' && t.type !== 'radio')) return\n const on = t.checked\n engine.excite(t, 0.5, on ? 'toggle-on' : 'toggle-off')\n }\n\n window.addEventListener('pointerdown', onPointerDown, { passive: true })\n window.addEventListener('click', onClick, { passive: true })\n window.addEventListener('change', onChange, { passive: true })\n return () => {\n window.removeEventListener('pointerdown', onPointerDown)\n window.removeEventListener('click', onClick)\n window.removeEventListener('change', onChange)\n }\n}\n","/**\n * L2 — keyboard: focus previews for Tab navigation (I4, accessibility parity) and\n * typing ticks that rise as the field fills (I5).\n */\nimport type { Engine } from '../core/engine'\n\nconst TICK_THROTTLE_MS = 30\n// Pentatonic-safe intervals: ticks climb without ever clashing with the site key.\nconst FILL_INTERVALS = [0, 2, 4, 7, 9, 12, 14, 16] as const\n\nexport function attachKeyboard(engine: Engine): () => void {\n let lastTick = 0\n let lastPointerDownT = -Infinity\n\n // Clicking focuses too — that focus must stay silent or every click sounds twice\n // (ghost-trigger fix, v0.5). Only keyboard-driven focus (Tab) previews.\n const onPointerDown = () => {\n lastPointerDownT = performance.now()\n }\n\n const onFocus = (e: FocusEvent) => {\n if (performance.now() - lastPointerDownT < 500) return\n const el = engine.scanner?.resolve(e.target as Element | null)\n if (el) engine.excite(el, 0.35, 'preview')\n }\n\n const onKeydown = (e: KeyboardEvent) => {\n const t = e.target\n const editable = t instanceof HTMLElement\n && (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t.isContentEditable)\n if (!editable) return\n const now = performance.now()\n if (now - lastTick < TICK_THROTTLE_MS) return\n lastTick = now\n const len = (t as HTMLInputElement).value?.length ?? t.textContent?.length ?? 0\n const interval = FILL_INTERVALS[Math.min(FILL_INTERVALS.length - 1, Math.floor(len / 4))] as number\n engine.excite(t, 0.15, 'tick', undefined, interval)\n }\n\n window.addEventListener('pointerdown', onPointerDown, { passive: true, capture: true })\n window.addEventListener('focusin', onFocus, { passive: true })\n window.addEventListener('keydown', onKeydown, { passive: true })\n return () => {\n window.removeEventListener('pointerdown', onPointerDown, { capture: true })\n window.removeEventListener('focusin', onFocus)\n window.removeEventListener('keydown', onKeydown)\n }\n}\n","/**\n * L2 — scroll & resize: cached rects go stale (I8), the room follows the viewport (S7/S8),\n * and scroll velocity becomes air rushing past (MATTER.md §2.2).\n */\nimport { airRushGain } from '../math/matter'\nimport type { Engine } from '../core/engine'\n\nexport function attachScroll(engine: Engine): () => void {\n let scrollQueued = false\n let lastY = window.scrollY\n let lastT = performance.now()\n const onScroll = () => {\n if (scrollQueued) return\n scrollQueued = true\n requestAnimationFrame(() => {\n scrollQueued = false\n engine.geometryChanged()\n const now = performance.now()\n const dt = Math.max(1, now - lastT)\n const v = Math.abs(window.scrollY - lastY) / dt // px per ms\n lastY = window.scrollY\n lastT = now\n engine.airRush(airRushGain(v))\n })\n }\n\n let resizeQueued = false\n const onResize = () => {\n if (resizeQueued) return\n resizeQueued = true\n requestAnimationFrame(() => {\n resizeQueued = false\n engine.roomResized()\n })\n }\n\n window.addEventListener('scroll', onScroll, { passive: true, capture: true })\n window.addEventListener('resize', onResize, { passive: true })\n return () => {\n window.removeEventListener('scroll', onScroll, { capture: true })\n window.removeEventListener('resize', onResize)\n }\n}\n","/**\n * L2 — embodied motion: device tilt steers the ears (I10), a shake strums the visible\n * page left→right (I11). iOS 13+ requires a permission request from a user gesture; attach()\n * runs inside the unlock gesture, so we ask immediately and degrade silently if refused.\n */\nimport type { Engine } from '../core/engine'\n\nconst SHAKE_THRESHOLD = 18 // m/s² deviation from gravity\nconst SHAKE_REFRACTORY_MS = 600\n\nexport function attachMotion(engine: Engine): () => void {\n if (typeof DeviceOrientationEvent === 'undefined') return () => {}\n\n let lastShake = 0\n let attached = false\n\n const onOrientation = (e: DeviceOrientationEvent) => {\n if (e.gamma == null || e.beta == null) return\n engine.rig?.tiltTo(e.gamma, e.beta)\n }\n\n const onMotion = (e: DeviceMotionEvent) => {\n const a = e.accelerationIncludingGravity\n if (!a || a.x == null || a.y == null || a.z == null) return\n const magnitude = Math.abs(Math.sqrt(a.x * a.x + a.y * a.y + a.z * a.z) - 9.81)\n const now = performance.now()\n if (now - lastShake <= SHAKE_REFRACTORY_MS) return\n if (magnitude > SHAKE_THRESHOLD) {\n lastShake = now\n engine.strum(engine.scanner.visibleElements(), 0.5)\n return\n }\n // Directional flick (v0.6 gesture grammar): a horizontal jab strums in its direction.\n if (Math.abs(a.x) > 12 && Math.abs(a.x) > 2 * Math.abs(a.y)) {\n lastShake = now\n engine.strum(engine.scanner.visibleElements(), 0.4, 'strum', a.x > 0)\n }\n }\n\n const listen = () => {\n if (attached) return\n attached = true\n window.addEventListener('deviceorientation', onOrientation, { passive: true })\n window.addEventListener('devicemotion', onMotion, { passive: true })\n }\n\n const request = (DeviceOrientationEvent as unknown as { requestPermission?: () => Promise<string> }).requestPermission\n if (typeof request === 'function') {\n request.call(DeviceOrientationEvent)\n .then((state) => { if (state === 'granted') listen() })\n .catch(() => { /* user said no, or we were outside a gesture — stay silent */ })\n } else {\n listen()\n }\n\n return () => {\n if (!attached) return\n window.removeEventListener('deviceorientation', onOrientation)\n window.removeEventListener('devicemotion', onMotion)\n }\n}\n","/**\n * L2 — drag glissando (MODULAR.md §3): press an interactive element and drag — the pointer\n * becomes a ribbon controller sweeping scale degrees. The initial hit stays immediate (the\n * ribbon only gates after 14 px of travel; latency invariant untouched).\n */\nimport type { Engine } from '../core/engine'\n\nconst START_PX = 14\n\nexport function attachDrag(engine: Engine): () => void {\n let session: { x0: number; el: Element; handle: ReturnType<Engine['ribbon']> } | null = null\n\n const onDown = (e: PointerEvent) => {\n if (!e.isPrimary) return\n const el = engine.scanner?.resolve(e.target as Element | null)\n if (!el) return\n const p = engine.scanner.profileFor(el)\n if (!p || p.role === 'container' || p.role === 'text') return\n session = { x0: e.clientX, el, handle: null }\n }\n\n const onMove = (e: PointerEvent) => {\n if (!session) return\n const dx = e.clientX - session.x0\n if (!session.handle) {\n if (Math.abs(dx) < START_PX) return\n session.handle = engine.ribbon(session.el)\n if (!session.handle) {\n session = null\n return\n }\n }\n session.handle.move(dx)\n }\n\n const end = () => {\n session?.handle?.release()\n session = null\n }\n\n window.addEventListener('pointerdown', onDown, { passive: true })\n window.addEventListener('pointermove', onMove, { passive: true })\n window.addEventListener('pointerup', end, { passive: true })\n window.addEventListener('pointercancel', end, { passive: true })\n return () => {\n end()\n window.removeEventListener('pointerdown', onDown)\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', end)\n window.removeEventListener('pointercancel', end)\n }\n}\n","/**\n * L2-out — Web MIDI bridge (option `midi: true`): every trigger mirrors to the first MIDI\n * output as note events, channel per role. The page becomes a MIDI controller — record your\n * browsing into a DAW, or drive hardware from the DOM. Feature-detected; silent elsewhere.\n */\nimport type { Engine } from '../core/engine'\nimport type { Role, TriggerDetail } from '../types'\n\nconst ROLE_CHANNEL: Partial<Record<Role, number>> = {\n button: 0, link: 1, toggle: 2, input: 3, heading: 4, media: 5, item: 6, text: 7, container: 8,\n}\n\nexport function attachMidi(engine: Engine): () => void {\n const nav = navigator as Navigator & { requestMIDIAccess?: () => Promise<unknown> }\n if (typeof nav.requestMIDIAccess !== 'function') return () => {}\n let out: { send(data: number[]): void } | null = null\n let off: (() => void) | null = null\n\n nav.requestMIDIAccess()\n .then((access) => {\n const a = access as unknown as { outputs: Map<string, { send(data: number[]): void }> }\n out = a.outputs.values().next().value ?? null\n if (!out) return\n off = engine.on('trigger', (detail) => {\n const d = detail as TriggerDetail\n const note = Math.max(0, Math.min(127, Math.round(d.profile.midi)))\n const vel = Math.max(1, Math.min(127, Math.round(d.velocity * d.profile.velocityScale * 127)))\n const ch = ROLE_CHANNEL[d.profile.role] ?? 9\n try {\n out!.send([0x90 | ch, note, vel])\n setTimeout(() => {\n try { out?.send([0x80 | ch, note, 0]) } catch { /* device gone */ }\n }, Math.min(4000, d.profile.durationS * 1000 + 60))\n } catch { /* device gone */ }\n })\n })\n .catch(() => { /* permission denied — stay silent */ })\n\n return () => off?.()\n}\n","/**\n * Sonarium — drop-in acoustic UX.\n * One script tag turns any webpage into a spatial sound field: layout becomes a stereo stage,\n * geometry becomes timbre (Kiki/Bouba), the DOM tree becomes depth and harmony, the viewport\n * becomes a room, and your cursor becomes your ears.\n *\n * import { create } from 'sonarium' // ESM\n * const space = create({ theme: 'aurora' })\n *\n * <script src=\".../sonarium.iife.js\" data-auto></script> // zero-code\n *\n * Docs: https://github.com/frank890417/sonarium — start with docs/PLAN.md.\n */\nimport { Engine } from './core/engine'\nimport type { SonariumOptions } from './types'\n\nexport const version = '0.6.0'\n\nexport type {\n SonariumOptions, SonicProfile, Theme, VoiceRecipe, Role, Wave, SynthKind,\n Articulation, TriggerDetail, SonariumEvent, SphereProps, PerceptualFactors,\n} from './types'\nexport { THEMES } from './themes/index'\nexport { siteKey, parseKey, degreeToMidi, midiToFreq, midiToNoteName, stepInScale, SCALES } from './math/scales'\nexport * as mapping from './math/mapping'\nexport * as matter from './math/matter'\nexport * as chroma from './math/chroma'\nexport * as pulse from './math/pulse'\nexport * as modular from './math/modular'\n// The pure spatial layer (SPATIAL.md) — reusable beyond the DOM.\nexport { foaGains, unitVector, DEG } from './spatial/sh'\nexport { rotationMatrix, lookMatrix, applyMat3 } from './spatial/rotation'\nexport { CUBE_LAYOUT, decodeMatrix, decodeGains } from './spatial/decoder'\nexport * as sphereMapping from './spatial/sphere'\nexport { DEFAULT_FACTORS } from './spatial/perceptual'\nexport type { Engine }\n\n/**\n * Create a Sonarium instance. Safe to call before any user gesture: audio arms itself and\n * starts on the first pointer/key interaction (browser autoplay policy treated as a feature).\n */\nexport function create(options: SonariumOptions = {}): Engine {\n return new Engine(options)\n}\n\n// ---------------------------------------------------------------------------- auto-init\n// <script src=\"sonarium.iife.js\" data-auto data-theme=\"paper\" data-ambient=\"0.2\"></script>\nfunction autoInit(): void {\n if (typeof document === 'undefined') return\n const script = document.currentScript as HTMLScriptElement | null\n if (!script || script.dataset.auto === undefined) return\n const opts: SonariumOptions = {}\n if (script.dataset.theme) opts.theme = script.dataset.theme as SonariumOptions['theme']\n if (script.dataset.key) opts.key = script.dataset.key\n if (script.dataset.ambient) opts.ambient = parseFloat(script.dataset.ambient)\n if (script.dataset.listener) opts.listener = script.dataset.listener as SonariumOptions['listener']\n if (script.dataset.volume) opts.volume = parseFloat(script.dataset.volume)\n if (script.dataset.panning) opts.panning = script.dataset.panning as SonariumOptions['panning']\n const boot = () => {\n try {\n const engine = create(opts)\n ;(window as unknown as Record<string, unknown>).sonarium = engine\n } catch (err) {\n console.warn('[sonarium] auto-init failed', err)\n }\n }\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', boot, { once: true })\n } else {\n boot()\n }\n}\n\nautoInit()\n"],"mappings":"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","names":["Tone","Tone","Tone","directGain","Tone","sizeT","roundness","Tone","Tone","now","norm","Tone","Tone","glideS","fmIndex","now","glideS","now","now","now","now","now","start","now"]}