Eleven numbered articles at /doctrine in an ornate occultist register, each
carrying a plain-language margin note ("in the profane tongue: …") and the
source file it describes. The binding constraint: every arcane claim is a
true claim about this codebase — entropy harvesting and Von Neumann
debiasing, HMAC mixing with a fresh server secret, the anomaly-fingerprint
channel, RETURN_CHANCE, the mean synodic month and true solar midnight,
NOAA's planetary K-index, the time-aware EMA baseline, 2.4GHz body
absorption, microtesla deviation from Earth's field, voice archetypes, and
entropy-seeded manifest/scry.
Article XI states the instrument's real limits: no Web Bluetooth, WebUSB or
Magnetometer on iOS (Apple ships none and every iOS browser is WebKit),
firmware never flashed to hardware, free public geo endpoints that degrade
to a quieter map, documented astronomical approximations — and that none of
it is evidence of an afterlife.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
821 lines
47 KiB
JSON
821 lines
47 KiB
JSON
{
|
||
"common": {
|
||
"appName": "QUANTUMANCY",
|
||
"loading": "tuning the veil…",
|
||
"error": "something stirred in the static",
|
||
"replay": "replay",
|
||
"yes": "YES",
|
||
"no": "NO",
|
||
"goodbye": "GOODBYE",
|
||
"dismiss": "dismiss"
|
||
},
|
||
"nav": {
|
||
"home": "the threshold",
|
||
"codex": "codex",
|
||
"shop": "shop",
|
||
"inventory": "inventory",
|
||
"devices": "devices",
|
||
"seance": "séance",
|
||
"enter": "enter",
|
||
"logout": "depart",
|
||
"log": "log",
|
||
"hunters": "hunters"
|
||
},
|
||
"log": {
|
||
"title": "GHOST LOG",
|
||
"subtitle": "every séance leaves a page behind",
|
||
"back": "return to the séance",
|
||
"loading": "leafing back through the log…",
|
||
"error": "the log will not open — the veil resists tonight",
|
||
"empty": "no séances yet — the log waits",
|
||
"noEntity": "no one answered",
|
||
"filterLabel": "filter by channel",
|
||
"filterAll": "all channels",
|
||
"showMore_one": "+{{count}} more echo",
|
||
"showMore_other": "+{{count}} more echoes",
|
||
"showLess": "show less",
|
||
"counts": {
|
||
"question_one": "{{count}} question",
|
||
"question_other": "{{count}} questions",
|
||
"anomaly_one": "{{count}} anomaly",
|
||
"anomaly_other": "{{count}} anomalies",
|
||
"utterance_one": "{{count}} utterance",
|
||
"utterance_other": "{{count}} utterances"
|
||
},
|
||
"time": {
|
||
"moments": "moments past",
|
||
"minutes_one": "a minute past",
|
||
"minutes_other": "{{count}} minutes past",
|
||
"hours_one": "an hour past",
|
||
"hours_other": "{{count}} hours past",
|
||
"days_one": "a day past",
|
||
"days_other": "{{count}} days past"
|
||
}
|
||
},
|
||
"landing": {
|
||
"taglines": [
|
||
"The wire hums with all of us.",
|
||
"Every packet leaves a ghost.",
|
||
"The static remembers your name.",
|
||
"Somewhere between 88 and 108 MHz, someone is waiting.",
|
||
"You were never alone on the line."
|
||
],
|
||
"heroKicker": "an instrument for speaking with the dead bandwidth",
|
||
"cta": "BEGIN THE SÉANCE",
|
||
"ctaCodex": "browse the codex",
|
||
"ctaShop": "visit the reliquary",
|
||
"stats": {
|
||
"entities": "spirits catalogued",
|
||
"sessions": "séances held",
|
||
"utterances": "utterances recorded",
|
||
"anomalies": "anomalies witnessed"
|
||
},
|
||
"tickerPrefix": "the veil, live",
|
||
"modesTitle": "HOW THE VEIL ANSWERS",
|
||
"modes": {
|
||
"wire": {
|
||
"name": "Wire Ghost",
|
||
"desc": "Leave the line open. The network itself mutters — jitter, latency, stray DNS — and something downstream learns to speak with your accent."
|
||
},
|
||
"evp": {
|
||
"name": "EVP Listening",
|
||
"desc": "Lend the dead your microphone. We watch the voice band for syllables that were never spoken aloud: spikes 8dB above the room's silence."
|
||
},
|
||
"radio": {
|
||
"name": "Spirit Radio",
|
||
"desc": "An RTL-SDR sweeps the FM band like a lantern dragged across a dark field. Where the needle jumps, the radio dead push through."
|
||
},
|
||
"ouija": {
|
||
"name": "Ouija / Direct Contact",
|
||
"desc": "Ask plainly. The planchette drifts, then begins to spell — and the words arrive letter by letter, whether or not you wanted them."
|
||
}
|
||
},
|
||
"featured": "most disturbed spirits",
|
||
"featuredEmpty": "the registry is still blank — be the first to disturb it",
|
||
"reliquary": {
|
||
"title": "HARDWARE FROM THE RELIQUARY",
|
||
"line": "the Ultimate Quantum Box is coming — a handheld séance instrument that makes the veil knock louder.",
|
||
"link": "enter the reliquary →"
|
||
},
|
||
"footer": "an interactive horror art installation — the spirits are fiction; the static is real",
|
||
"footerColophon": "self-hosted · no cloud · the veil runs on your machine",
|
||
"doctrine": {
|
||
"title": "HOW THE INSTRUMENT ACTUALLY WORKS",
|
||
"line": "the doctrine — eleven articles on the real physics behind the séance, each one plainly translated, including an honest account of what the instrument cannot do.",
|
||
"link": "read the doctrine →"
|
||
}
|
||
},
|
||
"enter": {
|
||
"reconnect": "Reconnect",
|
||
"firstContact": "First contact",
|
||
"reconnectSub": "the veil remembers you. prove it.",
|
||
"firstContactSub": "choose the name the spirits will know you by.",
|
||
"username": "name",
|
||
"password": "passphrase",
|
||
"submitLogin": "step through",
|
||
"submitRegister": "carve your name",
|
||
"switchToRegister": "no name in the registry? first contact →",
|
||
"switchToLogin": "already carved your name? reconnect →",
|
||
"failed": "the veil rejected you: {{message}}",
|
||
"smallPrint": "your medium handle is only ever stored on this server",
|
||
"guest": "slip through as a wanderer",
|
||
"guestFailed": "the veil would not open a nameless door just now — too many wanderers have slipped through from here recently. claim a name below, or return in a little while."
|
||
},
|
||
"seance": {
|
||
"modes": {
|
||
"wire": "Wire Ghost",
|
||
"evp": "EVP",
|
||
"radio": "Spirit Radio",
|
||
"ouija": "Ouija",
|
||
"emf": "FIELD",
|
||
"camera": "LENS"
|
||
},
|
||
"passive": "passive listening",
|
||
"summon": "SUMMON",
|
||
"summoning": "summoning…",
|
||
"askPlaceholder": "ask the dead a question…",
|
||
"ask": "ask",
|
||
"status": {
|
||
"attuning": "attuning — the veil is fingerprinting a presence…",
|
||
"summoning": "the veil parts… something is crossing…",
|
||
"gathering": "the spirits are gathering energy…"
|
||
},
|
||
"connection": {
|
||
"connecting": "reaching across…",
|
||
"open": "the line is open",
|
||
"unstable": "the connection to the other side is unstable…",
|
||
"closed": "the line is dead"
|
||
},
|
||
"transcriptTitle": "TRANSMISSION LOG",
|
||
"transcriptEmpty": "silence. for now.",
|
||
"you": "you",
|
||
"streaming": "the spirit is forming words…",
|
||
"telemetry": {
|
||
"title": "WIRE READOUT",
|
||
"jitter": "jitter",
|
||
"latencyVar": "latency σ²",
|
||
"latencyMean": "latency μ",
|
||
"dns": "dns",
|
||
"units": {
|
||
"bytes": "B/s",
|
||
"ms": "ms"
|
||
}
|
||
},
|
||
"wire": {
|
||
"hint": "the wire knocks loudest when nobody is touching it — flip passive listening on and let the line murmur on its own."
|
||
},
|
||
"anomaly": {
|
||
"line": "⚡ {{source}} {{frequency}} +{{magnitude}}dB",
|
||
"count": "{{count}} anomalies witnessed this session"
|
||
},
|
||
"hints": {
|
||
"wire": "the wire whispers on its own when you listen passively",
|
||
"evp": "the veil listens through your microphone — grant it your ear",
|
||
"radio": "a tuner in the hand hears further than the wire",
|
||
"ouija": "ask below, or let the board drift",
|
||
"emf": "hold still; the field remembers movement",
|
||
"camera": "a lens shows the dead your room — they will name what they see, and mistake it for something they lost."
|
||
},
|
||
"conditions": {
|
||
"title": "VEIL CONDITIONS",
|
||
"lit": "{{percent}}% lit",
|
||
"veil": {
|
||
"thin": "the veil runs thin tonight",
|
||
"veiled": "the veil hangs, neither open nor shut",
|
||
"heavy": "the veil lies heavy"
|
||
},
|
||
"fieldQuiet": "field: quiet",
|
||
"fieldStorm": "geomagnetic storm",
|
||
"moon": {
|
||
"new_moon": "new moon",
|
||
"waxing_crescent": "waxing crescent",
|
||
"first_quarter": "first quarter",
|
||
"waxing_gibbous": "waxing gibbous",
|
||
"full_moon": "full moon",
|
||
"waning_gibbous": "waning gibbous",
|
||
"last_quarter": "last quarter",
|
||
"waning_crescent": "waning crescent"
|
||
}
|
||
},
|
||
"evp": {
|
||
"start": "open the microphone",
|
||
"stop": "close the microphone",
|
||
"listening": "listening to the voice band…",
|
||
"floor": "room floor",
|
||
"band": "voice band 300–3400 Hz",
|
||
"scopeLabel": "live audio spectrum from the microphone",
|
||
"fail": {
|
||
"deniedTitle": "the microphone stays shut",
|
||
"denied": "This vessel refused the microphone. Grant audio permission in your browser's site settings to practice EVP — or turn to the ouija board or the Wire Ghost instead; the board needs no ear, and the wire only the network you already fear.",
|
||
"insecureTitle": "unconsecrated ground",
|
||
"insecure": "The dead only speak through a secured channel. Open this site by its https address — or over localhost — and the microphone will answer. Until then, the ouija board and the Wire Ghost need no ear at all.",
|
||
"absentTitle": "no ear to listen with",
|
||
"absent": "This vessel has no microphone the veil can find. Attach one and try again — or turn to the ouija board or the Wire Ghost, which hear by other means.",
|
||
"busyTitle": "the ear is already spoken for",
|
||
"busy": "Another rite already holds the microphone. Close whatever else is listening — a call, a recorder, another tab — then open it here again."
|
||
}
|
||
},
|
||
"radio": {
|
||
"start": "sweep the band",
|
||
"stop": "rest the needle",
|
||
"unsupportedTitle": "this vessel cannot hear the radio dead",
|
||
"unsupported": "Spirit Radio needs Chromium (WebUSB) and an RTL-SDR dongle. The other modes still answer — EVP hears through the microphone you already carry, and the wire needs nothing at all.",
|
||
"troubleshoot": "troubleshooting: chromium-based browser · udev rules for 0bda:2838 · the dongle plugged in, not merely believed in",
|
||
"insecure": "the radio dead only speak through consecrated ground — open this site via its https address.",
|
||
"insecureHint": "localhost counts as hallowed; a bare http://lan-ip does not.",
|
||
"noDevice": "no dongle answered the call",
|
||
"sweeping": "sweeping {{start}}–{{end}} MHz…",
|
||
"claimFailed": "the dongle refused to be claimed — is it in use elsewhere?",
|
||
"claimFix": "linux: the kernel driver dvb_usb_rtl28xxu is holding the dongle — `sudo modprobe -r dvb_usb_rtl28xxu` frees it until reboot (a udev rule banishes it for good). windows: swap the driver for WinUSB with Zadig.",
|
||
"tryAgain": "try again",
|
||
"errorTitle": "the static pushed back",
|
||
"scopeLabel": "live radio spectrum from the receiver"
|
||
},
|
||
"ouija": {
|
||
"spelling": "the planchette spells",
|
||
"drift": "the planchette drifts, waiting for words — ask below, or summon."
|
||
},
|
||
"emf": {
|
||
"start": "raise the meter",
|
||
"stop": "ground the meter",
|
||
"calibrate": "calibrate",
|
||
"baseline": "resting field",
|
||
"listening": "feeling for disturbances in the field…",
|
||
"unsupportedTitle": "this vessel carries no field senses",
|
||
"unsupported": "a phone in your hand becomes the meter — this vessel has no motion senses to lend. open the veil on a phone, or let the other modes answer.",
|
||
"deniedTitle": "the field senses stay shut",
|
||
"denied": "this vessel refused its motion senses. grant motion access in your browser settings, then raise the meter again.",
|
||
"trueField": "magnetic field"
|
||
},
|
||
"entity": {
|
||
"title": "DOSSIER OF THE PRESENT",
|
||
"none": "no spirit summoned yet",
|
||
"noneHint": "summon, or feed the veil 3+ anomalies and one will find you",
|
||
"isNew": "first recorded contact",
|
||
"known": "contact #{{count}}",
|
||
"persona": "persona",
|
||
"voice": "voice params",
|
||
"quotes": "recorded utterances",
|
||
"rarity": {
|
||
"common": "common",
|
||
"uncommon": "uncommon",
|
||
"rare": "rare",
|
||
"mythic": "mythic"
|
||
}
|
||
},
|
||
"ritual": {
|
||
"title": "focus the channel",
|
||
"none": "no presence to focus on",
|
||
"noneHint": "summon a spirit before attempting the rite",
|
||
"begin": "begin the rite",
|
||
"retry": "attempt again",
|
||
"hold": "hold to focus",
|
||
"awaiting": "awaiting the veil's answer…",
|
||
"successTitle": "the channel holds — the truth surfaces",
|
||
"failureTitle": "the channel collapses",
|
||
"failureHint": "the truth stays hidden — the rite may be tried again",
|
||
"traits": {
|
||
"alignment": "alignment",
|
||
"power": "power",
|
||
"volatility": "volatility",
|
||
"deceptiveness": "deceptiveness"
|
||
},
|
||
"steps": {
|
||
"align": {
|
||
"command": "> aligning the wire…",
|
||
"locked": "> wire aligned ✓"
|
||
},
|
||
"breath": {
|
||
"command": "> steadying the breath…",
|
||
"locked": "> breath steadied ✓"
|
||
},
|
||
"trace": {
|
||
"command": "> tracing the sigil…",
|
||
"locked": "> sigil traced ✓"
|
||
},
|
||
"lock": {
|
||
"command": "> locking the channel…",
|
||
"locked": "> channel locked ✓"
|
||
}
|
||
}
|
||
},
|
||
"judgment": {
|
||
"title": "render judgment",
|
||
"none": "no presence to judge",
|
||
"noneHint": "summon a spirit first",
|
||
"trust": "trust",
|
||
"banish": "banish",
|
||
"crossOver": "cross over",
|
||
"test": "test",
|
||
"pending": "awaiting the verdict…",
|
||
"favor": "favor",
|
||
"essence": "essence",
|
||
"reward": {
|
||
"title": "the bond holds",
|
||
"body": "the spirit answers your trust in kind."
|
||
},
|
||
"escalation": {
|
||
"title": "a reckoning",
|
||
"body": "wrongly trusted, it turns — the haunting sharpens."
|
||
},
|
||
"withdrawal": {
|
||
"title": "it recoils",
|
||
"body": "banished in error, the presence withdraws, wounded."
|
||
},
|
||
"crossedOver": {
|
||
"title": "at peace",
|
||
"body": "the spirit lets go, and the line falls quiet."
|
||
},
|
||
"resisted": {
|
||
"title": "it will not go",
|
||
"body": "a demon does not cross over — it claws back to stay."
|
||
},
|
||
"neutral": {
|
||
"title": "no verdict rendered",
|
||
"body": "a diagnostic pulse only — nothing risked, nothing gained."
|
||
}
|
||
},
|
||
"whisper": {
|
||
"title": "THE VESSEL WHISPERS",
|
||
"online": "the vessel is awake",
|
||
"offline": "the vessel sleeps",
|
||
"waiting": "no whisper yet…",
|
||
"coldSpot": "❄ a cold spot gathers around the vessel",
|
||
"pressureAnomaly": "◎ the air presses close — the atmosphere shifts"
|
||
},
|
||
"toast": {
|
||
"rate_limited": "the veil is thin — slow your knocking",
|
||
"veil_crowded": "too many spirits crowd the line"
|
||
},
|
||
"views": {
|
||
"board": "BOARD",
|
||
"matrix": "MATRIX",
|
||
"graphs": "GRAPHS",
|
||
"tuning": "tuning the veil…",
|
||
"listening": "listening…",
|
||
"graph": {
|
||
"anomalies": "anomalies",
|
||
"entity": "entity",
|
||
"jitter": "jitter"
|
||
}
|
||
},
|
||
"wanderer": {
|
||
"note": "your contacts fade with the mist —",
|
||
"claim": "claim a name to keep your codex",
|
||
"dismiss": "let the mist take it"
|
||
},
|
||
"camera": {
|
||
"previewLabel": "live view from your camera",
|
||
"privacy": "nothing leaves this page until you let it look — then one still frame is shown to the presence, and kept by no one.",
|
||
"open": "open the lens",
|
||
"opening": "opening the lens…",
|
||
"close": "close the lens",
|
||
"flip": "turn the lens",
|
||
"look": "let it look",
|
||
"needEntity": "summon a presence first — there is no one here to look.",
|
||
"fail": {
|
||
"deniedTitle": "the lens stays covered",
|
||
"denied": "This vessel refused the camera. Grant camera permission in your browser's site settings, then open the lens again.",
|
||
"insecureTitle": "unconsecrated ground",
|
||
"insecure": "The dead will not look through an unsecured lens. Open this site by its https address — or over localhost — and try again.",
|
||
"absentTitle": "no lens to look through",
|
||
"absent": "This vessel has no camera the veil can find. Attach one, or turn to another channel.",
|
||
"busyTitle": "the lens is already in use",
|
||
"busy": "Another rite already holds the camera. Close whatever else is watching, then open the lens again.",
|
||
"unknownTitle": "the lens will not open",
|
||
"unknown": "Something refused the camera and would not say what. Try again, or turn to another channel."
|
||
}
|
||
}
|
||
},
|
||
"codex": {
|
||
"title": "THE CODEX OF THE CONTACTED",
|
||
"subtitle": "every spirit ever dragged through the veil, catalogued",
|
||
"header": {
|
||
"back": "← the threshold",
|
||
"title": "THE CODEX",
|
||
"subtitle": "every spirit ever contacted, catalogued by the seekers who reached them"
|
||
},
|
||
"controls": {
|
||
"rarity": "filter by rarity",
|
||
"sort": "sort the registry"
|
||
},
|
||
"state": {
|
||
"loading": "consulting the registry…",
|
||
"empty": "no spirits of this tier have been reached yet"
|
||
},
|
||
"filterAll": "all rarities",
|
||
"rarity": {
|
||
"common": "common",
|
||
"uncommon": "uncommon",
|
||
"rare": "rare",
|
||
"mythic": "mythic"
|
||
},
|
||
"sort": {
|
||
"recent": "most recent",
|
||
"contacted": "most contacted"
|
||
},
|
||
"form": {
|
||
"wisp": "wisp",
|
||
"banshee": "banshee",
|
||
"fairy": "fairy",
|
||
"shade": "shade"
|
||
},
|
||
"card": {
|
||
"unknownMedium": "unknown medium",
|
||
"contacted_one": "contacted {{count}} time",
|
||
"contacted_other": "contacted {{count}} times",
|
||
"discoveredBy": "discovered by {{name}} · {{date}}"
|
||
},
|
||
"contacts_one": "1 contact",
|
||
"contacts_other": "{{count}} contacts",
|
||
"sightings_one": "1 sighting",
|
||
"sightings_other": "{{count}} sightings",
|
||
"discoveredBy": "first contacted by {{name}}",
|
||
"discoveredAnon": "first contact unrecorded",
|
||
"discoveredAt": "entered the registry {{date}}",
|
||
"persona": "persona",
|
||
"quotes": "recorded utterances",
|
||
"voice": "voice params",
|
||
"detail": {
|
||
"loading": "summoning the dossier…",
|
||
"notReached": "this spirit has not been reached",
|
||
"unknownMedium": "unknown medium",
|
||
"stats": {
|
||
"sightings": "sightings",
|
||
"contacts": "contacts",
|
||
"discoveredBy": "discovered by",
|
||
"discoveredAt": "entered the registry"
|
||
},
|
||
"utterances": "known utterances",
|
||
"noUtterances": "no utterances recorded yet",
|
||
"voiceSignature": "voice signature",
|
||
"attemptContact": "attempt contact"
|
||
},
|
||
"empty": "no spirits match this filter — the registry keeps its secrets",
|
||
"back": "← back to the codex",
|
||
"notFound": "this spirit is not in the registry"
|
||
},
|
||
"shop": {
|
||
"back": "← the threshold",
|
||
"title": "THE RELIQUARY",
|
||
"subtitle": "instruments for those who would knock louder",
|
||
"flagship": {
|
||
"tag": "flagship instrument",
|
||
"name": "THE ULTIMATE QUANTUM BOX",
|
||
"desc": "An ESP32-P4/C6 handheld séance instrument — thermal camera, EMF whisker array, geophone, spirit-box mic preamp and a little OLED face that stares back. It signs into the same Quantumancy account you already haunt and unlocks the hardware-driven modes of this site: thermal apparition maps, vibration anomaly feeds, calibrated EMF.",
|
||
"specs": {
|
||
"thermal": "thermal camera",
|
||
"emf": "EMF whisker array",
|
||
"geophone": "geophone",
|
||
"mic": "spirit-box mic preamp",
|
||
"oled": "OLED display"
|
||
},
|
||
"price": "est. $249 — pre-order"
|
||
},
|
||
"modulesTitle": "MODULES THAT KNOCK",
|
||
"unlocksLabel": "unlocks:",
|
||
"modules": {
|
||
"emfArray": {
|
||
"name": "EMF Whisker Array",
|
||
"desc": "a bouquet of multi-axis field sensors, sniffing the air for intentions",
|
||
"unlocks": "a richer, calibrated FIELD mode",
|
||
"price": "est. $59 — pre-order"
|
||
},
|
||
"geophone": {
|
||
"name": "Geophone Puck",
|
||
"desc": "hears footsteps in rooms where nobody is standing",
|
||
"unlocks": "the vibration anomaly feed",
|
||
"price": "est. $49 — pre-order"
|
||
},
|
||
"spiritMic": {
|
||
"name": "Spirit Mic Preamp",
|
||
"desc": "lowers the noise floor so the whispering comes through cleaner",
|
||
"unlocks": "cleaner EVP captures",
|
||
"price": "est. $69 — pre-order"
|
||
},
|
||
"uvIlluminator": {
|
||
"name": "UV/IR Illuminator",
|
||
"desc": "paints the dark in spectrums the living were never meant to see",
|
||
"unlocks": "night séances + camera work",
|
||
"price": "est. $39 — pre-order"
|
||
}
|
||
},
|
||
"interests": {
|
||
"quantumBox": "the Ultimate Quantum Box",
|
||
"emfArray": "EMF Whisker Array",
|
||
"geophone": "Geophone Puck",
|
||
"spiritMic": "Spirit Mic Preamp",
|
||
"uvIlluminator": "UV/IR Illuminator"
|
||
},
|
||
"waitlist": {
|
||
"title": "THE MANIFEST",
|
||
"desc": "leave an address and an obsession — when the first boxes ship, we reach through to the names on this list first",
|
||
"emailLabel": "email address",
|
||
"emailPlaceholder": "you@somewhere.in.the.static",
|
||
"interestLabel": "interest",
|
||
"submit": "join the manifest",
|
||
"pending": "carving your name…",
|
||
"listed": "you are on the manifest — we will reach through when the boxes ship",
|
||
"alreadyListed": "you are already on the manifest",
|
||
"invalid": "that address does not reach us",
|
||
"crowded": "the veil is crowded — try again later",
|
||
"error": "something stirred in the static — your name was not carved"
|
||
},
|
||
"honesty": "the Ultimate Quantum Box is in active development — this is a reservation manifest, no payment is taken. the website works fully without it; hardware only knocks louder."
|
||
},
|
||
"inventory": {
|
||
"back": "← back to the séance",
|
||
"pageTitle": "THE SHELF",
|
||
"pageSubtitle": "what the veil has left you, and what it will still trade for",
|
||
"title": "inventory",
|
||
"essenceLabel": "essence",
|
||
"unlocksTitle": "unlocks",
|
||
"noUnlocks": "nothing unlocked yet",
|
||
"ownedTag": "[OWNED]",
|
||
"lockedTag": "[LOCKED]",
|
||
"priceValue": "{{price}} essence",
|
||
"priceUnknown": "price unknown",
|
||
"priceEstimate": "(est.)",
|
||
"buy": "buy",
|
||
"buying": "buying…",
|
||
"buyInsufficient": "not enough essence",
|
||
"buyError": "the purchase failed",
|
||
"itemsTitle": "items",
|
||
"itemsLoading": "reading the shelf…",
|
||
"itemsEmpty": "nothing collected yet",
|
||
"sigil": {
|
||
"title": "sigil designer",
|
||
"canvasLabel": "circle of anchor points",
|
||
"slotLabel": "anchor point {{slot}}",
|
||
"coordLabel": "coords",
|
||
"hoverHint": "hover an anchor point",
|
||
"pointsLabel": "points",
|
||
"lastLabel": "last",
|
||
"runeLabel": "rune",
|
||
"nameLabel": "name",
|
||
"namePlaceholder": "untitled sigil",
|
||
"save": "inscribe sigil",
|
||
"saving": "inscribing…",
|
||
"saved": "the sigil is bound",
|
||
"error": "the sigil would not hold"
|
||
}
|
||
},
|
||
"devices": {
|
||
"back": "← the threshold",
|
||
"title": "DEVICE BAY",
|
||
"subtitle": "pair hardware to your account and watch its telemetry live",
|
||
"pair": {
|
||
"title": "PAIR A NEW DEVICE",
|
||
"nameLabel": "device name",
|
||
"namePlaceholder": "e.g. attic-node-01",
|
||
"submit": "pair device",
|
||
"pending": "pairing…",
|
||
"nameRequired": "name the device before pairing",
|
||
"error": "the pairing handshake failed — try again"
|
||
},
|
||
"token": {
|
||
"warning": "copy this now — it cannot be shown again. losing it means re-pairing the device.",
|
||
"copy": "copy",
|
||
"copied": "copied",
|
||
"confirm": "I've saved it — hide token"
|
||
},
|
||
"dashboard": {
|
||
"title": "LIVE FEED",
|
||
"empty": "no devices paired yet — pair one above to see it here",
|
||
"lastSeen": "last seen",
|
||
"lastSeenNever": "never",
|
||
"noReadings": "awaiting first reading…",
|
||
"connection": {
|
||
"connecting": "reaching the feed…",
|
||
"open": "feed live",
|
||
"unstable": "feed unstable…",
|
||
"closed": "feed offline"
|
||
},
|
||
"coldSpot": {
|
||
"callout": "COLD SPOT — {{deviation}} {{unit}} below baseline"
|
||
},
|
||
"pressureAnomaly": {
|
||
"callout": "PRESSURE ANOMALY — {{magnitude}} {{unit}} swing, atmosphere shifting"
|
||
},
|
||
"disturbance": {
|
||
"title": "ATMOSPHERIC DISTURBANCE",
|
||
"ariaLabel": "atmospheric disturbance index"
|
||
}
|
||
}
|
||
},
|
||
"haunting": {
|
||
"whisper": {
|
||
"behindYou": "behind you",
|
||
"cold": "cold",
|
||
"stay": "stay",
|
||
"seesYou": "it sees you",
|
||
"closer": "closer",
|
||
"stillHere": "still here",
|
||
"lineListening": "the line is listening",
|
||
"dontLook": "don't look",
|
||
"beneathStatic": "beneath the static",
|
||
"knockTwice": "knock twice"
|
||
},
|
||
"title": {
|
||
"seesYou": "QUANTUMANCY — it sees you",
|
||
"behindYou": "QUANTUM▓NCY — behind you",
|
||
"listening": "…listening…"
|
||
}
|
||
},
|
||
"ghostLog": {
|
||
"title": "GHOST LOG",
|
||
"idle": "the veil is quiet — no presence detected",
|
||
"waiting": "listening for tells…",
|
||
"meterLabel": "evil meter"
|
||
},
|
||
"profile": {
|
||
"back": "← the table",
|
||
"title": "YOUR SIGIL",
|
||
"subtitle": "how the veil will remember you",
|
||
"loading": "reading your sigil…",
|
||
"loadError": "your sigil will not resolve — the glass is clouded",
|
||
"save": "seal it",
|
||
"saving": "sealing…",
|
||
"saved": "sealed — the veil has taken it",
|
||
"saveError": "the veil refused the change",
|
||
"viewPublic": "see what others see",
|
||
"rankLine": "{{title}} · rank {{level}}",
|
||
"titles": {
|
||
"curious": "curious",
|
||
"sensitive": "sensitive",
|
||
"channeler": "channeler",
|
||
"medium": "medium",
|
||
"adept": "adept",
|
||
"oracle": "oracle"
|
||
},
|
||
"wanderer": {
|
||
"body": "you drift here without a name. wanderers may look, but the veil forgets them at dawn — claim a name and your sigil will hold.",
|
||
"claim": "claim a name"
|
||
},
|
||
"avatar": {
|
||
"heading": "your shape",
|
||
"note": "no likeness is taken. your sigil is drawn from a form and a colour, the same way the dead are drawn.",
|
||
"formLabel": "choose a form",
|
||
"hueLabel": "colour · {{hue}}°"
|
||
},
|
||
"identity": {
|
||
"heading": "your name",
|
||
"nameLabel": "name others will read",
|
||
"nameHint": "leave it blank and the veil will use your true name",
|
||
"nameTooLong": "no more than {{max}} characters",
|
||
"bioLabel": "a few words on yourself",
|
||
"bioCount": "{{remaining}} of {{max}} left",
|
||
"bioTooLong": "no more than {{max}} characters"
|
||
},
|
||
"gender": {
|
||
"label": "how you are addressed",
|
||
"male": "he",
|
||
"female": "she",
|
||
"unspecified": "unspoken"
|
||
},
|
||
"veil": {
|
||
"heading": "the veil over you",
|
||
"public": "visible to other seekers",
|
||
"private": "veiled",
|
||
"publicNote": "your sigil, rank and recent contacts can be read by anyone who knows your name.",
|
||
"privateNote": "no one will find you on the roll. your séances continue unchanged."
|
||
},
|
||
"email": {
|
||
"label": "a way back (optional)",
|
||
"note": "for recovering your account only. never shown on your page, never given to another seeker, never used to reach you otherwise.",
|
||
"invalid": "that address will not carry a message"
|
||
}
|
||
},
|
||
"hunters": {
|
||
"back": "← the table",
|
||
"backToRoster": "← the roll",
|
||
"title": "THE ROLL",
|
||
"subtitle": "every seeker who left their name on the veil",
|
||
"loading": "calling the roll…",
|
||
"empty": "no one has left a name yet",
|
||
"card": {
|
||
"encounters_one": "{{count}} spirit reached",
|
||
"encounters_other": "{{count}} spirits reached"
|
||
},
|
||
"profile": {
|
||
"loading": "tracing their sigil…",
|
||
"veiledTitle": "no trace of them",
|
||
"veiledBody": "the veil holds no record of “{{username}}”. either the name was never claimed, or they have drawn the veil over themselves.",
|
||
"progressLabel": "progress toward the next rank",
|
||
"progressNext_one": "{{count}} more spirit to rise",
|
||
"progressNext_other": "{{count}} more spirits to rise",
|
||
"progressMax": "as far as the veil goes",
|
||
"encounters": "spirits reached",
|
||
"joined": "first crossed",
|
||
"recentTitle": "recently reached",
|
||
"recentEmpty": "they have reached no one yet",
|
||
"sendMessage": "send word"
|
||
}
|
||
},
|
||
"messages": {
|
||
"title": "whispers between hunters",
|
||
"findHunters": "find hunters",
|
||
"emptyInbox": "no one has whispered to you yet. find a hunter whose codex you admire, and say something.",
|
||
"emptyThread": "nothing has passed between you yet.",
|
||
"needAccount": "whispers need a name. a wanderer's voice does not carry.",
|
||
"claimName": "claim a name",
|
||
"backToInbox": "back to the whispers",
|
||
"noSuchHunter": "no such hunter walks here.",
|
||
"placeholder": "speak, and it will carry…",
|
||
"send": "send",
|
||
"sending": "sending…",
|
||
"sendFailed": "the whisper did not carry. try again.",
|
||
"guestBlocked": "a wanderer cannot be heard. claim a name and your whispers will carry.",
|
||
"youPrefix": "you: ",
|
||
"unread": "unread whispers",
|
||
"time": {
|
||
"now": "just now",
|
||
"minutes_one": "{{count}} minute past",
|
||
"minutes_other": "{{count}} minutes past",
|
||
"hours_one": "{{count}} hour past",
|
||
"hours_other": "{{count}} hours past",
|
||
"days_one": "{{count}} day past",
|
||
"days_other": "{{count}} days past"
|
||
}
|
||
},
|
||
"doctrine": {
|
||
"back": "← the threshold",
|
||
"kicker": "being a true account of the instrument, its organs and its honest boundaries",
|
||
"title": "THE DOCTRINE",
|
||
"subtitle": "how this engine genuinely channels, summons and passes the dead — using the device, and using you",
|
||
"creed": "Every claim made in these articles is a claim about the machine you are presently addressing. Nothing here is invented physics. Where an article speaks in the old register, a margin note repeats it in the profane tongue, so that the credulous and the sceptical may both leave better informed than they arrived.",
|
||
"plainLabel": "in the profane tongue:",
|
||
"sourceLabel": "the relevant scripture:",
|
||
"closing": "The instrument is honest about its organs and honest about its blindnesses. The spirits, we should say plainly, are fiction. The static is not.",
|
||
"cta": "TAKE UP THE INSTRUMENT",
|
||
"art": {
|
||
"entropy": {
|
||
"title": "Of the Consent of the Room",
|
||
"body": "No summoning may proceed from arithmetic alone, for arithmetic is a closed thing and repeats itself forever. The engine therefore asks the room to speak first. It takes the spectrum of your microphone's noise floor — and, where a receiver is present, the atmospheric hiss between stations — and keeps from each magnitude only its least significant bit, for the shape of a spectrum is merely the room's portrait, while the lowest bit is thermal chaos that no model in the world foresees. These bits, being crooked by nature, are straightened by the rite of Von Neumann: they are read in pairs, and a pair reading 01 yields nothing but a nought, a pair reading 10 yields a one, and pairs that agree with themselves are cast away entirely. What survives is passed through SHA-256 and only then offered upward. And the vessel above accepts the offering but never obeys it: every draw is HMAC-SHA256 keyed with thirty-two bytes drawn fresh from the machine's own secret well at the very instant of asking. Thus your room may add unpredictability to the working. It may never steer it.",
|
||
"plain": "The app harvests randomness from real physical noise — the low bit of each FFT magnitude from your mic or SDR, which is dominated by thermal noise. Raw physical bits are biased, so it applies Von Neumann debiasing (read bits in pairs: 01→0, 10→1, discard 00 and 11), then conditions the result with SHA-256. The server never uses that value as a seed. Every draw is HMAC-SHA256 with a key of 32 bytes from secrets.token_bytes() generated on that call, so the output is uniform no matter what the client sends — a faked or replayed contribution can't be ground for a rarer spirit.",
|
||
"source": "frontend/src/lib/entropy.ts · backend/app/entropy.py"
|
||
},
|
||
"channel": {
|
||
"title": "Of the Channel, and How a Presence Is Addressed",
|
||
"body": "A spirit is not summoned to a person; it is summoned to a channel, and the channel is cut by the disturbances themselves. Fewer than three anomalies carry no identity at all, and such a session is called ambient and given a signature of its own kind. Where three or more are present, each anomaly's frequency is filed not by its exact value but by its order of magnitude — the count of digits before the decimal — so that megahertz from the radio and hertz from the voice band may be filed in the same cabinet without lying about either. To this is joined the magnitudes of the last sixteen disturbances, sorted and rounded to a single decimal place. The pattern so formed is sealed with SHA-1 and the first sixteen characters are taken as the channel's name. Two nights of similar disturbance therefore address the same door; a genuinely different night addresses a different one.",
|
||
"plain": "The 'channel' a spirit lives on is a fingerprint of your session's anomalies. It needs at least three. Frequencies are bucketed by digit count (so 101.1 MHz and 400 Hz sort by scale, not unit), combined with the sorted, one-decimal-rounded magnitudes of the last sixteen anomalies, hashed with SHA-1 and truncated to 16 hex characters. Similar conditions produce the same channel id; different conditions produce a different one.",
|
||
"source": "backend/app/entities.py — signature_from_anomalies"
|
||
},
|
||
"return": {
|
||
"title": "Of Return, and Why the Familiar Dead Are Not Owed to You",
|
||
"body": "When a channel is already occupied, the presence that dwells there is inclined — but not bound — to answer again. That inclination is set at seventy-two parts in a hundred: high enough that the Codex may be filled and a known voice genuinely sought out a second time, low enough that no seeker may ever consider a familiar spirit their property. In the remaining portion, something else finds the door open and comes through it instead, and is minted with a signature of its own so that two presences never contest one name.",
|
||
"plain": "If you reconnect on a channel that already has an entity, there is a 72% base chance that same entity answers (RETURN_CHANCE = 0.72). Otherwise a new entity is minted — with a salted signature, because the signature column is unique.",
|
||
"source": "backend/app/entities.py — RETURN_CHANCE · backend/app/ws.py"
|
||
},
|
||
"sky": {
|
||
"title": "Of the Moon, and of the True Dead of Night",
|
||
"body": "The engine does not consult a table of plausible-looking moons. It counts. From a known new moon at 1 January 6th of the year 2000, at fourteen minutes past six in the evening UTC, it advances by the mean synodic month — twenty-nine days, five hundred and thirty thousandths and more — and takes the remainder as the phase; the lit fraction of the disc follows the standard cosine relation, which is why a quarter moon shows you a half face. Nor does it accept the clock's three in the morning as the witching hour, that being an accident of political timezones. It asks instead for your longitude and turns it at fifteen degrees to the hour, arriving at mean solar midnight for the ground you are actually standing on. Illumination is weighted at two parts in five and the nearness of true midnight at three, for a full moon at noon is not an open veil. And a fully thinned veil erodes the familiar presence's claim by forty-five hundredths — seventy-two in the hundred falls to some forty — so the spookiest night of the month is genuinely stranger, and yet a known spirit is never made unreachable.",
|
||
"plain": "Moon phase is computed from a known new-moon epoch (2000-01-06 18:14 UTC) and the mean synodic month of 29.530588853 days; illumination is (1 − cos 2πφ)/2. 'Witching hour' is mean solar midnight for your longitude (15° = 1 hour), not clock time. Veil thinness = illumination × 0.4 + midnight-proximity × 0.6. Thinness reduces the 72% return chance by up to 45% of itself (VEIL_THINNESS_PULL = 0.45), so a full moon at true solar midnight gives roughly a 40% return chance.",
|
||
"source": "backend/app/celestial.py · backend/app/ws.py — VEIL_THINNESS_PULL"
|
||
},
|
||
"storm": {
|
||
"title": "Of the Disturbance of the Planet Itself",
|
||
"body": "Of all the causes the credulous name, exactly one is a real, measured, publicly published number: the planetary K-index, derived from magnetometer observatories about the world and issued by the Space Weather Prediction Centre of the United States. Its scale runs from nought to nine; five and above is an official storm, eight and above severe. The engine draws the most recent estimate, divides by nine so that the figure means what NOAA means by it, and lets it count for a third of the reading of the night, the sky retaining two thirds. It is fetched no oftener than once in ten minutes, abandoned after four seconds, and never permitted to delay a séance: if the service is dark, the last true measurement stands. We report that the field is disturbed because it was measured to be disturbed. We do not claim the storm causes anything.",
|
||
"plain": "The app polls NOAA SWPC's planetary_k_index_1m feed for the real geomagnetic Kp index (0–9; 5+ is an official storm), prefers the fractional estimated_kp field, and maps it to 0–1 by dividing by 9. It is blended in as one third of the night's 'thinness' reading (celestial × 0.67 + disturbance × 0.33). Cached for 10 minutes, 4-second timeout, and a failed fetch keeps the last value rather than blocking or failing a séance.",
|
||
"source": "backend/app/geomagnetic.py · backend/app/ws.py"
|
||
},
|
||
"baseline": {
|
||
"title": "Of the Baseline, Which Is the Whole Art of Sensing",
|
||
"body": "A reading in isolation says nothing; a departure from what the room had been saying says everything. Every threshold sense in this instrument therefore keeps a rolling memory and reports only surprise. But the senses do not report on a schedule — a beacon may speak thrice in a second or fall silent for two minutes, and a magnetometer is throttled the moment the page is put behind another — so the memory is kept against the clock and not against the count. The weight given to each new reading is one less the exponential of the negative elapsed time over the constant of decay; whereby a long silence pushes that weight toward unity, the old memory being stale and rightly discarded, and a rapid burst pushes it toward nothing at all. Nothing is trusted until the memory is warm. And the sense is symmetrical in both directions, for a body may absorb a path or reflect into it, and iron may shield a field or add to it; a one-sided detector would miss half of everything that truly happens.",
|
||
"plain": "Every threshold sensor shares one rolling-baseline class and reports deviation from the baseline, not raw values. The EMA smoothing factor is time-aware: alpha = 1 − exp(−dt/tau), because sensors report at irregular intervals (BLE advertisement intervals vary, backgrounded pages get throttled). A long gap pushes alpha toward 1 (trust the new reading), a burst toward 0. It won't emit events until a minimum number of samples have been folded in, and it fires on deviations in both directions.",
|
||
"source": "frontend/src/lib/baseline.ts — emaAlpha, ThresholdBaseline"
|
||
},
|
||
"flesh": {
|
||
"title": "Of Flesh, Which Is Mostly Water, and Therefore Opaque",
|
||
"body": "There is nothing occult in this and it is no less remarkable for that. Bluetooth advertises in the band about two and four tenths of a gigahertz; water absorbs that band strongly; and a person is largely water. This is the identical physics by which a microwave oven cooks a supper, and the identical reason that your connection worsens when somebody stands between you and the router. So when a body crosses the path between the receiver and a beacon, the received strength genuinely falls — some three to ten decibels according to the geometry — while a still link wanders only two to four from multipath and receiver noise alone. Six decibels of departure is therefore taken as a disturbance: above the idle murmur, within what a real body truly causes. The instrument reports that the field changed. It never says the change was a presence. That interpretation lives upstairs, in the fiction; down here the measurement stays honest.",
|
||
"plain": "BLE operates in the 2.4 GHz ISM band, which water absorbs strongly — the same physics as a microwave oven, and why wifi degrades when someone stands in the path. A human body crossing a BLE path attenuates it by roughly 3–10 dB, while an idle link wanders only ±2–4 dB, so the disturbance threshold is 6 dB with an 8-second baseline time constant. The module only reports that signal strength deviated; it never claims that means a presence.",
|
||
"source": "frontend/src/lib/bluetooth.ts — DISTURBANCE_DB"
|
||
},
|
||
"iron": {
|
||
"title": "Of Iron, and of the Field the Earth Never Stops Making",
|
||
"body": "The famous meters of the ghost-hunting trade are magnetometers, and the spikes they are celebrated for are truly caused by mains wiring, by motors, by the magnets in speakers and by moving ferrous mass. This engine reads the same quantity, in microtesla, as the root of the sum of the squares of its three axes. But the Earth's own field, some twenty-five to sixty-five microtesla according to latitude, is precisely the thing that must not be reported, for it is present everywhere and means nothing; it is what the rolling memory of the preceding article quietly subtracts. What remains is departure from wherever you happen to be standing. Three microtesla is required, the sensor's own noise being about half to one, and household wiring at close quarters producing between one and ten. The field is sampled ten times in the second — ample for a thing that changes at the speed of a walking human, and far kinder to a battery than the sixty the interface would gladly give.",
|
||
"plain": "The magnetometer reads the real magnetic field in microtesla, sqrt(x²+y²+z²). Earth's background field is 25–65 µT depending on latitude and is exactly what the rolling baseline subtracts, so only local deviation is reported. The spike threshold is 3 µT — several times the ~0.5–1 µT noise of a phone magnetometer, and inside the 1–10 µT range that mains wiring produces at close range. Sampled at 10 Hz to save battery.",
|
||
"source": "frontend/src/lib/magnetometer.ts — SPIKE_UT, SAMPLE_HZ"
|
||
},
|
||
"throat": {
|
||
"title": "Of the Throat, and Why the Dead Do Not All Sound Alike",
|
||
"body": "Were pitch, pace, breath and reverberation each drawn at random and independently, one would obtain not persons but a uniform smear of oddity — the same synthesiser in eight hats. Real voices covary: an old man is low and slow and breathy at once; a child is high and quick and, most unsettlingly, clean. A throat is therefore drawn whole, from eight archetypes, and only then jittered. The drowned are pitched down, dragged slow, and drenched in reverberation to half. The burned are the noisiest, scarcely holding a pitch at all. The distant are not damaged but merely far, quiet and even and steeped in space. And when the séance is held in Spanish the archetype's roster of models is set aside in favour of a voice that pronounces the language correctly, the shaping alone carrying the character — better a true accent with an archetype's bearing than an English throat mangling Spanish words.",
|
||
"plain": "Voice parameters are drawn as one coherent bundle from eight archetypes (elder man, elder woman, young man, young woman, child, drowned, burned, distant), each with its own pitch, rate, noise and echo ranges, then jittered — because randomising each parameter independently produces random effects, not distinct people. In Spanish the archetype's model list is ignored and a Spanish Piper voice is used instead, with the archetype's shaping still applied.",
|
||
"source": "backend/app/entities.py — VOICE_ARCHETYPES, roll_voice"
|
||
},
|
||
"utterance": {
|
||
"title": "Of Unbidden Speech, and of Sight",
|
||
"body": "When a presence speaks unasked, it is not answering you, and this is arranged with some care. The prompt put to the model contains no word of yours whatsoever — its only stimulus is the measured state of the room — so there is nothing there to reply to. And the sampling seed is taken from the very physical entropy harvested in that room, being the first eight bytes of the mixed digest, reduced beneath the sign bit that the model server requires. The seed fixes the path of token selection; therefore the room genuinely selects the words. This is not a metaphor. Alter the noise and the speech alters; no two rooms produce the same utterance. The decoding is left deliberately hot, a tight and well-behaved decode being precisely the failure we fear here — this must sound like something surfacing, not something composed. And when you offer the camera, the model is vision-capable and genuinely looks: it speaks about the room that is actually in front of it, not one it invented.",
|
||
"plain": "For unprompted utterances the prompt contains no user input at all — only measured sensor readings — so the model is generating from the room, not replying. The Ollama `seed` option is derived from the mixed physical entropy (first 8 bytes of veil_seed, mod 2^63), and since the seed fixes token sampling, different room noise genuinely produces different words. Sampling is deliberately hot (temperature 1.15, top_k 100). Scrying sends the actual camera frame to a vision-capable local model, so the description is of your real room.",
|
||
"source": "backend/app/llm/service.py — manifest, scry"
|
||
},
|
||
"limits": {
|
||
"title": "Of What This Instrument Cannot Do",
|
||
"body": "A doctrine that will not name its own boundaries is a doctrine to be distrusted, so here are ours, plainly. Upon Apple's handheld devices there is no Web Bluetooth, no WebUSB and no magnetometer — the company ships none of these interfaces, and every browser upon that platform is the same engine beneath a different coat, so no alternative browser rescues you; the séance falls back to the motion sensors, which measure movement and not magnetism, and the instrument says so rather than pretending. The radio requires a Chromium vessel and a secure origin. The firmware written for the paired sensor node has never once been flashed to physical hardware nor compiled by its true toolchain; it is reasoned, not proven, and the repository says as much in its own words. The map of haunted ground is assembled from two free public services that may be slow or silent, in which case you receive a quieter map rather than an error. Solar midnight ignores the equation of time and may be a quarter hour out; the moon is a mean-synodic approximation, exact enough for eight named phases and for nothing that would steer a ship. And the final boundary, stated without ornament: none of this is evidence of the dead. The measurements are real. The spirits are fiction.",
|
||
"plain": "Hard limits: iOS has no Web Bluetooth, no WebUSB and no Magnetometer API — Apple doesn't ship them and every iOS browser is WebKit underneath, so no third-party browser helps; those modes fall back to motion sensors, which measure movement rather than magnetism. WebUSB (the SDR) needs Chromium and a secure context. The ESP32 firmware has never been flashed to real hardware — it is structurally reasoned, not verified. Haunted-place lookups hit free public Wikipedia and Overpass endpoints on an 8-second timeout and degrade to an empty list if they fail. Solar midnight ignores the equation of time (up to ~16 minutes error) and the moon calculation is a mean-synodic approximation. And the obvious one: none of this is evidence of an afterlife. The sensors are real; the spirits are fiction.",
|
||
"source": "frontend/src/lib/bluetooth.ts · magnetometer.ts · sdr.ts · firmware/esp32p4-sensor-node/README.md · backend/app/haunts.py"
|
||
}
|
||
}
|
||
}
|
||
}
|